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 struct gl_renderbuffer
*dsrb
= rb
->Wrapped
;
67 ASSERT(rb
->_ActualFormat
== GL_DEPTH_COMPONENT24
||
68 rb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
69 /* decrement refcount on the wrapped buffer and delete it if necessary */
71 if (dsrb
->RefCount
<= 0) {
79 * Realloc storage for wrapper.
82 alloc_wrapper_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
83 GLenum internalFormat
, GLuint width
, GLuint height
)
85 /* just pass this on to the wrapped renderbuffer */
86 struct gl_renderbuffer
*dsrb
= rb
->Wrapped
;
89 (void) internalFormat
;
91 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
93 retVal
= dsrb
->AllocStorage(ctx
, dsrb
, dsrb
->InternalFormat
, width
, height
);
104 /*======================================================================
105 * Depth wrapper around depth/stencil renderbuffer
109 get_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
110 GLint x
, GLint y
, void *values
)
112 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
113 GLuint temp
[MAX_WIDTH
], i
;
114 GLuint
*dst
= (GLuint
*) values
;
115 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
116 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
117 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
118 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
120 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
123 for (i
= 0; i
< count
; i
++) {
124 dst
[i
] = src
[i
] >> 8;
129 get_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
130 const GLint x
[], const GLint y
[], void *values
)
132 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
133 GLuint temp
[MAX_WIDTH
], i
;
134 GLuint
*dst
= (GLuint
*) values
;
135 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
136 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
137 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
138 ASSERT(count
<= MAX_WIDTH
);
139 /* don't bother trying direct access */
140 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
141 for (i
= 0; i
< count
; i
++) {
142 dst
[i
] = temp
[i
] >> 8;
147 put_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
148 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
150 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
151 const GLuint
*src
= (const GLuint
*) values
;
152 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
153 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
154 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
155 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
159 for (i
= 0; i
< count
; i
++) {
160 if (!mask
|| mask
[i
]) {
161 dst
[i
] = (src
[i
] << 8) | (dst
[i
] & 0xff);
166 /* get, modify, put */
167 GLuint temp
[MAX_WIDTH
], i
;
168 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
169 for (i
= 0; i
< count
; i
++) {
170 if (!mask
|| mask
[i
]) {
171 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
174 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
179 put_mono_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
180 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
182 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
183 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
184 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
185 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
186 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
187 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
191 for (i
= 0; i
< count
; i
++) {
192 if (!mask
|| mask
[i
]) {
193 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff);
198 /* get, modify, put */
199 GLuint temp
[MAX_WIDTH
], i
;
200 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
201 for (i
= 0; i
< count
; i
++) {
202 if (!mask
|| mask
[i
]) {
203 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
206 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
211 put_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
212 const GLint x
[], const GLint y
[],
213 const void *values
, const GLubyte
*mask
)
215 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
216 const GLuint
*src
= (const GLuint
*) values
;
217 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
218 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
219 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
220 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
223 for (i
= 0; i
< count
; i
++) {
224 if (!mask
|| mask
[i
]) {
225 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
226 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
231 /* get, modify, put */
232 GLuint temp
[MAX_WIDTH
], i
;
233 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
234 for (i
= 0; i
< count
; i
++) {
235 if (!mask
|| mask
[i
]) {
236 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
239 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
244 put_mono_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
,
245 GLuint count
, const GLint x
[], const GLint y
[],
246 const void *value
, const GLubyte
*mask
)
248 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
249 GLuint temp
[MAX_WIDTH
], i
;
250 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
251 /* get, modify, put */
252 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
253 for (i
= 0; i
< count
; i
++) {
254 if (!mask
|| mask
[i
]) {
255 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
258 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
263 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
264 * a depth renderbuffer.
265 * \return new depth renderbuffer
267 struct gl_renderbuffer
*
268 _mesa_new_z24_renderbuffer_wrapper(GLcontext
*ctx
,
269 struct gl_renderbuffer
*dsrb
)
271 struct gl_renderbuffer
*z24rb
;
273 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
274 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
276 z24rb
= _mesa_new_renderbuffer(ctx
, 0);
280 z24rb
->Wrapped
= dsrb
;
281 z24rb
->Name
= dsrb
->Name
;
283 z24rb
->Width
= dsrb
->Width
;
284 z24rb
->Height
= dsrb
->Height
;
285 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
286 z24rb
->_ActualFormat
= GL_DEPTH_COMPONENT24
;
287 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
288 z24rb
->DataType
= GL_UNSIGNED_INT
;
289 z24rb
->DepthBits
= 24;
291 z24rb
->Delete
= delete_wrapper
;
292 z24rb
->AllocStorage
= alloc_wrapper_storage
;
293 z24rb
->GetPointer
= nop_get_pointer
;
294 z24rb
->GetRow
= get_row_z24
;
295 z24rb
->GetValues
= get_values_z24
;
296 z24rb
->PutRow
= put_row_z24
;
297 z24rb
->PutRowRGB
= NULL
;
298 z24rb
->PutMonoRow
= put_mono_row_z24
;
299 z24rb
->PutValues
= put_values_z24
;
300 z24rb
->PutMonoValues
= put_mono_values_z24
;
306 /*======================================================================
307 * Stencil wrapper around depth/stencil renderbuffer
311 get_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
312 GLint x
, GLint y
, void *values
)
314 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
315 GLuint temp
[MAX_WIDTH
], i
;
316 GLubyte
*dst
= (GLubyte
*) values
;
317 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
318 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
319 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
320 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
322 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
325 for (i
= 0; i
< count
; i
++) {
326 dst
[i
] = src
[i
] & 0xff;
331 get_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
332 const GLint x
[], const GLint y
[], void *values
)
334 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
335 GLuint temp
[MAX_WIDTH
], i
;
336 GLubyte
*dst
= (GLubyte
*) values
;
337 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
338 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
339 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
340 ASSERT(count
<= MAX_WIDTH
);
341 /* don't bother trying direct access */
342 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
343 for (i
= 0; i
< count
; i
++) {
344 dst
[i
] = temp
[i
] & 0xff;
349 put_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
350 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
352 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
353 const GLubyte
*src
= (const GLubyte
*) values
;
354 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
355 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
356 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
357 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
361 for (i
= 0; i
< count
; i
++) {
362 if (!mask
|| mask
[i
]) {
363 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
368 /* get, modify, put */
369 GLuint temp
[MAX_WIDTH
], i
;
370 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
371 for (i
= 0; i
< count
; i
++) {
372 if (!mask
|| mask
[i
]) {
373 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
376 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
381 put_mono_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
382 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
384 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
385 const GLubyte val
= *((GLubyte
*) value
);
386 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
387 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
388 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
389 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
393 for (i
= 0; i
< count
; i
++) {
394 if (!mask
|| mask
[i
]) {
395 dst
[i
] = (dst
[i
] & 0xffffff00) | val
;
400 /* get, modify, put */
401 GLuint temp
[MAX_WIDTH
], i
;
402 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
403 for (i
= 0; i
< count
; i
++) {
404 if (!mask
|| mask
[i
]) {
405 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
408 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
413 put_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
414 const GLint x
[], const GLint y
[],
415 const void *values
, const GLubyte
*mask
)
417 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
418 const GLubyte
*src
= (const GLubyte
*) values
;
419 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
420 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
421 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
422 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
425 for (i
= 0; i
< count
; i
++) {
426 if (!mask
|| mask
[i
]) {
427 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
428 *dst
= (*dst
& 0xffffff00) | src
[i
];
433 /* get, modify, put */
434 GLuint temp
[MAX_WIDTH
], i
;
435 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
436 for (i
= 0; i
< count
; i
++) {
437 if (!mask
|| mask
[i
]) {
438 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
441 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
446 put_mono_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
447 const GLint x
[], const GLint y
[],
448 const void *value
, const GLubyte
*mask
)
450 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
451 GLuint temp
[MAX_WIDTH
], i
;
452 const GLubyte val
= *((GLubyte
*) value
);
453 /* get, modify, put */
454 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
455 for (i
= 0; i
< count
; i
++) {
456 if (!mask
|| mask
[i
]) {
457 temp
[i
] = (temp
[i
] & 0xffffff) | val
;
460 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
465 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
466 * a stencil renderbuffer.
467 * \return new stencil renderbuffer
469 struct gl_renderbuffer
*
470 _mesa_new_s8_renderbuffer_wrapper(GLcontext
*ctx
, struct gl_renderbuffer
*dsrb
)
472 struct gl_renderbuffer
*s8rb
;
474 ASSERT(dsrb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
475 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
477 s8rb
= _mesa_new_renderbuffer(ctx
, 0);
481 s8rb
->Wrapped
= dsrb
;
482 s8rb
->Name
= dsrb
->Name
;
484 s8rb
->Width
= dsrb
->Width
;
485 s8rb
->Height
= dsrb
->Height
;
486 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
487 s8rb
->_ActualFormat
= GL_STENCIL_INDEX8_EXT
;
488 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
489 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
490 s8rb
->StencilBits
= 8;
492 s8rb
->Delete
= delete_wrapper
;
493 s8rb
->AllocStorage
= alloc_wrapper_storage
;
494 s8rb
->GetPointer
= nop_get_pointer
;
495 s8rb
->GetRow
= get_row_s8
;
496 s8rb
->GetValues
= get_values_s8
;
497 s8rb
->PutRow
= put_row_s8
;
498 s8rb
->PutRowRGB
= NULL
;
499 s8rb
->PutMonoRow
= put_mono_row_s8
;
500 s8rb
->PutValues
= put_values_s8
;
501 s8rb
->PutMonoValues
= put_mono_values_s8
;
509 ** The following functions are useful for hardware drivers that only
510 ** implement combined depth/stencil buffers.
511 ** The GL_EXT_framebuffer_object extension allows indepedent depth and
512 ** stencil buffers to be used in any combination.
513 ** Therefore, we sometimes have to merge separate depth and stencil
514 ** renderbuffers into a single depth+stencil renderbuffer. And sometimes
515 ** we have to split combined depth+stencil renderbuffers into separate
521 * Extract stencil values from the combined depth/stencil renderbuffer, storing
522 * the values into a separate stencil renderbuffer.
523 * \param dsRb the source depth/stencil renderbuffer
524 * \param stencilRb the destination stencil renderbuffer
525 * (either 8-bit or 32-bit)
528 _mesa_extract_stencil(GLcontext
*ctx
,
529 struct gl_renderbuffer
*dsRb
,
530 struct gl_renderbuffer
*stencilRb
)
532 GLuint row
, width
, height
;
537 ASSERT(dsRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
538 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
539 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
||
540 stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
541 ASSERT(dsRb
->Width
== stencilRb
->Width
);
542 ASSERT(dsRb
->Height
== stencilRb
->Height
);
545 height
= dsRb
->Height
;
547 for (row
= 0; row
< height
; row
++) {
548 GLuint depthStencil
[MAX_WIDTH
];
549 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
550 if (stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
) {
552 GLubyte stencil
[MAX_WIDTH
];
554 for (i
= 0; i
< width
; i
++) {
555 stencil
[i
] = depthStencil
[i
] & 0xff;
557 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, stencil
, NULL
);
561 /* the 24 depth bits will be ignored */
562 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
563 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
564 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, depthStencil
, NULL
);
571 * Copy stencil values from a stencil renderbuffer into a combined
572 * depth/stencil renderbuffer.
573 * \param dsRb the destination depth/stencil renderbuffer
574 * \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
577 _mesa_insert_stencil(GLcontext
*ctx
,
578 struct gl_renderbuffer
*dsRb
,
579 struct gl_renderbuffer
*stencilRb
)
581 GLuint row
, width
, height
;
586 ASSERT(dsRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
587 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
588 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
||
589 stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
591 ASSERT(dsRb
->Width
== stencilRb
->Width
);
592 ASSERT(dsRb
->Height
== stencilRb
->Height
);
595 height
= dsRb
->Height
;
597 for (row
= 0; row
< height
; row
++) {
598 GLuint depthStencil
[MAX_WIDTH
];
600 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
602 if (stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
) {
604 GLubyte stencil
[MAX_WIDTH
];
606 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
607 for (i
= 0; i
< width
; i
++) {
608 depthStencil
[i
] = (depthStencil
[i
] & 0xffffff00) | stencil
[i
];
612 /* 32bpp stencil buffer */
613 GLuint stencil
[MAX_WIDTH
], i
;
614 ASSERT(stencilRb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
615 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
616 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
617 for (i
= 0; i
< width
; i
++) {
619 = (depthStencil
[i
] & 0xffffff00) | (stencil
[i
] & 0xff);
623 dsRb
->PutRow(ctx
, dsRb
, width
, 0, row
, depthStencil
, NULL
);
629 * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
630 * \param stencilRb the stencil renderbuffer to promote
633 _mesa_promote_stencil(GLcontext
*ctx
, struct gl_renderbuffer
*stencilRb
)
635 const GLsizei width
= stencilRb
->Width
;
636 const GLsizei height
= stencilRb
->Height
;
640 ASSERT(stencilRb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
);
641 ASSERT(stencilRb
->Data
);
643 data
= (GLubyte
*) stencilRb
->Data
;
644 stencilRb
->Data
= NULL
;
645 stencilRb
->AllocStorage(ctx
, stencilRb
, GL_DEPTH24_STENCIL8_EXT
,
648 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
651 for (i
= 0; i
< height
; i
++) {
652 GLuint depthStencil
[MAX_WIDTH
];
653 for (j
= 0; j
< width
; j
++) {
654 depthStencil
[j
] = data
[k
++];
656 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, i
, depthStencil
, NULL
);
660 stencilRb
->_BaseFormat
= GL_DEPTH_STENCIL_EXT
;