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 or S8_Z24 renderbuffer with depth and
44 * stencil adaptors, each with the right kind of depth/stencil Get/Put functions.
49 nop_get_pointer(struct gl_context
*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
->Format
== MESA_FORMAT_S8
||
66 rb
->Format
== MESA_FORMAT_X8_Z24
);
67 _mesa_reference_renderbuffer(&rb
->Wrapped
, NULL
);
73 * Realloc storage for wrapper.
76 alloc_wrapper_storage(struct gl_context
*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
->Format
== MESA_FORMAT_Z24_S8
||
86 dsrb
->Format
== MESA_FORMAT_Z24_X8
||
87 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
88 dsrb
->Format
== MESA_FORMAT_X8_Z24
);
90 retVal
= dsrb
->AllocStorage(ctx
, dsrb
, dsrb
->InternalFormat
, width
, height
);
101 /*======================================================================
102 * Depth wrapper around depth/stencil renderbuffer
106 get_row_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
107 GLint x
, GLint y
, void *values
)
109 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
110 GLuint temp
[MAX_WIDTH
], i
;
111 GLuint
*dst
= (GLuint
*) values
;
112 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
113 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
114 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
116 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
119 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
120 for (i
= 0; i
< count
; i
++) {
121 dst
[i
] = src
[i
] >> 8;
125 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
126 for (i
= 0; i
< count
; i
++) {
127 dst
[i
] = src
[i
] & 0xffffff;
133 get_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
134 const GLint x
[], const GLint y
[], void *values
)
136 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
137 GLuint temp
[MAX_WIDTH
], i
;
138 GLuint
*dst
= (GLuint
*) values
;
139 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
140 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
141 ASSERT(count
<= MAX_WIDTH
);
142 /* don't bother trying direct access */
143 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
144 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
145 for (i
= 0; i
< count
; i
++) {
146 dst
[i
] = temp
[i
] >> 8;
150 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
151 for (i
= 0; i
< count
; i
++) {
152 dst
[i
] = temp
[i
] & 0xffffff;
158 put_row_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
159 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
161 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
162 const GLuint
*src
= (const GLuint
*) values
;
163 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
164 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
165 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
169 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
170 for (i
= 0; i
< count
; i
++) {
171 if (!mask
|| mask
[i
]) {
172 dst
[i
] = (src
[i
] << 8) | (dst
[i
] & 0xff);
177 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
178 for (i
= 0; i
< count
; i
++) {
179 if (!mask
|| mask
[i
]) {
180 dst
[i
] = (src
[i
] & 0xffffff) | (dst
[i
] & 0xff000000);
186 /* get, modify, put */
187 GLuint temp
[MAX_WIDTH
], i
;
188 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
189 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
190 for (i
= 0; i
< count
; i
++) {
191 if (!mask
|| mask
[i
]) {
192 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
197 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
198 for (i
= 0; i
< count
; i
++) {
199 if (!mask
|| mask
[i
]) {
200 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
204 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
209 put_mono_row_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
210 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
212 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
213 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
214 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
215 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
219 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
220 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
221 for (i
= 0; i
< count
; i
++) {
222 if (!mask
|| mask
[i
]) {
223 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff);
228 const GLuint shiftedVal
= *((GLuint
*) value
);
229 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
230 for (i
= 0; i
< count
; i
++) {
231 if (!mask
|| mask
[i
]) {
232 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff000000);
238 /* get, modify, put */
239 GLuint temp
[MAX_WIDTH
], i
;
240 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
241 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
242 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
243 for (i
= 0; i
< count
; i
++) {
244 if (!mask
|| mask
[i
]) {
245 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
250 const GLuint shiftedVal
= *((GLuint
*) value
);
251 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
252 for (i
= 0; i
< count
; i
++) {
253 if (!mask
|| mask
[i
]) {
254 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
258 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
263 put_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
264 const GLint x
[], const GLint y
[],
265 const void *values
, const GLubyte
*mask
)
267 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
268 const GLuint
*src
= (const GLuint
*) values
;
269 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
270 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
271 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
274 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
275 for (i
= 0; i
< count
; i
++) {
276 if (!mask
|| mask
[i
]) {
277 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
278 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
283 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
284 for (i
= 0; i
< count
; i
++) {
285 if (!mask
|| mask
[i
]) {
286 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
287 *dst
= (src
[i
] & 0xffffff) | (*dst
& 0xff000000);
293 /* get, modify, put */
294 GLuint temp
[MAX_WIDTH
], i
;
295 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
296 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
297 for (i
= 0; i
< count
; i
++) {
298 if (!mask
|| mask
[i
]) {
299 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
304 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
305 for (i
= 0; i
< count
; i
++) {
306 if (!mask
|| mask
[i
]) {
307 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
311 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
316 put_mono_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
,
317 GLuint count
, const GLint x
[], const GLint y
[],
318 const void *value
, const GLubyte
*mask
)
320 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
321 GLuint temp
[MAX_WIDTH
], i
;
322 /* get, modify, put */
323 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
324 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
325 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
326 for (i
= 0; i
< count
; i
++) {
327 if (!mask
|| mask
[i
]) {
328 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
333 const GLuint shiftedVal
= *((GLuint
*) value
);
334 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
335 for (i
= 0; i
< count
; i
++) {
336 if (!mask
|| mask
[i
]) {
337 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
341 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
346 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
347 * a depth renderbuffer.
348 * \return new depth renderbuffer
350 struct gl_renderbuffer
*
351 _mesa_new_z24_renderbuffer_wrapper(struct gl_context
*ctx
,
352 struct gl_renderbuffer
*dsrb
)
354 struct gl_renderbuffer
*z24rb
;
356 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
357 dsrb
->Format
== MESA_FORMAT_Z24_X8
||
358 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
359 dsrb
->Format
== MESA_FORMAT_X8_Z24
);
360 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
362 z24rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
366 /* NOTE: need to do manual refcounting here */
367 z24rb
->Wrapped
= dsrb
;
370 z24rb
->Name
= dsrb
->Name
;
372 z24rb
->Width
= dsrb
->Width
;
373 z24rb
->Height
= dsrb
->Height
;
374 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
375 z24rb
->Format
= MESA_FORMAT_X8_Z24
;
376 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
377 z24rb
->DataType
= GL_UNSIGNED_INT
;
379 z24rb
->Delete
= delete_wrapper
;
380 z24rb
->AllocStorage
= alloc_wrapper_storage
;
381 z24rb
->GetPointer
= nop_get_pointer
;
382 z24rb
->GetRow
= get_row_z24
;
383 z24rb
->GetValues
= get_values_z24
;
384 z24rb
->PutRow
= put_row_z24
;
385 z24rb
->PutRowRGB
= NULL
;
386 z24rb
->PutMonoRow
= put_mono_row_z24
;
387 z24rb
->PutValues
= put_values_z24
;
388 z24rb
->PutMonoValues
= put_mono_values_z24
;
394 /*======================================================================
395 * Stencil wrapper around depth/stencil renderbuffer
399 get_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
400 GLint x
, GLint y
, void *values
)
402 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
403 GLuint temp
[MAX_WIDTH
], i
;
404 GLubyte
*dst
= (GLubyte
*) values
;
405 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
406 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
407 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
409 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
412 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
413 for (i
= 0; i
< count
; i
++) {
414 dst
[i
] = src
[i
] & 0xff;
418 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
419 for (i
= 0; i
< count
; i
++) {
420 dst
[i
] = src
[i
] >> 24;
426 get_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
427 const GLint x
[], const GLint y
[], void *values
)
429 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
430 GLuint temp
[MAX_WIDTH
], i
;
431 GLubyte
*dst
= (GLubyte
*) values
;
432 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
433 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
434 ASSERT(count
<= MAX_WIDTH
);
435 /* don't bother trying direct access */
436 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
437 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
438 for (i
= 0; i
< count
; i
++) {
439 dst
[i
] = temp
[i
] & 0xff;
443 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
444 for (i
= 0; i
< count
; i
++) {
445 dst
[i
] = temp
[i
] >> 24;
451 put_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
452 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
454 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
455 const GLubyte
*src
= (const GLubyte
*) values
;
456 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
457 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
458 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
462 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
463 for (i
= 0; i
< count
; i
++) {
464 if (!mask
|| mask
[i
]) {
465 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
470 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
471 for (i
= 0; i
< count
; i
++) {
472 if (!mask
|| mask
[i
]) {
473 dst
[i
] = (dst
[i
] & 0xffffff) | (src
[i
] << 24);
479 /* get, modify, put */
480 GLuint temp
[MAX_WIDTH
], i
;
481 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
482 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
483 for (i
= 0; i
< count
; i
++) {
484 if (!mask
|| mask
[i
]) {
485 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
490 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
491 for (i
= 0; i
< count
; i
++) {
492 if (!mask
|| mask
[i
]) {
493 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
497 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
502 put_mono_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
503 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
505 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
506 const GLubyte val
= *((GLubyte
*) value
);
507 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
508 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
509 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
513 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
514 for (i
= 0; i
< count
; i
++) {
515 if (!mask
|| mask
[i
]) {
516 dst
[i
] = (dst
[i
] & 0xffffff00) | val
;
521 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
522 for (i
= 0; i
< count
; i
++) {
523 if (!mask
|| mask
[i
]) {
524 dst
[i
] = (dst
[i
] & 0xffffff) | (val
<< 24);
530 /* get, modify, put */
531 GLuint temp
[MAX_WIDTH
], i
;
532 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
533 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
534 for (i
= 0; i
< count
; i
++) {
535 if (!mask
|| mask
[i
]) {
536 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
541 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
542 for (i
= 0; i
< count
; i
++) {
543 if (!mask
|| mask
[i
]) {
544 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
548 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
553 put_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
554 const GLint x
[], const GLint y
[],
555 const void *values
, const GLubyte
*mask
)
557 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
558 const GLubyte
*src
= (const GLubyte
*) values
;
559 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
560 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
561 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
564 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
565 for (i
= 0; i
< count
; i
++) {
566 if (!mask
|| mask
[i
]) {
567 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
568 *dst
= (*dst
& 0xffffff00) | src
[i
];
573 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
574 for (i
= 0; i
< count
; i
++) {
575 if (!mask
|| mask
[i
]) {
576 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
577 *dst
= (*dst
& 0xffffff) | (src
[i
] << 24);
583 /* get, modify, put */
584 GLuint temp
[MAX_WIDTH
], i
;
585 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
586 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
587 for (i
= 0; i
< count
; i
++) {
588 if (!mask
|| mask
[i
]) {
589 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
594 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
595 for (i
= 0; i
< count
; i
++) {
596 if (!mask
|| mask
[i
]) {
597 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
601 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
606 put_mono_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
607 const GLint x
[], const GLint y
[],
608 const void *value
, const GLubyte
*mask
)
610 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
611 GLuint temp
[MAX_WIDTH
], i
;
612 const GLubyte val
= *((GLubyte
*) value
);
613 /* get, modify, put */
614 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
615 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
616 for (i
= 0; i
< count
; i
++) {
617 if (!mask
|| mask
[i
]) {
618 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
623 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
624 for (i
= 0; i
< count
; i
++) {
625 if (!mask
|| mask
[i
]) {
626 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
630 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
635 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
636 * a stencil renderbuffer.
637 * \return new stencil renderbuffer
639 struct gl_renderbuffer
*
640 _mesa_new_s8_renderbuffer_wrapper(struct gl_context
*ctx
, struct gl_renderbuffer
*dsrb
)
642 struct gl_renderbuffer
*s8rb
;
644 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
645 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
646 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
648 s8rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
652 /* NOTE: need to do manual refcounting here */
653 s8rb
->Wrapped
= dsrb
;
656 s8rb
->Name
= dsrb
->Name
;
658 s8rb
->Width
= dsrb
->Width
;
659 s8rb
->Height
= dsrb
->Height
;
660 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
661 s8rb
->Format
= MESA_FORMAT_S8
;
662 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
663 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
665 s8rb
->Delete
= delete_wrapper
;
666 s8rb
->AllocStorage
= alloc_wrapper_storage
;
667 s8rb
->GetPointer
= nop_get_pointer
;
668 s8rb
->GetRow
= get_row_s8
;
669 s8rb
->GetValues
= get_values_s8
;
670 s8rb
->PutRow
= put_row_s8
;
671 s8rb
->PutRowRGB
= NULL
;
672 s8rb
->PutMonoRow
= put_mono_row_s8
;
673 s8rb
->PutValues
= put_values_s8
;
674 s8rb
->PutMonoValues
= put_mono_values_s8
;
682 ** The following functions are useful for hardware drivers that only
683 ** implement combined depth/stencil buffers.
684 ** The GL_EXT_framebuffer_object extension allows indepedent depth and
685 ** stencil buffers to be used in any combination.
686 ** Therefore, we sometimes have to merge separate depth and stencil
687 ** renderbuffers into a single depth+stencil renderbuffer. And sometimes
688 ** we have to split combined depth+stencil renderbuffers into separate
694 * Extract stencil values from the combined depth/stencil renderbuffer, storing
695 * the values into a separate stencil renderbuffer.
696 * \param dsRb the source depth/stencil renderbuffer
697 * \param stencilRb the destination stencil renderbuffer
698 * (either 8-bit or 32-bit)
701 _mesa_extract_stencil(struct gl_context
*ctx
,
702 struct gl_renderbuffer
*dsRb
,
703 struct gl_renderbuffer
*stencilRb
)
705 GLuint row
, width
, height
;
710 ASSERT(dsRb
->Format
== MESA_FORMAT_Z24_S8
);
711 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
712 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
||
713 stencilRb
->Format
== MESA_FORMAT_S8
);
714 ASSERT(dsRb
->Width
== stencilRb
->Width
);
715 ASSERT(dsRb
->Height
== stencilRb
->Height
);
718 height
= dsRb
->Height
;
720 for (row
= 0; row
< height
; row
++) {
721 GLuint depthStencil
[MAX_WIDTH
];
722 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
723 if (stencilRb
->Format
== MESA_FORMAT_S8
) {
725 GLubyte stencil
[MAX_WIDTH
];
727 for (i
= 0; i
< width
; i
++) {
728 stencil
[i
] = depthStencil
[i
] & 0xff;
730 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, stencil
, NULL
);
734 /* the 24 depth bits will be ignored */
735 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
);
736 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
737 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, depthStencil
, NULL
);
744 * Copy stencil values from a stencil renderbuffer into a combined
745 * depth/stencil renderbuffer.
746 * \param dsRb the destination depth/stencil renderbuffer
747 * \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
750 _mesa_insert_stencil(struct gl_context
*ctx
,
751 struct gl_renderbuffer
*dsRb
,
752 struct gl_renderbuffer
*stencilRb
)
754 GLuint row
, width
, height
;
759 ASSERT(dsRb
->Format
== MESA_FORMAT_Z24_S8
);
760 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
761 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
||
762 stencilRb
->Format
== MESA_FORMAT_S8
);
764 ASSERT(dsRb
->Width
== stencilRb
->Width
);
765 ASSERT(dsRb
->Height
== stencilRb
->Height
);
768 height
= dsRb
->Height
;
770 for (row
= 0; row
< height
; row
++) {
771 GLuint depthStencil
[MAX_WIDTH
];
773 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
775 if (stencilRb
->Format
== MESA_FORMAT_S8
) {
777 GLubyte stencil
[MAX_WIDTH
];
779 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
780 for (i
= 0; i
< width
; i
++) {
781 depthStencil
[i
] = (depthStencil
[i
] & 0xffffff00) | stencil
[i
];
785 /* 32bpp stencil buffer */
786 GLuint stencil
[MAX_WIDTH
], i
;
787 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
);
788 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
789 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
790 for (i
= 0; i
< width
; i
++) {
792 = (depthStencil
[i
] & 0xffffff00) | (stencil
[i
] & 0xff);
796 dsRb
->PutRow(ctx
, dsRb
, width
, 0, row
, depthStencil
, NULL
);
802 * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
803 * \param stencilRb the stencil renderbuffer to promote
806 _mesa_promote_stencil(struct gl_context
*ctx
, struct gl_renderbuffer
*stencilRb
)
808 const GLsizei width
= stencilRb
->Width
;
809 const GLsizei height
= stencilRb
->Height
;
813 ASSERT(stencilRb
->Format
== MESA_FORMAT_S8
);
814 ASSERT(stencilRb
->Data
);
816 data
= (GLubyte
*) stencilRb
->Data
;
817 stencilRb
->Data
= NULL
;
818 stencilRb
->AllocStorage(ctx
, stencilRb
, GL_DEPTH24_STENCIL8_EXT
,
821 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
824 for (i
= 0; i
< height
; i
++) {
825 GLuint depthStencil
[MAX_WIDTH
];
826 for (j
= 0; j
< width
; j
++) {
827 depthStencil
[j
] = data
[k
++];
829 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, i
, depthStencil
, NULL
);