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.
30 #include "depthstencil.h"
31 #include "renderbuffer.h"
35 * Adaptor/wrappers for GL_DEPTH_STENCIL renderbuffers.
37 * The problem with a GL_DEPTH_STENCIL renderbuffer is that sometimes we
38 * want to treat it as a stencil buffer, other times we want to treat it
39 * as a depth/z buffer and still other times when we want to treat it as
40 * a combined Z+stencil buffer! That implies we need three different sets
41 * of Get/Put functions.
43 * We solve this by wrapping the Z24_S8 renderbuffer with depth and stencil
44 * adaptors, each with the right kind of depth/stencil Get/Put functions.
49 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
60 * Delete a depth or stencil wrapper renderbuffer.
63 delete_wrapper(struct gl_renderbuffer
*rb
)
65 ASSERT(rb
->_ActualFormat
== GL_DEPTH_COMPONENT24
||
66 rb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
67 _mesa_reference_renderbuffer(&rb
->Wrapped
, NULL
);
73 * Realloc storage for wrapper.
76 alloc_wrapper_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
77 GLenum internalFormat
, GLuint width
, GLuint height
)
79 /* just pass this on to the wrapped renderbuffer */
80 struct gl_renderbuffer
*dsrb
= rb
->Wrapped
;
83 (void) internalFormat
;
85 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
87 retVal
= dsrb
->AllocStorage(ctx
, dsrb
, dsrb
->InternalFormat
, width
, height
);
98 /*======================================================================
99 * Depth wrapper around depth/stencil renderbuffer
103 get_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
104 GLint x
, GLint y
, void *values
)
106 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
107 GLuint temp
[MAX_WIDTH
], i
;
108 GLuint
*dst
= (GLuint
*) values
;
109 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
110 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
111 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
112 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
114 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
117 for (i
= 0; i
< count
; i
++) {
118 dst
[i
] = src
[i
] >> 8;
123 get_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
124 const GLint x
[], const GLint y
[], void *values
)
126 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
127 GLuint temp
[MAX_WIDTH
], i
;
128 GLuint
*dst
= (GLuint
*) values
;
129 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
130 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
131 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
132 ASSERT(count
<= MAX_WIDTH
);
133 /* don't bother trying direct access */
134 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
135 for (i
= 0; i
< count
; i
++) {
136 dst
[i
] = temp
[i
] >> 8;
141 put_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
142 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
144 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
145 const GLuint
*src
= (const GLuint
*) values
;
146 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
147 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
148 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
149 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
153 for (i
= 0; i
< count
; i
++) {
154 if (!mask
|| mask
[i
]) {
155 dst
[i
] = (src
[i
] << 8) | (dst
[i
] & 0xff);
160 /* get, modify, put */
161 GLuint temp
[MAX_WIDTH
], i
;
162 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
163 for (i
= 0; i
< count
; i
++) {
164 if (!mask
|| mask
[i
]) {
165 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
168 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
173 put_mono_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
174 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
176 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
177 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
178 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
179 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
180 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
181 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
185 for (i
= 0; i
< count
; i
++) {
186 if (!mask
|| mask
[i
]) {
187 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff);
192 /* get, modify, put */
193 GLuint temp
[MAX_WIDTH
], i
;
194 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
195 for (i
= 0; i
< count
; i
++) {
196 if (!mask
|| mask
[i
]) {
197 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
200 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
205 put_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
206 const GLint x
[], const GLint y
[],
207 const void *values
, const GLubyte
*mask
)
209 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
210 const GLuint
*src
= (const GLuint
*) values
;
211 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
212 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
213 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
214 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
217 for (i
= 0; i
< count
; i
++) {
218 if (!mask
|| mask
[i
]) {
219 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
220 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
225 /* get, modify, put */
226 GLuint temp
[MAX_WIDTH
], i
;
227 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
228 for (i
= 0; i
< count
; i
++) {
229 if (!mask
|| mask
[i
]) {
230 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
233 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
238 put_mono_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
,
239 GLuint count
, const GLint x
[], const GLint y
[],
240 const void *value
, const GLubyte
*mask
)
242 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
243 GLuint temp
[MAX_WIDTH
], i
;
244 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
245 /* get, modify, put */
246 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
247 for (i
= 0; i
< count
; i
++) {
248 if (!mask
|| mask
[i
]) {
249 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
252 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
257 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
258 * a depth renderbuffer.
259 * \return new depth renderbuffer
261 struct gl_renderbuffer
*
262 _mesa_new_z24_renderbuffer_wrapper(GLcontext
*ctx
,
263 struct gl_renderbuffer
*dsrb
)
265 struct gl_renderbuffer
*z24rb
;
267 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
268 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
270 z24rb
= _mesa_new_renderbuffer(ctx
, 0);
274 z24rb
->Wrapped
= dsrb
;
275 z24rb
->Name
= dsrb
->Name
;
277 z24rb
->Width
= dsrb
->Width
;
278 z24rb
->Height
= dsrb
->Height
;
279 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
280 z24rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
281 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
282 z24rb
->DataType
= GL_UNSIGNED_INT
;
283 z24rb
->DepthBits
= 24;
285 z24rb
->Delete
= delete_wrapper
;
286 z24rb
->AllocStorage
= alloc_wrapper_storage
;
287 z24rb
->GetPointer
= nop_get_pointer
;
288 z24rb
->GetRow
= get_row_z24
;
289 z24rb
->GetValues
= get_values_z24
;
290 z24rb
->PutRow
= put_row_z24
;
291 z24rb
->PutRowRGB
= NULL
;
292 z24rb
->PutMonoRow
= put_mono_row_z24
;
293 z24rb
->PutValues
= put_values_z24
;
294 z24rb
->PutMonoValues
= put_mono_values_z24
;
300 /*======================================================================
301 * Stencil wrapper around depth/stencil renderbuffer
305 get_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
306 GLint x
, GLint y
, void *values
)
308 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
309 GLuint temp
[MAX_WIDTH
], i
;
310 GLubyte
*dst
= (GLubyte
*) values
;
311 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
312 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
313 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
314 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
316 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
319 for (i
= 0; i
< count
; i
++) {
320 dst
[i
] = src
[i
] & 0xff;
325 get_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
326 const GLint x
[], const GLint y
[], void *values
)
328 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
329 GLuint temp
[MAX_WIDTH
], i
;
330 GLubyte
*dst
= (GLubyte
*) values
;
331 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
332 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
333 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
334 ASSERT(count
<= MAX_WIDTH
);
335 /* don't bother trying direct access */
336 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
337 for (i
= 0; i
< count
; i
++) {
338 dst
[i
] = temp
[i
] & 0xff;
343 put_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
344 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
346 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
347 const GLubyte
*src
= (const GLubyte
*) values
;
348 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
349 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
350 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
351 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
355 for (i
= 0; i
< count
; i
++) {
356 if (!mask
|| mask
[i
]) {
357 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
362 /* get, modify, put */
363 GLuint temp
[MAX_WIDTH
], i
;
364 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
365 for (i
= 0; i
< count
; i
++) {
366 if (!mask
|| mask
[i
]) {
367 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
370 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
375 put_mono_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
376 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
378 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
379 const GLubyte val
= *((GLubyte
*) value
);
380 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
381 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
382 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
383 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
387 for (i
= 0; i
< count
; i
++) {
388 if (!mask
|| mask
[i
]) {
389 dst
[i
] = (dst
[i
] & 0xffffff00) | val
;
394 /* get, modify, put */
395 GLuint temp
[MAX_WIDTH
], i
;
396 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
397 for (i
= 0; i
< count
; i
++) {
398 if (!mask
|| mask
[i
]) {
399 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
402 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
407 put_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
408 const GLint x
[], const GLint y
[],
409 const void *values
, const GLubyte
*mask
)
411 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
412 const GLubyte
*src
= (const GLubyte
*) values
;
413 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
414 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
415 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
416 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
419 for (i
= 0; i
< count
; i
++) {
420 if (!mask
|| mask
[i
]) {
421 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
422 *dst
= (*dst
& 0xffffff00) | src
[i
];
427 /* get, modify, put */
428 GLuint temp
[MAX_WIDTH
], i
;
429 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
430 for (i
= 0; i
< count
; i
++) {
431 if (!mask
|| mask
[i
]) {
432 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
435 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
440 put_mono_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
441 const GLint x
[], const GLint y
[],
442 const void *value
, const GLubyte
*mask
)
444 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
445 GLuint temp
[MAX_WIDTH
], i
;
446 const GLubyte val
= *((GLubyte
*) value
);
447 /* get, modify, put */
448 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
449 for (i
= 0; i
< count
; i
++) {
450 if (!mask
|| mask
[i
]) {
451 temp
[i
] = (temp
[i
] & 0xffffff) | val
;
454 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
459 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
460 * a stencil renderbuffer.
461 * \return new stencil renderbuffer
463 struct gl_renderbuffer
*
464 _mesa_new_s8_renderbuffer_wrapper(GLcontext
*ctx
, struct gl_renderbuffer
*dsrb
)
466 struct gl_renderbuffer
*s8rb
;
468 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
469 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
471 s8rb
= _mesa_new_renderbuffer(ctx
, 0);
475 s8rb
->Wrapped
= dsrb
;
476 s8rb
->Name
= dsrb
->Name
;
478 s8rb
->Width
= dsrb
->Width
;
479 s8rb
->Height
= dsrb
->Height
;
480 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
481 s8rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
482 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
483 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
484 s8rb
->StencilBits
= 8;
486 s8rb
->Delete
= delete_wrapper
;
487 s8rb
->AllocStorage
= alloc_wrapper_storage
;
488 s8rb
->GetPointer
= nop_get_pointer
;
489 s8rb
->GetRow
= get_row_s8
;
490 s8rb
->GetValues
= get_values_s8
;
491 s8rb
->PutRow
= put_row_s8
;
492 s8rb
->PutRowRGB
= NULL
;
493 s8rb
->PutMonoRow
= put_mono_row_s8
;
494 s8rb
->PutValues
= put_values_s8
;
495 s8rb
->PutMonoValues
= put_mono_values_s8
;
503 ** The following functions are useful for hardware drivers that only
504 ** implement combined depth/stencil buffers.
505 ** The GL_EXT_framebuffer_object extension allows indepedent depth and
506 ** stencil buffers to be used in any combination.
507 ** Therefore, we sometimes have to merge separate depth and stencil
508 ** renderbuffers into a single depth+stencil renderbuffer. And sometimes
509 ** we have to split combined depth+stencil renderbuffers into separate
515 * Extract stencil values from the combined depth/stencil renderbuffer, storing
516 * the values into a separate stencil renderbuffer.
517 * \param dsRb the source depth/stencil renderbuffer
518 * \param stencilRb the destination stencil renderbuffer
519 * (either 8-bit or 32-bit)
522 _mesa_extract_stencil(GLcontext
*ctx
,
523 struct gl_renderbuffer
*dsRb
,
524 struct gl_renderbuffer
*stencilRb
)
526 GLuint row
, width
, height
;
531 ASSERT(dsRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
532 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
533 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
||
534 stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
535 ASSERT(dsRb
->Width
== stencilRb
->Width
);
536 ASSERT(dsRb
->Height
== stencilRb
->Height
);
539 height
= dsRb
->Height
;
541 for (row
= 0; row
< height
; row
++) {
542 GLuint depthStencil
[MAX_WIDTH
];
543 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
544 if (stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
) {
546 GLubyte stencil
[MAX_WIDTH
];
548 for (i
= 0; i
< width
; i
++) {
549 stencil
[i
] = depthStencil
[i
] & 0xff;
551 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, stencil
, NULL
);
555 /* the 24 depth bits will be ignored */
556 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
557 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
558 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, depthStencil
, NULL
);
565 * Copy stencil values from a stencil renderbuffer into a combined
566 * depth/stencil renderbuffer.
567 * \param dsRb the destination depth/stencil renderbuffer
568 * \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
571 _mesa_insert_stencil(GLcontext
*ctx
,
572 struct gl_renderbuffer
*dsRb
,
573 struct gl_renderbuffer
*stencilRb
)
575 GLuint row
, width
, height
;
580 ASSERT(dsRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
581 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
582 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
||
583 stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
585 ASSERT(dsRb
->Width
== stencilRb
->Width
);
586 ASSERT(dsRb
->Height
== stencilRb
->Height
);
589 height
= dsRb
->Height
;
591 for (row
= 0; row
< height
; row
++) {
592 GLuint depthStencil
[MAX_WIDTH
];
594 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
596 if (stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
) {
598 GLubyte stencil
[MAX_WIDTH
];
600 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
601 for (i
= 0; i
< width
; i
++) {
602 depthStencil
[i
] = (depthStencil
[i
] & 0xffffff00) | stencil
[i
];
606 /* 32bpp stencil buffer */
607 GLuint stencil
[MAX_WIDTH
], i
;
608 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
609 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
610 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
611 for (i
= 0; i
< width
; i
++) {
613 = (depthStencil
[i
] & 0xffffff00) | (stencil
[i
] & 0xff);
617 dsRb
->PutRow(ctx
, dsRb
, width
, 0, row
, depthStencil
, NULL
);
623 * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
624 * \param stencilRb the stencil renderbuffer to promote
627 _mesa_promote_stencil(GLcontext
*ctx
, struct gl_renderbuffer
*stencilRb
)
629 const GLsizei width
= stencilRb
->Width
;
630 const GLsizei height
= stencilRb
->Height
;
634 ASSERT(stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
635 ASSERT(stencilRb
->Data
);
637 data
= (GLubyte
*) stencilRb
->Data
;
638 stencilRb
->Data
= NULL
;
639 stencilRb
->AllocStorage(ctx
, stencilRb
, GL_DEPTH24_STENCIL8_EXT
,
642 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
645 for (i
= 0; i
< height
; i
++) {
646 GLuint depthStencil
[MAX_WIDTH
];
647 for (j
= 0; j
< width
; j
++) {
648 depthStencil
[j
] = data
[k
++];
650 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, i
, depthStencil
, NULL
);
654 stencilRb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;