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 software-based renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
33 #include "main/glheader.h"
34 #include "main/imports.h"
35 #include "main/context.h"
36 #include "main/fbobject.h"
37 #include "main/formats.h"
38 #include "main/mtypes.h"
39 #include "main/renderbuffer.h"
40 #include "swrast/s_renderbuffer.h"
44 * Routines for get/put values in common buffer formats follow.
47 /* Returns a bytes per pixel of the DataType in the get/put span
48 * functions for at least a subset of the available combinations a
49 * renderbuffer can have.
51 * It would be nice to see gl_renderbuffer start talking about a
52 * gl_format instead of a GLenum DataType.
55 get_datatype_bytes(struct gl_renderbuffer
*rb
)
59 switch (rb
->DataType
) {
60 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV
:
65 case GL_UNSIGNED_INT_24_8_EXT
:
68 case GL_UNSIGNED_SHORT
:
71 case GL_UNSIGNED_BYTE
:
79 switch (rb
->_BaseFormat
) {
80 case GL_DEPTH_COMPONENT
:
81 case GL_DEPTH_STENCIL
:
82 return component_size
;
84 return 4 * component_size
;
88 /* This is commonly used by most of the accessors. */
90 get_pointer_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
96 return ((char *) rb
->Data
+
97 (y
* rb
->RowStride
+ x
) * _mesa_get_format_bytes(rb
->Format
));
100 /* GetRow() implementation for formats where DataType matches the rb->Format.
103 get_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
104 GLuint count
, GLint x
, GLint y
, void *values
)
106 void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
107 memcpy(values
, src
, count
* _mesa_get_format_bytes(rb
->Format
));
110 /* Only used for float textures currently, but might also be used for
111 * RGBA8888, RGBA16, etc.
114 get_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
115 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
117 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
120 for (i
= 0; i
< count
; i
++) {
121 const void *src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
122 char *dst
= (char *) values
+ i
* format_bytes
;
123 memcpy(dst
, src
, format_bytes
);
127 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
128 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
129 * storing those initial components of the value per pixel into the
133 put_row_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
134 GLuint count
, GLint x
, GLint y
,
135 const void *values
, const GLubyte
*mask
)
137 void *row
= rb
->GetPointer(ctx
, rb
, x
, y
);
138 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
139 int datatype_bytes
= get_datatype_bytes(rb
);
143 for (i
= 0; i
< count
; i
++) {
144 char *dst
= (char *) row
+ i
* format_bytes
;
145 const char *src
= (const char *) values
+ i
* datatype_bytes
;
148 memcpy(dst
, src
, format_bytes
);
153 for (i
= 0; i
< count
; i
++) {
154 char *dst
= (char *) row
+ i
* format_bytes
;
155 const char *src
= (const char *) values
+ i
* datatype_bytes
;
156 memcpy(dst
, src
, format_bytes
);
163 put_values_generic(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
164 GLuint count
, const GLint x
[], const GLint y
[],
165 const void *values
, const GLubyte
*mask
)
167 int format_bytes
= _mesa_get_format_bytes(rb
->Format
) / sizeof(GLfloat
);
168 int datatype_bytes
= get_datatype_bytes(rb
);
171 for (i
= 0; i
< count
; i
++) {
172 if (!mask
|| mask
[i
]) {
173 void *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
174 const char *src
= (const char *) values
+ i
* datatype_bytes
;
175 memcpy(dst
, src
, format_bytes
);
182 /**********************************************************************
183 * Functions for buffers of 1 X GLubyte values.
188 get_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
189 const GLint x
[], const GLint y
[], void *values
)
191 GLubyte
*dst
= (GLubyte
*) values
;
193 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
194 for (i
= 0; i
< count
; i
++) {
195 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
202 put_row_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
203 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
205 const GLubyte
*src
= (const GLubyte
*) values
;
206 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
207 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
210 for (i
= 0; i
< count
; i
++) {
217 memcpy(dst
, values
, count
* sizeof(GLubyte
));
223 put_values_ubyte(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
224 const GLint x
[], const GLint y
[],
225 const void *values
, const GLubyte
*mask
)
227 const GLubyte
*src
= (const GLubyte
*) values
;
229 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
230 for (i
= 0; i
< count
; i
++) {
231 if (!mask
|| mask
[i
]) {
232 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
239 /**********************************************************************
240 * Functions for buffers of 1 X GLushort values.
245 get_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
246 const GLint x
[], const GLint y
[], void *values
)
248 GLushort
*dst
= (GLushort
*) values
;
250 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
251 for (i
= 0; i
< count
; i
++) {
252 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
259 put_row_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
260 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
262 const GLushort
*src
= (const GLushort
*) values
;
263 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
264 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
267 for (i
= 0; i
< count
; i
++) {
274 memcpy(dst
, src
, count
* sizeof(GLushort
));
280 put_values_ushort(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
281 const GLint x
[], const GLint y
[], const void *values
,
284 const GLushort
*src
= (const GLushort
*) values
;
286 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
287 for (i
= 0; i
< count
; i
++) {
288 if (!mask
|| mask
[i
]) {
289 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
296 /**********************************************************************
297 * Functions for buffers of 1 X GLuint values.
298 * Typically depth/Z or color index.
302 get_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
303 const GLint x
[], const GLint y
[], void *values
)
305 GLuint
*dst
= (GLuint
*) values
;
307 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
308 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
309 for (i
= 0; i
< count
; i
++) {
310 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
317 put_row_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
318 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
320 const GLuint
*src
= (const GLuint
*) values
;
321 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->RowStride
+ x
;
322 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
323 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
326 for (i
= 0; i
< count
; i
++) {
333 memcpy(dst
, src
, count
* sizeof(GLuint
));
339 put_values_uint(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
340 const GLint x
[], const GLint y
[], const void *values
,
343 const GLuint
*src
= (const GLuint
*) values
;
345 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
346 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
347 for (i
= 0; i
< count
; i
++) {
348 if (!mask
|| mask
[i
]) {
349 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->RowStride
+ x
[i
];
356 /**********************************************************************
357 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
358 * Typically color buffers.
359 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
360 * alpha values and return 255 for outgoing alpha values.
364 get_pointer_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
367 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
368 /* No direct access since this buffer is RGB but caller will be
369 * treating it as if it were RGBA.
376 get_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
377 GLint x
, GLint y
, void *values
)
379 const GLubyte
*src
= ((const GLubyte
*) rb
->Data
) +
380 3 * (y
* rb
->RowStride
+ x
);
381 GLubyte
*dst
= (GLubyte
*) values
;
383 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
384 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
385 for (i
= 0; i
< count
; i
++) {
386 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
387 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
388 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
389 dst
[i
* 4 + 3] = 255;
395 get_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
396 const GLint x
[], const GLint y
[], void *values
)
398 GLubyte
*dst
= (GLubyte
*) values
;
400 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
401 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
402 for (i
= 0; i
< count
; i
++) {
404 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
405 dst
[i
* 4 + 0] = src
[0];
406 dst
[i
* 4 + 1] = src
[1];
407 dst
[i
* 4 + 2] = src
[2];
408 dst
[i
* 4 + 3] = 255;
414 put_row_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
415 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
417 /* note: incoming values are RGB+A! */
418 const GLubyte
*src
= (const GLubyte
*) values
;
419 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
421 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
422 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
423 for (i
= 0; i
< count
; i
++) {
424 if (!mask
|| mask
[i
]) {
425 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
426 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
427 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
434 put_row_rgb_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
435 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
437 /* note: incoming values are RGB+A! */
438 const GLubyte
*src
= (const GLubyte
*) values
;
439 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->RowStride
+ x
);
441 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
442 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
443 for (i
= 0; i
< count
; i
++) {
444 if (!mask
|| mask
[i
]) {
445 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
446 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
447 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
454 put_values_ubyte3(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
455 const GLint x
[], const GLint y
[], const void *values
,
458 /* note: incoming values are RGB+A! */
459 const GLubyte
*src
= (const GLubyte
*) values
;
461 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
462 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
463 for (i
= 0; i
< count
; i
++) {
464 if (!mask
|| mask
[i
]) {
465 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->RowStride
+ x
[i
]);
466 dst
[0] = src
[i
* 4 + 0];
467 dst
[1] = src
[i
* 4 + 1];
468 dst
[2] = src
[i
* 4 + 2];
474 /**********************************************************************
475 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
476 * Typically color buffers.
480 get_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
481 const GLint x
[], const GLint y
[], void *values
)
483 /* treat 4*GLubyte as 1*GLuint */
484 GLuint
*dst
= (GLuint
*) values
;
486 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
487 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
488 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
489 for (i
= 0; i
< count
; i
++) {
490 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
497 put_row_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
498 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
500 /* treat 4*GLubyte as 1*GLuint */
501 const GLuint
*src
= (const GLuint
*) values
;
502 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->RowStride
+ x
);
503 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
504 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
505 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
508 for (i
= 0; i
< count
; i
++) {
515 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
521 put_row_rgb_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
522 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
524 /* Store RGB values in RGBA buffer */
525 const GLubyte
*src
= (const GLubyte
*) values
;
526 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
528 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
529 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
530 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
531 for (i
= 0; i
< count
; i
++) {
532 if (!mask
|| mask
[i
]) {
533 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
534 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
535 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
536 dst
[i
* 4 + 3] = 0xff;
543 put_values_ubyte4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
544 const GLint x
[], const GLint y
[], const void *values
,
547 /* treat 4*GLubyte as 1*GLuint */
548 const GLuint
*src
= (const GLuint
*) values
;
550 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
551 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
||
552 rb
->Format
== MESA_FORMAT_RGBA8888_REV
);
553 for (i
= 0; i
< count
; i
++) {
554 if (!mask
|| mask
[i
]) {
555 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->RowStride
+ x
[i
]);
562 /**********************************************************************
563 * Functions for buffers of 4 X GLushort (or GLshort) values.
564 * Typically accum buffer.
568 get_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
569 const GLint x
[], const GLint y
[], void *values
)
571 GLushort
*dst
= (GLushort
*) values
;
573 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
574 for (i
= 0; i
< count
; i
++) {
576 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
583 put_row_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
584 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
586 const GLushort
*src
= (const GLushort
*) values
;
587 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
588 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
591 for (i
= 0; i
< count
; i
++) {
593 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
594 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
595 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
596 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
601 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
607 put_row_rgb_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
608 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
610 /* Put RGB values in RGBA buffer */
611 const GLushort
*src
= (const GLushort
*) values
;
612 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->RowStride
+ x
);
613 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
616 for (i
= 0; i
< count
; i
++) {
618 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
619 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
620 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
621 dst
[i
* 4 + 3] = 0xffff;
626 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
632 put_values_ushort4(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
633 const GLint x
[], const GLint y
[], const void *values
,
636 const GLushort
*src
= (const GLushort
*) values
;
638 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
639 for (i
= 0; i
< count
; i
++) {
640 if (!mask
|| mask
[i
]) {
642 ((GLushort
*) rb
->Data
) + 4 * (y
[i
] * rb
->RowStride
+ x
[i
]);
643 dst
[0] = src
[i
* 4 + 0];
644 dst
[1] = src
[i
* 4 + 1];
645 dst
[2] = src
[i
* 4 + 2];
646 dst
[3] = src
[i
* 4 + 3];
652 /**********************************************************************
653 * Functions for MESA_FORMAT_R8.
656 get_row_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
657 GLint x
, GLint y
, void *values
)
659 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
660 GLuint
*dst
= values
;
663 for (i
= 0; i
< count
; i
++) {
664 dst
[i
] = 0xff000000 | src
[i
];
669 get_values_r8(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
670 const GLint x
[], const GLint y
[], void *values
)
672 GLuint
*dst
= (GLuint
*) values
;
675 for (i
= 0; i
< count
; i
++) {
676 const GLubyte
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
677 dst
[i
] = 0xff000000 | *src
;
681 /**********************************************************************
682 * Functions for MESA_FORMAT_GR88.
685 get_row_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
686 GLint x
, GLint y
, void *values
)
688 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
689 GLuint
*dst
= values
;
692 for (i
= 0; i
< count
; i
++) {
693 dst
[i
] = 0xff000000 | src
[i
];
698 get_values_rg88(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
699 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
701 GLuint
*dst
= (GLuint
*) values
;
704 for (i
= 0; i
< count
; i
++) {
705 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
706 dst
[i
] = 0xff000000 | *src
;
710 /**********************************************************************
711 * Functions for MESA_FORMAT_R16.
714 get_row_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
715 GLint x
, GLint y
, void *values
)
717 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
718 GLushort
*dst
= values
;
721 for (i
= 0; i
< count
; i
++) {
722 dst
[i
* 4 + RCOMP
] = src
[i
];
723 dst
[i
* 4 + GCOMP
] = 0;
724 dst
[i
* 4 + BCOMP
] = 0;
725 dst
[i
* 4 + ACOMP
] = 0xffff;
730 get_values_r16(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
731 const GLint x
[], const GLint y
[], void *values
)
733 GLushort
*dst
= values
;
736 for (i
= 0; i
< count
; i
++) {
737 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
738 dst
[i
* 4 + RCOMP
] = *src
;
739 dst
[i
* 4 + GCOMP
] = 0;
740 dst
[i
* 4 + BCOMP
] = 0;
741 dst
[i
* 4 + ACOMP
] = 0xffff;
745 /**********************************************************************
746 * Functions for MESA_FORMAT_RG1616.
749 get_row_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
750 GLint x
, GLint y
, void *values
)
752 const GLushort
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
753 GLushort
*dst
= values
;
756 for (i
= 0; i
< count
; i
++) {
757 dst
[i
* 4 + RCOMP
] = src
[i
* 2];
758 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
759 dst
[i
* 4 + BCOMP
] = 0;
760 dst
[i
* 4 + ACOMP
] = 0xffff;
765 get_values_rg1616(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
766 GLuint count
, const GLint x
[], const GLint y
[], void *values
)
768 GLushort
*dst
= values
;
771 for (i
= 0; i
< count
; i
++) {
772 const GLshort
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
773 dst
[i
* 4 + RCOMP
] = src
[0];
774 dst
[i
* 4 + GCOMP
] = src
[1];
775 dst
[i
* 4 + BCOMP
] = 0;
776 dst
[i
* 4 + ACOMP
] = 0xffff;
780 /**********************************************************************
781 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
784 get_row_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
785 GLuint count
, GLint x
, GLint y
, void *values
)
787 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
788 GLfloat
*dst
= values
;
791 for (i
= 0; i
< count
; i
++) {
795 dst
[i
* 4 + ACOMP
] = src
[i
];
800 get_values_i_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
801 GLuint count
, const GLint x
[], const GLint y
[],
804 GLfloat
*dst
= values
;
807 for (i
= 0; i
< count
; i
++) {
808 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
812 dst
[i
* 4 + ACOMP
] = src
[0];
816 /**********************************************************************
817 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
820 get_row_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
821 GLuint count
, GLint x
, GLint y
, void *values
)
823 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
824 GLfloat
*dst
= values
;
827 for (i
= 0; i
< count
; i
++) {
830 dst
[i
* 4 + BCOMP
] = src
[i
];
831 dst
[i
* 4 + ACOMP
] = 1.0;
836 get_values_l_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
837 GLuint count
, const GLint x
[], const GLint y
[],
840 GLfloat
*dst
= values
;
843 for (i
= 0; i
< count
; i
++) {
844 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
847 dst
[i
* 4 + BCOMP
] = src
[0];
848 dst
[i
* 4 + ACOMP
] = 1.0;
852 /**********************************************************************
853 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
856 get_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
857 GLuint count
, GLint x
, GLint y
, void *values
)
859 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
860 GLfloat
*dst
= values
;
863 for (i
= 0; i
< count
; i
++) {
864 dst
[i
* 4 + RCOMP
] = 0.0;
865 dst
[i
* 4 + GCOMP
] = 0.0;
866 dst
[i
* 4 + BCOMP
] = 0.0;
867 dst
[i
* 4 + ACOMP
] = src
[i
];
872 get_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
873 GLuint count
, const GLint x
[], const GLint y
[],
876 GLfloat
*dst
= values
;
879 for (i
= 0; i
< count
; i
++) {
880 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
881 dst
[i
* 4 + RCOMP
] = 0.0;
882 dst
[i
* 4 + GCOMP
] = 0.0;
883 dst
[i
* 4 + BCOMP
] = 0.0;
884 dst
[i
* 4 + ACOMP
] = src
[0];
889 put_row_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
890 GLuint count
, GLint x
, GLint y
,
891 const void *values
, const GLubyte
*mask
)
893 float *dst
= rb
->GetPointer(ctx
, rb
, x
, y
);
894 const float *src
= values
;
898 for (i
= 0; i
< count
; i
++) {
900 dst
[i
] = src
[i
* 4 + ACOMP
];
905 for (i
= 0; i
< count
; i
++) {
906 dst
[i
] = src
[i
* 4 + ACOMP
];
912 put_values_a_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
913 GLuint count
, const GLint x
[], const GLint y
[],
914 const void *values
, const GLubyte
*mask
)
916 const float *src
= values
;
919 for (i
= 0; i
< count
; i
++) {
920 if (!mask
|| mask
[i
]) {
921 float *dst
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
923 *dst
= src
[i
* 4 + ACOMP
];
928 /**********************************************************************
929 * Functions for MESA_FORMAT_R_FLOAT32.
932 get_row_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
933 GLuint count
, GLint x
, GLint y
, void *values
)
935 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
936 GLfloat
*dst
= values
;
939 for (i
= 0; i
< count
; i
++) {
940 dst
[i
* 4 + RCOMP
] = src
[i
];
941 dst
[i
* 4 + GCOMP
] = 0.0;
942 dst
[i
* 4 + BCOMP
] = 0.0;
943 dst
[i
* 4 + ACOMP
] = 1.0;
948 get_values_r_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
949 GLuint count
, const GLint x
[], const GLint y
[],
952 GLfloat
*dst
= values
;
955 for (i
= 0; i
< count
; i
++) {
956 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
957 dst
[i
* 4 + RCOMP
] = src
[0];
958 dst
[i
* 4 + GCOMP
] = 0.0;
959 dst
[i
* 4 + BCOMP
] = 0.0;
960 dst
[i
* 4 + ACOMP
] = 1.0;
964 /**********************************************************************
965 * Functions for MESA_FORMAT_RG_FLOAT32.
968 get_row_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
969 GLuint count
, GLint x
, GLint y
, void *values
)
971 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
, y
);
972 GLfloat
*dst
= values
;
975 for (i
= 0; i
< count
; i
++) {
976 dst
[i
* 4 + RCOMP
] = src
[i
* 2 + 0];
977 dst
[i
* 4 + GCOMP
] = src
[i
* 2 + 1];
978 dst
[i
* 4 + BCOMP
] = 0.0;
979 dst
[i
* 4 + ACOMP
] = 1.0;
984 get_values_rg_float32(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
985 GLuint count
, const GLint x
[], const GLint y
[],
988 GLfloat
*dst
= values
;
991 for (i
= 0; i
< count
; i
++) {
992 const GLfloat
*src
= rb
->GetPointer(ctx
, rb
, x
[i
], y
[i
]);
993 dst
[i
* 4 + RCOMP
] = src
[0];
994 dst
[i
* 4 + GCOMP
] = src
[1];
995 dst
[i
* 4 + BCOMP
] = 0.0;
996 dst
[i
* 4 + ACOMP
] = 1.0;
1001 * This is the default software fallback for gl_renderbuffer's span
1004 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1005 * are packed in the type of rb->Format, and that subsequent rows appear
1006 * rb->RowStride pixels later.
1009 _swrast_set_renderbuffer_accessors(struct gl_renderbuffer
*rb
)
1011 rb
->GetPointer
= get_pointer_generic
;
1012 rb
->GetRow
= get_row_generic
;
1014 switch (rb
->Format
) {
1015 case MESA_FORMAT_RGB888
:
1016 rb
->DataType
= GL_UNSIGNED_BYTE
;
1017 rb
->GetPointer
= get_pointer_ubyte3
;
1018 rb
->GetRow
= get_row_ubyte3
;
1019 rb
->GetValues
= get_values_ubyte3
;
1020 rb
->PutRow
= put_row_ubyte3
;
1021 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
1022 rb
->PutValues
= put_values_ubyte3
;
1025 case MESA_FORMAT_RGBA8888
:
1026 case MESA_FORMAT_RGBA8888_REV
:
1027 rb
->DataType
= GL_UNSIGNED_BYTE
;
1028 rb
->GetValues
= get_values_ubyte4
;
1029 rb
->PutRow
= put_row_ubyte4
;
1030 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
1031 rb
->PutValues
= put_values_ubyte4
;
1034 case MESA_FORMAT_R8
:
1035 rb
->DataType
= GL_UNSIGNED_BYTE
;
1036 rb
->GetValues
= get_values_r8
;
1037 rb
->GetRow
= get_row_r8
;
1038 rb
->PutRow
= put_row_generic
;
1039 rb
->PutRowRGB
= put_row_generic
;
1040 rb
->PutValues
= put_values_generic
;
1043 case MESA_FORMAT_GR88
:
1044 rb
->DataType
= GL_UNSIGNED_BYTE
;
1045 rb
->GetValues
= get_values_rg88
;
1046 rb
->GetRow
= get_row_rg88
;
1047 rb
->PutRow
= put_row_generic
;
1048 rb
->PutRowRGB
= put_row_generic
;
1049 rb
->PutValues
= put_values_generic
;
1052 case MESA_FORMAT_R16
:
1053 rb
->DataType
= GL_UNSIGNED_SHORT
;
1054 rb
->GetValues
= get_values_r16
;
1055 rb
->GetRow
= get_row_r16
;
1056 rb
->PutRow
= put_row_generic
;
1057 rb
->PutRowRGB
= put_row_generic
;
1058 rb
->PutValues
= put_values_generic
;
1061 case MESA_FORMAT_RG1616
:
1062 rb
->DataType
= GL_UNSIGNED_SHORT
;
1063 rb
->GetValues
= get_values_rg1616
;
1064 rb
->GetRow
= get_row_rg1616
;
1065 rb
->PutRow
= put_row_generic
;
1066 rb
->PutRowRGB
= put_row_generic
;
1067 rb
->PutValues
= put_values_generic
;
1070 case MESA_FORMAT_SIGNED_RGBA_16
:
1071 rb
->DataType
= GL_SHORT
;
1072 rb
->GetValues
= get_values_ushort4
;
1073 rb
->PutRow
= put_row_ushort4
;
1074 rb
->PutRowRGB
= put_row_rgb_ushort4
;
1075 rb
->PutValues
= put_values_ushort4
;
1078 case MESA_FORMAT_S8
:
1079 rb
->DataType
= GL_UNSIGNED_BYTE
;
1080 rb
->GetValues
= get_values_ubyte
;
1081 rb
->PutRow
= put_row_ubyte
;
1082 rb
->PutRowRGB
= NULL
;
1083 rb
->PutValues
= put_values_ubyte
;
1086 case MESA_FORMAT_Z16
:
1087 rb
->DataType
= GL_UNSIGNED_SHORT
;
1088 rb
->GetValues
= get_values_ushort
;
1089 rb
->PutRow
= put_row_ushort
;
1090 rb
->PutRowRGB
= NULL
;
1091 rb
->PutValues
= put_values_ushort
;
1094 case MESA_FORMAT_Z32
:
1095 case MESA_FORMAT_X8_Z24
:
1096 case MESA_FORMAT_Z24_X8
:
1097 rb
->DataType
= GL_UNSIGNED_INT
;
1098 rb
->GetValues
= get_values_uint
;
1099 rb
->PutRow
= put_row_uint
;
1100 rb
->PutRowRGB
= NULL
;
1101 rb
->PutValues
= put_values_uint
;
1104 case MESA_FORMAT_Z24_S8
:
1105 case MESA_FORMAT_S8_Z24
:
1106 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1107 rb
->GetValues
= get_values_uint
;
1108 rb
->PutRow
= put_row_uint
;
1109 rb
->PutRowRGB
= NULL
;
1110 rb
->PutValues
= put_values_uint
;
1113 case MESA_FORMAT_RGBA_FLOAT32
:
1114 rb
->GetRow
= get_row_generic
;
1115 rb
->GetValues
= get_values_generic
;
1116 rb
->PutRow
= put_row_generic
;
1117 rb
->PutRowRGB
= NULL
;
1118 rb
->PutValues
= put_values_generic
;
1121 case MESA_FORMAT_INTENSITY_FLOAT32
:
1122 rb
->GetRow
= get_row_i_float32
;
1123 rb
->GetValues
= get_values_i_float32
;
1124 rb
->PutRow
= put_row_generic
;
1125 rb
->PutRowRGB
= NULL
;
1126 rb
->PutValues
= put_values_generic
;
1129 case MESA_FORMAT_LUMINANCE_FLOAT32
:
1130 rb
->GetRow
= get_row_l_float32
;
1131 rb
->GetValues
= get_values_l_float32
;
1132 rb
->PutRow
= put_row_generic
;
1133 rb
->PutRowRGB
= NULL
;
1134 rb
->PutValues
= put_values_generic
;
1137 case MESA_FORMAT_ALPHA_FLOAT32
:
1138 rb
->GetRow
= get_row_a_float32
;
1139 rb
->GetValues
= get_values_a_float32
;
1140 rb
->PutRow
= put_row_a_float32
;
1141 rb
->PutRowRGB
= NULL
;
1142 rb
->PutValues
= put_values_a_float32
;
1145 case MESA_FORMAT_RG_FLOAT32
:
1146 rb
->GetRow
= get_row_rg_float32
;
1147 rb
->GetValues
= get_values_rg_float32
;
1148 rb
->PutRow
= put_row_generic
;
1149 rb
->PutRowRGB
= NULL
;
1150 rb
->PutValues
= put_values_generic
;
1153 case MESA_FORMAT_R_FLOAT32
:
1154 rb
->GetRow
= get_row_r_float32
;
1155 rb
->GetValues
= get_values_r_float32
;
1156 rb
->PutRow
= put_row_generic
;
1157 rb
->PutRowRGB
= NULL
;
1158 rb
->PutValues
= put_values_generic
;
1167 * This is a software fallback for the gl_renderbuffer->AllocStorage
1169 * Device drivers will typically override this function for the buffers
1170 * which it manages (typically color buffers, Z and stencil).
1171 * Other buffers (like software accumulation and aux buffers) which the driver
1172 * doesn't manage can be handled with this function.
1174 * This one multi-purpose function can allocate stencil, depth, accum, color
1175 * or color-index buffers!
1177 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1178 * Get/PutValues functions.
1181 soft_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1182 GLenum internalFormat
,
1183 GLuint width
, GLuint height
)
1185 switch (internalFormat
) {
1194 rb
->Format
= MESA_FORMAT_RGB888
;
1205 if (_mesa_little_endian())
1206 rb
->Format
= MESA_FORMAT_RGBA8888_REV
;
1208 rb
->Format
= MESA_FORMAT_RGBA8888
;
1211 case GL_RGBA16_SNORM
:
1212 /* for accum buffer */
1213 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1215 case GL_STENCIL_INDEX
:
1216 case GL_STENCIL_INDEX1_EXT
:
1217 case GL_STENCIL_INDEX4_EXT
:
1218 case GL_STENCIL_INDEX8_EXT
:
1219 case GL_STENCIL_INDEX16_EXT
:
1220 rb
->Format
= MESA_FORMAT_S8
;
1222 case GL_DEPTH_COMPONENT
:
1223 case GL_DEPTH_COMPONENT16
:
1224 rb
->Format
= MESA_FORMAT_Z16
;
1226 case GL_DEPTH_COMPONENT24
:
1227 rb
->Format
= MESA_FORMAT_X8_Z24
;
1229 case GL_DEPTH_COMPONENT32
:
1230 rb
->Format
= MESA_FORMAT_Z32
;
1232 case GL_DEPTH_STENCIL_EXT
:
1233 case GL_DEPTH24_STENCIL8_EXT
:
1234 rb
->Format
= MESA_FORMAT_Z24_S8
;
1237 /* unsupported format */
1241 _swrast_set_renderbuffer_accessors(rb
);
1243 ASSERT(rb
->DataType
);
1244 ASSERT(rb
->GetPointer
);
1246 ASSERT(rb
->GetValues
);
1248 ASSERT(rb
->PutValues
);
1250 /* free old buffer storage */
1256 rb
->RowStride
= width
;
1258 if (width
> 0 && height
> 0) {
1259 /* allocate new buffer storage */
1260 rb
->Data
= malloc(width
* height
* _mesa_get_format_bytes(rb
->Format
));
1262 if (rb
->Data
== NULL
) {
1266 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1267 "software renderbuffer allocation (%d x %d x %d)",
1268 width
, height
, _mesa_get_format_bytes(rb
->Format
));
1274 rb
->Height
= height
;
1275 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1277 if (rb
->Name
== 0 &&
1278 internalFormat
== GL_RGBA16_SNORM
&&
1279 rb
->_BaseFormat
== 0) {
1280 /* NOTE: This is a special case just for accumulation buffers.
1281 * This is a very limited use case- there's no snorm texturing or
1282 * rendering going on.
1284 rb
->_BaseFormat
= GL_RGBA
;
1287 /* the internalFormat should have been error checked long ago */
1288 ASSERT(rb
->_BaseFormat
);
1296 _swrast_map_soft_renderbuffer(struct gl_context
*ctx
,
1297 struct gl_renderbuffer
*rb
,
1298 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
1303 GLubyte
*map
= rb
->Data
;
1304 int cpp
= _mesa_get_format_bytes(rb
->Format
);
1305 int stride
= rb
->RowStride
* cpp
;
1313 *out_stride
= stride
;
1318 _swrast_unmap_soft_renderbuffer(struct gl_context
*ctx
,
1319 struct gl_renderbuffer
*rb
)
1326 * Allocate a software-based renderbuffer. This is called via the
1327 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1329 * This would not be used for hardware-based renderbuffers.
1331 struct gl_renderbuffer
*
1332 _swrast_new_soft_renderbuffer(struct gl_context
*ctx
, GLuint name
)
1334 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1336 rb
->AllocStorage
= soft_renderbuffer_storage
;
1337 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1338 * But we're doing that in the soft_renderbuffer_storage() function
1347 * Add software-based color renderbuffers to the given framebuffer.
1348 * This is a helper routine for device drivers when creating a
1349 * window system framebuffer (not a user-created render/framebuffer).
1350 * Once this function is called, you can basically forget about this
1351 * renderbuffer; core Mesa will handle all the buffer management and
1355 add_color_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1356 GLuint rgbBits
, GLuint alphaBits
,
1357 GLboolean frontLeft
, GLboolean backLeft
,
1358 GLboolean frontRight
, GLboolean backRight
)
1362 if (rgbBits
> 16 || alphaBits
> 16) {
1364 "Unsupported bit depth in add_color_renderbuffers");
1368 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1370 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1371 struct gl_renderbuffer
*rb
;
1373 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1375 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1377 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1379 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1382 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1384 rb
= _mesa_new_renderbuffer(ctx
, 0);
1386 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1390 rb
->InternalFormat
= GL_RGBA
;
1392 rb
->AllocStorage
= soft_renderbuffer_storage
;
1393 _mesa_add_renderbuffer(fb
, b
, rb
);
1401 * Add a software-based depth renderbuffer to the given framebuffer.
1402 * This is a helper routine for device drivers when creating a
1403 * window system framebuffer (not a user-created render/framebuffer).
1404 * Once this function is called, you can basically forget about this
1405 * renderbuffer; core Mesa will handle all the buffer management and
1409 add_depth_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1412 struct gl_renderbuffer
*rb
;
1414 if (depthBits
> 32) {
1416 "Unsupported depthBits in add_depth_renderbuffer");
1420 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1422 rb
= _mesa_new_renderbuffer(ctx
, 0);
1424 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1428 if (depthBits
<= 16) {
1429 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1431 else if (depthBits
<= 24) {
1432 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1435 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1438 rb
->AllocStorage
= soft_renderbuffer_storage
;
1439 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1446 * Add a software-based stencil renderbuffer to the given framebuffer.
1447 * This is a helper routine for device drivers when creating a
1448 * window system framebuffer (not a user-created render/framebuffer).
1449 * Once this function is called, you can basically forget about this
1450 * renderbuffer; core Mesa will handle all the buffer management and
1454 add_stencil_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1457 struct gl_renderbuffer
*rb
;
1459 if (stencilBits
> 16) {
1461 "Unsupported stencilBits in add_stencil_renderbuffer");
1465 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1467 rb
= _mesa_new_renderbuffer(ctx
, 0);
1469 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1473 assert(stencilBits
<= 8);
1474 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
1476 rb
->AllocStorage
= soft_renderbuffer_storage
;
1477 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1484 add_depth_stencil_renderbuffer(struct gl_context
*ctx
,
1485 struct gl_framebuffer
*fb
)
1487 struct gl_renderbuffer
*rb
;
1489 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1490 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1492 rb
= _mesa_new_renderbuffer(ctx
, 0);
1494 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth+stencil buffer");
1498 rb
->InternalFormat
= GL_DEPTH_STENCIL
;
1500 rb
->AllocStorage
= soft_renderbuffer_storage
;
1501 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1502 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1509 * Add a software-based accumulation renderbuffer to the given framebuffer.
1510 * This is a helper routine for device drivers when creating a
1511 * window system framebuffer (not a user-created render/framebuffer).
1512 * Once this function is called, you can basically forget about this
1513 * renderbuffer; core Mesa will handle all the buffer management and
1517 add_accum_renderbuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1518 GLuint redBits
, GLuint greenBits
,
1519 GLuint blueBits
, GLuint alphaBits
)
1521 struct gl_renderbuffer
*rb
;
1523 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1525 "Unsupported accumBits in add_accum_renderbuffer");
1529 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1531 rb
= _mesa_new_renderbuffer(ctx
, 0);
1533 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1537 rb
->InternalFormat
= GL_RGBA16_SNORM
;
1538 rb
->AllocStorage
= soft_renderbuffer_storage
;
1539 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1547 * Add a software-based aux renderbuffer to the given framebuffer.
1548 * This is a helper routine for device drivers when creating a
1549 * window system framebuffer (not a user-created render/framebuffer).
1550 * Once this function is called, you can basically forget about this
1551 * renderbuffer; core Mesa will handle all the buffer management and
1554 * NOTE: color-index aux buffers not supported.
1557 add_aux_renderbuffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1558 GLuint colorBits
, GLuint numBuffers
)
1562 if (colorBits
> 16) {
1564 "Unsupported colorBits in add_aux_renderbuffers");
1568 assert(numBuffers
<= MAX_AUX_BUFFERS
);
1570 for (i
= 0; i
< numBuffers
; i
++) {
1571 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1573 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1576 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating aux buffer");
1580 assert (colorBits
<= 8);
1581 rb
->InternalFormat
= GL_RGBA
;
1583 rb
->AllocStorage
= soft_renderbuffer_storage
;
1584 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1591 * Create/attach software-based renderbuffers to the given framebuffer.
1592 * This is a helper routine for device drivers. Drivers can just as well
1593 * call the individual _mesa_add_*_renderbuffer() routines directly.
1596 _swrast_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1604 GLboolean frontLeft
= GL_TRUE
;
1605 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1606 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1607 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1610 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1611 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1612 add_color_renderbuffers(NULL
, fb
,
1614 fb
->Visual
.alphaBits
,
1615 frontLeft
, backLeft
,
1616 frontRight
, backRight
);
1620 /* This is pretty much for debugging purposes only since there's a perf
1621 * hit for using combined depth/stencil in swrast.
1623 if (depth
&& fb
->Visual
.depthBits
== 24 &&
1624 stencil
&& fb
->Visual
.stencilBits
== 8) {
1625 /* use combined depth/stencil buffer */
1626 add_depth_stencil_renderbuffer(NULL
, fb
);
1630 (void) add_depth_stencil_renderbuffer
;
1634 assert(fb
->Visual
.depthBits
> 0);
1635 add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1639 assert(fb
->Visual
.stencilBits
> 0);
1640 add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1645 assert(fb
->Visual
.accumRedBits
> 0);
1646 assert(fb
->Visual
.accumGreenBits
> 0);
1647 assert(fb
->Visual
.accumBlueBits
> 0);
1648 add_accum_renderbuffer(NULL
, fb
,
1649 fb
->Visual
.accumRedBits
,
1650 fb
->Visual
.accumGreenBits
,
1651 fb
->Visual
.accumBlueBits
,
1652 fb
->Visual
.accumAlphaBits
);
1656 assert(fb
->Visual
.numAuxBuffers
> 0);
1657 add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1658 fb
->Visual
.numAuxBuffers
);