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.
31 #include "depthstencil.h"
32 #include "renderbuffer.h"
36 * Adaptor/wrappers for GL_DEPTH_STENCIL renderbuffers.
38 * The problem with a GL_DEPTH_STENCIL renderbuffer is that sometimes we
39 * want to treat it as a stencil buffer, other times we want to treat it
40 * as a depth/z buffer and still other times when we want to treat it as
41 * a combined Z+stencil buffer! That implies we need three different sets
42 * of Get/Put functions.
44 * We solve this by wrapping the Z24_S8 or S8_Z24 renderbuffer with depth and
45 * stencil adaptors, each with the right kind of depth/stencil Get/Put functions.
50 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
61 * Delete a depth or stencil wrapper renderbuffer.
64 delete_wrapper(struct gl_renderbuffer
*rb
)
66 ASSERT(rb
->Format
== MESA_FORMAT_Z24_S8
||
67 rb
->Format
== MESA_FORMAT_S8_Z24
);
68 _mesa_reference_renderbuffer(&rb
->Wrapped
, NULL
);
74 * Realloc storage for wrapper.
77 alloc_wrapper_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
78 GLenum internalFormat
, GLuint width
, GLuint height
)
80 /* just pass this on to the wrapped renderbuffer */
81 struct gl_renderbuffer
*dsrb
= rb
->Wrapped
;
84 (void) internalFormat
;
86 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
87 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
89 retVal
= dsrb
->AllocStorage(ctx
, dsrb
, dsrb
->InternalFormat
, width
, height
);
100 /*======================================================================
101 * Depth wrapper around depth/stencil renderbuffer
105 get_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
106 GLint x
, GLint y
, void *values
)
108 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
109 GLuint temp
[MAX_WIDTH
], i
;
110 GLuint
*dst
= (GLuint
*) values
;
111 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
112 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
113 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
115 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
118 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
119 for (i
= 0; i
< count
; i
++) {
120 dst
[i
] = src
[i
] >> 8;
124 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
125 for (i
= 0; i
< count
; i
++) {
126 dst
[i
] = src
[i
] & 0xffffff;
132 get_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
133 const GLint x
[], const GLint y
[], void *values
)
135 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
136 GLuint temp
[MAX_WIDTH
], i
;
137 GLuint
*dst
= (GLuint
*) values
;
138 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
139 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
140 ASSERT(count
<= MAX_WIDTH
);
141 /* don't bother trying direct access */
142 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
143 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
144 for (i
= 0; i
< count
; i
++) {
145 dst
[i
] = temp
[i
] >> 8;
149 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
150 for (i
= 0; i
< count
; i
++) {
151 dst
[i
] = temp
[i
] & 0xffffff;
157 put_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
158 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
160 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
161 const GLuint
*src
= (const GLuint
*) values
;
162 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
163 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
164 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
168 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
169 for (i
= 0; i
< count
; i
++) {
170 if (!mask
|| mask
[i
]) {
171 dst
[i
] = (src
[i
] << 8) | (dst
[i
] & 0xff);
176 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
177 for (i
= 0; i
< count
; i
++) {
178 if (!mask
|| mask
[i
]) {
179 dst
[i
] = (src
[i
] & 0xffffff) | (dst
[i
] & 0xff000000);
185 /* get, modify, put */
186 GLuint temp
[MAX_WIDTH
], i
;
187 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
188 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
189 for (i
= 0; i
< count
; i
++) {
190 if (!mask
|| mask
[i
]) {
191 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
196 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
197 for (i
= 0; i
< count
; i
++) {
198 if (!mask
|| mask
[i
]) {
199 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
203 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
208 put_mono_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
209 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
211 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
212 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
213 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
214 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
218 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
219 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
220 for (i
= 0; i
< count
; i
++) {
221 if (!mask
|| mask
[i
]) {
222 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff);
227 const GLuint shiftedVal
= *((GLuint
*) value
);
228 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
229 for (i
= 0; i
< count
; i
++) {
230 if (!mask
|| mask
[i
]) {
231 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff000000);
237 /* get, modify, put */
238 GLuint temp
[MAX_WIDTH
], i
;
239 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
240 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
241 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
242 for (i
= 0; i
< count
; i
++) {
243 if (!mask
|| mask
[i
]) {
244 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
249 const GLuint shiftedVal
= *((GLuint
*) value
);
250 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
251 for (i
= 0; i
< count
; i
++) {
252 if (!mask
|| mask
[i
]) {
253 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
257 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
262 put_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
263 const GLint x
[], const GLint y
[],
264 const void *values
, const GLubyte
*mask
)
266 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
267 const GLuint
*src
= (const GLuint
*) values
;
268 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
269 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
270 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
273 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
274 for (i
= 0; i
< count
; i
++) {
275 if (!mask
|| mask
[i
]) {
276 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
277 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
282 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
283 for (i
= 0; i
< count
; i
++) {
284 if (!mask
|| mask
[i
]) {
285 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
286 *dst
= (src
[i
] & 0xffffff) | (*dst
& 0xff000000);
292 /* get, modify, put */
293 GLuint temp
[MAX_WIDTH
], i
;
294 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
295 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
296 for (i
= 0; i
< count
; i
++) {
297 if (!mask
|| mask
[i
]) {
298 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
303 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
304 for (i
= 0; i
< count
; i
++) {
305 if (!mask
|| mask
[i
]) {
306 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
310 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
315 put_mono_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
,
316 GLuint count
, const GLint x
[], const GLint y
[],
317 const void *value
, const GLubyte
*mask
)
319 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
320 GLuint temp
[MAX_WIDTH
], i
;
321 /* get, modify, put */
322 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
323 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
324 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
325 for (i
= 0; i
< count
; i
++) {
326 if (!mask
|| mask
[i
]) {
327 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
332 const GLuint shiftedVal
= *((GLuint
*) value
);
333 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
334 for (i
= 0; i
< count
; i
++) {
335 if (!mask
|| mask
[i
]) {
336 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
340 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
345 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
346 * a depth renderbuffer.
347 * \return new depth renderbuffer
349 struct gl_renderbuffer
*
350 _mesa_new_z24_renderbuffer_wrapper(GLcontext
*ctx
,
351 struct gl_renderbuffer
*dsrb
)
353 struct gl_renderbuffer
*z24rb
;
355 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
356 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
357 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
359 z24rb
= _mesa_new_renderbuffer(ctx
, 0);
363 z24rb
->Wrapped
= dsrb
;
364 z24rb
->Name
= dsrb
->Name
;
366 z24rb
->Width
= dsrb
->Width
;
367 z24rb
->Height
= dsrb
->Height
;
368 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
369 z24rb
->Format
= MESA_FORMAT_X8_Z24
;
370 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
371 z24rb
->DataType
= GL_UNSIGNED_INT
;
373 z24rb
->Delete
= delete_wrapper
;
374 z24rb
->AllocStorage
= alloc_wrapper_storage
;
375 z24rb
->GetPointer
= nop_get_pointer
;
376 z24rb
->GetRow
= get_row_z24
;
377 z24rb
->GetValues
= get_values_z24
;
378 z24rb
->PutRow
= put_row_z24
;
379 z24rb
->PutRowRGB
= NULL
;
380 z24rb
->PutMonoRow
= put_mono_row_z24
;
381 z24rb
->PutValues
= put_values_z24
;
382 z24rb
->PutMonoValues
= put_mono_values_z24
;
388 /*======================================================================
389 * Stencil wrapper around depth/stencil renderbuffer
393 get_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
394 GLint x
, GLint y
, void *values
)
396 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
397 GLuint temp
[MAX_WIDTH
], i
;
398 GLubyte
*dst
= (GLubyte
*) values
;
399 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
400 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
401 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
403 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
406 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
407 for (i
= 0; i
< count
; i
++) {
408 dst
[i
] = src
[i
] & 0xff;
412 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
413 for (i
= 0; i
< count
; i
++) {
414 dst
[i
] = src
[i
] >> 24;
420 get_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
421 const GLint x
[], const GLint y
[], void *values
)
423 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
424 GLuint temp
[MAX_WIDTH
], i
;
425 GLubyte
*dst
= (GLubyte
*) values
;
426 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
427 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
428 ASSERT(count
<= MAX_WIDTH
);
429 /* don't bother trying direct access */
430 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
431 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
432 for (i
= 0; i
< count
; i
++) {
433 dst
[i
] = temp
[i
] & 0xff;
437 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
438 for (i
= 0; i
< count
; i
++) {
439 dst
[i
] = temp
[i
] >> 24;
445 put_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
446 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
448 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
449 const GLubyte
*src
= (const GLubyte
*) values
;
450 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
451 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
452 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
456 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
457 for (i
= 0; i
< count
; i
++) {
458 if (!mask
|| mask
[i
]) {
459 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
464 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
465 for (i
= 0; i
< count
; i
++) {
466 if (!mask
|| mask
[i
]) {
467 dst
[i
] = (dst
[i
] & 0xffffff) | (src
[i
] << 24);
473 /* get, modify, put */
474 GLuint temp
[MAX_WIDTH
], i
;
475 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
476 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
477 for (i
= 0; i
< count
; i
++) {
478 if (!mask
|| mask
[i
]) {
479 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
484 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
485 for (i
= 0; i
< count
; i
++) {
486 if (!mask
|| mask
[i
]) {
487 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
491 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
496 put_mono_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
497 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
499 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
500 const GLubyte val
= *((GLubyte
*) value
);
501 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
502 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
503 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
507 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
508 for (i
= 0; i
< count
; i
++) {
509 if (!mask
|| mask
[i
]) {
510 dst
[i
] = (dst
[i
] & 0xffffff00) | val
;
515 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
516 for (i
= 0; i
< count
; i
++) {
517 if (!mask
|| mask
[i
]) {
518 dst
[i
] = (dst
[i
] & 0xffffff) | (val
<< 24);
524 /* get, modify, put */
525 GLuint temp
[MAX_WIDTH
], i
;
526 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
527 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
528 for (i
= 0; i
< count
; i
++) {
529 if (!mask
|| mask
[i
]) {
530 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
535 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
536 for (i
= 0; i
< count
; i
++) {
537 if (!mask
|| mask
[i
]) {
538 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
542 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
547 put_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
548 const GLint x
[], const GLint y
[],
549 const void *values
, const GLubyte
*mask
)
551 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
552 const GLubyte
*src
= (const GLubyte
*) values
;
553 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
554 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
555 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
558 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
559 for (i
= 0; i
< count
; i
++) {
560 if (!mask
|| mask
[i
]) {
561 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
562 *dst
= (*dst
& 0xffffff00) | src
[i
];
567 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
568 for (i
= 0; i
< count
; i
++) {
569 if (!mask
|| mask
[i
]) {
570 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
571 *dst
= (*dst
& 0xffffff) | (src
[i
] << 24);
577 /* get, modify, put */
578 GLuint temp
[MAX_WIDTH
], i
;
579 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
580 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
581 for (i
= 0; i
< count
; i
++) {
582 if (!mask
|| mask
[i
]) {
583 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
588 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
589 for (i
= 0; i
< count
; i
++) {
590 if (!mask
|| mask
[i
]) {
591 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
595 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
600 put_mono_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
601 const GLint x
[], const GLint y
[],
602 const void *value
, const GLubyte
*mask
)
604 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
605 GLuint temp
[MAX_WIDTH
], i
;
606 const GLubyte val
= *((GLubyte
*) value
);
607 /* get, modify, put */
608 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
609 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
610 for (i
= 0; i
< count
; i
++) {
611 if (!mask
|| mask
[i
]) {
612 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
617 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
618 for (i
= 0; i
< count
; i
++) {
619 if (!mask
|| mask
[i
]) {
620 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
624 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
629 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
630 * a stencil renderbuffer.
631 * \return new stencil renderbuffer
633 struct gl_renderbuffer
*
634 _mesa_new_s8_renderbuffer_wrapper(GLcontext
*ctx
, struct gl_renderbuffer
*dsrb
)
636 struct gl_renderbuffer
*s8rb
;
638 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
639 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
640 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
642 s8rb
= _mesa_new_renderbuffer(ctx
, 0);
646 s8rb
->Wrapped
= dsrb
;
647 s8rb
->Name
= dsrb
->Name
;
649 s8rb
->Width
= dsrb
->Width
;
650 s8rb
->Height
= dsrb
->Height
;
651 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
652 s8rb
->Format
= MESA_FORMAT_S8
;
653 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
654 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
656 s8rb
->Delete
= delete_wrapper
;
657 s8rb
->AllocStorage
= alloc_wrapper_storage
;
658 s8rb
->GetPointer
= nop_get_pointer
;
659 s8rb
->GetRow
= get_row_s8
;
660 s8rb
->GetValues
= get_values_s8
;
661 s8rb
->PutRow
= put_row_s8
;
662 s8rb
->PutRowRGB
= NULL
;
663 s8rb
->PutMonoRow
= put_mono_row_s8
;
664 s8rb
->PutValues
= put_values_s8
;
665 s8rb
->PutMonoValues
= put_mono_values_s8
;
673 ** The following functions are useful for hardware drivers that only
674 ** implement combined depth/stencil buffers.
675 ** The GL_EXT_framebuffer_object extension allows indepedent depth and
676 ** stencil buffers to be used in any combination.
677 ** Therefore, we sometimes have to merge separate depth and stencil
678 ** renderbuffers into a single depth+stencil renderbuffer. And sometimes
679 ** we have to split combined depth+stencil renderbuffers into separate
685 * Extract stencil values from the combined depth/stencil renderbuffer, storing
686 * the values into a separate stencil renderbuffer.
687 * \param dsRb the source depth/stencil renderbuffer
688 * \param stencilRb the destination stencil renderbuffer
689 * (either 8-bit or 32-bit)
692 _mesa_extract_stencil(GLcontext
*ctx
,
693 struct gl_renderbuffer
*dsRb
,
694 struct gl_renderbuffer
*stencilRb
)
696 GLuint row
, width
, height
;
701 ASSERT(dsRb
->Format
== MESA_FORMAT_Z24_S8
);
702 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
703 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
||
704 stencilRb
->Format
== MESA_FORMAT_S8
);
705 ASSERT(dsRb
->Width
== stencilRb
->Width
);
706 ASSERT(dsRb
->Height
== stencilRb
->Height
);
709 height
= dsRb
->Height
;
711 for (row
= 0; row
< height
; row
++) {
712 GLuint depthStencil
[MAX_WIDTH
];
713 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
714 if (stencilRb
->Format
== MESA_FORMAT_S8
) {
716 GLubyte stencil
[MAX_WIDTH
];
718 for (i
= 0; i
< width
; i
++) {
719 stencil
[i
] = depthStencil
[i
] & 0xff;
721 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, stencil
, NULL
);
725 /* the 24 depth bits will be ignored */
726 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
);
727 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
728 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, depthStencil
, NULL
);
735 * Copy stencil values from a stencil renderbuffer into a combined
736 * depth/stencil renderbuffer.
737 * \param dsRb the destination depth/stencil renderbuffer
738 * \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
741 _mesa_insert_stencil(GLcontext
*ctx
,
742 struct gl_renderbuffer
*dsRb
,
743 struct gl_renderbuffer
*stencilRb
)
745 GLuint row
, width
, height
;
750 ASSERT(dsRb
->Format
== MESA_FORMAT_Z24_S8
);
751 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
752 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
||
753 stencilRb
->Format
== MESA_FORMAT_S8
);
755 ASSERT(dsRb
->Width
== stencilRb
->Width
);
756 ASSERT(dsRb
->Height
== stencilRb
->Height
);
759 height
= dsRb
->Height
;
761 for (row
= 0; row
< height
; row
++) {
762 GLuint depthStencil
[MAX_WIDTH
];
764 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
766 if (stencilRb
->Format
== MESA_FORMAT_S8
) {
768 GLubyte stencil
[MAX_WIDTH
];
770 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
771 for (i
= 0; i
< width
; i
++) {
772 depthStencil
[i
] = (depthStencil
[i
] & 0xffffff00) | stencil
[i
];
776 /* 32bpp stencil buffer */
777 GLuint stencil
[MAX_WIDTH
], i
;
778 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
);
779 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
780 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
781 for (i
= 0; i
< width
; i
++) {
783 = (depthStencil
[i
] & 0xffffff00) | (stencil
[i
] & 0xff);
787 dsRb
->PutRow(ctx
, dsRb
, width
, 0, row
, depthStencil
, NULL
);
793 * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
794 * \param stencilRb the stencil renderbuffer to promote
797 _mesa_promote_stencil(GLcontext
*ctx
, struct gl_renderbuffer
*stencilRb
)
799 const GLsizei width
= stencilRb
->Width
;
800 const GLsizei height
= stencilRb
->Height
;
804 ASSERT(stencilRb
->Format
== MESA_FORMAT_S8
);
805 ASSERT(stencilRb
->Data
);
807 data
= (GLubyte
*) stencilRb
->Data
;
808 stencilRb
->Data
= NULL
;
809 stencilRb
->AllocStorage(ctx
, stencilRb
, GL_DEPTH24_STENCIL8_EXT
,
812 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
815 for (i
= 0; i
< height
; i
++) {
816 GLuint depthStencil
[MAX_WIDTH
];
817 for (j
= 0; j
< width
; j
++) {
818 depthStencil
[j
] = data
[k
++];
820 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, i
, depthStencil
, NULL
);