892520b695908a5bec5b43b55e095ade9f2e949f
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(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
->Format
== MESA_FORMAT_Z24_S8
||
66 rb
->Format
== MESA_FORMAT_S8_Z24
);
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
->Format
== MESA_FORMAT_Z24_S8
||
86 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
88 retVal
= dsrb
->AllocStorage(ctx
, dsrb
, dsrb
->InternalFormat
, width
, height
);
99 /*======================================================================
100 * Depth wrapper around depth/stencil renderbuffer
104 get_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
105 GLint x
, GLint y
, void *values
)
107 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
108 GLuint temp
[MAX_WIDTH
], i
;
109 GLuint
*dst
= (GLuint
*) values
;
110 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
111 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
112 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
114 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
117 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
118 for (i
= 0; i
< count
; i
++) {
119 dst
[i
] = src
[i
] >> 8;
123 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
124 for (i
= 0; i
< count
; i
++) {
125 dst
[i
] = src
[i
] & 0xffffff;
131 get_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
132 const GLint x
[], const GLint y
[], void *values
)
134 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
135 GLuint temp
[MAX_WIDTH
], i
;
136 GLuint
*dst
= (GLuint
*) values
;
137 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
138 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
139 ASSERT(count
<= MAX_WIDTH
);
140 /* don't bother trying direct access */
141 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
142 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
143 for (i
= 0; i
< count
; i
++) {
144 dst
[i
] = temp
[i
] >> 8;
148 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
149 for (i
= 0; i
< count
; i
++) {
150 dst
[i
] = temp
[i
] & 0xffffff;
156 put_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
157 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
159 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
160 const GLuint
*src
= (const GLuint
*) values
;
161 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
162 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
163 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
167 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
168 for (i
= 0; i
< count
; i
++) {
169 if (!mask
|| mask
[i
]) {
170 dst
[i
] = (src
[i
] << 8) | (dst
[i
] & 0xff);
175 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
176 for (i
= 0; i
< count
; i
++) {
177 if (!mask
|| mask
[i
]) {
178 dst
[i
] = (src
[i
] & 0xffffff) | (dst
[i
] & 0xff000000);
184 /* get, modify, put */
185 GLuint temp
[MAX_WIDTH
], i
;
186 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
187 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
188 for (i
= 0; i
< count
; i
++) {
189 if (!mask
|| mask
[i
]) {
190 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
195 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
196 for (i
= 0; i
< count
; i
++) {
197 if (!mask
|| mask
[i
]) {
198 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
202 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
207 put_mono_row_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
208 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
210 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
211 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
212 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
213 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
217 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
218 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
219 for (i
= 0; i
< count
; i
++) {
220 if (!mask
|| mask
[i
]) {
221 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff);
226 const GLuint shiftedVal
= *((GLuint
*) value
);
227 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
228 for (i
= 0; i
< count
; i
++) {
229 if (!mask
|| mask
[i
]) {
230 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff000000);
236 /* get, modify, put */
237 GLuint temp
[MAX_WIDTH
], i
;
238 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
239 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
240 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
241 for (i
= 0; i
< count
; i
++) {
242 if (!mask
|| mask
[i
]) {
243 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
248 const GLuint shiftedVal
= *((GLuint
*) value
);
249 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
250 for (i
= 0; i
< count
; i
++) {
251 if (!mask
|| mask
[i
]) {
252 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
256 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
261 put_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
262 const GLint x
[], const GLint y
[],
263 const void *values
, const GLubyte
*mask
)
265 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
266 const GLuint
*src
= (const GLuint
*) values
;
267 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
268 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
269 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
272 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
273 for (i
= 0; i
< count
; i
++) {
274 if (!mask
|| mask
[i
]) {
275 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
276 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
281 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
282 for (i
= 0; i
< count
; i
++) {
283 if (!mask
|| mask
[i
]) {
284 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
285 *dst
= (src
[i
] & 0xffffff) | (*dst
& 0xff000000);
291 /* get, modify, put */
292 GLuint temp
[MAX_WIDTH
], i
;
293 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
294 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
295 for (i
= 0; i
< count
; i
++) {
296 if (!mask
|| mask
[i
]) {
297 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
302 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
303 for (i
= 0; i
< count
; i
++) {
304 if (!mask
|| mask
[i
]) {
305 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
309 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
314 put_mono_values_z24(GLcontext
*ctx
, struct gl_renderbuffer
*z24rb
,
315 GLuint count
, const GLint x
[], const GLint y
[],
316 const void *value
, const GLubyte
*mask
)
318 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
319 GLuint temp
[MAX_WIDTH
], i
;
320 /* get, modify, put */
321 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
322 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
323 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
324 for (i
= 0; i
< count
; i
++) {
325 if (!mask
|| mask
[i
]) {
326 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
331 const GLuint shiftedVal
= *((GLuint
*) value
);
332 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
333 for (i
= 0; i
< count
; i
++) {
334 if (!mask
|| mask
[i
]) {
335 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
339 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
344 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
345 * a depth renderbuffer.
346 * \return new depth renderbuffer
348 struct gl_renderbuffer
*
349 _mesa_new_z24_renderbuffer_wrapper(GLcontext
*ctx
,
350 struct gl_renderbuffer
*dsrb
)
352 struct gl_renderbuffer
*z24rb
;
354 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
355 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
356 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
358 z24rb
= _mesa_new_renderbuffer(ctx
, 0);
362 z24rb
->Wrapped
= dsrb
;
363 z24rb
->Name
= dsrb
->Name
;
365 z24rb
->Width
= dsrb
->Width
;
366 z24rb
->Height
= dsrb
->Height
;
367 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
368 z24rb
->Format
= MESA_FORMAT_X8_Z24
;
369 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
370 z24rb
->DataType
= GL_UNSIGNED_INT
;
372 z24rb
->Delete
= delete_wrapper
;
373 z24rb
->AllocStorage
= alloc_wrapper_storage
;
374 z24rb
->GetPointer
= nop_get_pointer
;
375 z24rb
->GetRow
= get_row_z24
;
376 z24rb
->GetValues
= get_values_z24
;
377 z24rb
->PutRow
= put_row_z24
;
378 z24rb
->PutRowRGB
= NULL
;
379 z24rb
->PutMonoRow
= put_mono_row_z24
;
380 z24rb
->PutValues
= put_values_z24
;
381 z24rb
->PutMonoValues
= put_mono_values_z24
;
387 /*======================================================================
388 * Stencil wrapper around depth/stencil renderbuffer
392 get_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
393 GLint x
, GLint y
, void *values
)
395 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
396 GLuint temp
[MAX_WIDTH
], i
;
397 GLubyte
*dst
= (GLubyte
*) values
;
398 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
399 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
400 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
402 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
405 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
406 for (i
= 0; i
< count
; i
++) {
407 dst
[i
] = src
[i
] & 0xff;
411 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
412 for (i
= 0; i
< count
; i
++) {
413 dst
[i
] = src
[i
] >> 24;
419 get_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
420 const GLint x
[], const GLint y
[], void *values
)
422 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
423 GLuint temp
[MAX_WIDTH
], i
;
424 GLubyte
*dst
= (GLubyte
*) values
;
425 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
426 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
427 ASSERT(count
<= MAX_WIDTH
);
428 /* don't bother trying direct access */
429 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
430 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
431 for (i
= 0; i
< count
; i
++) {
432 dst
[i
] = temp
[i
] & 0xff;
436 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
437 for (i
= 0; i
< count
; i
++) {
438 dst
[i
] = temp
[i
] >> 24;
444 put_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
445 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
447 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
448 const GLubyte
*src
= (const GLubyte
*) values
;
449 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
450 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
451 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
455 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
456 for (i
= 0; i
< count
; i
++) {
457 if (!mask
|| mask
[i
]) {
458 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
463 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
464 for (i
= 0; i
< count
; i
++) {
465 if (!mask
|| mask
[i
]) {
466 dst
[i
] = (dst
[i
] & 0xffffff) | (src
[i
] << 24);
472 /* get, modify, put */
473 GLuint temp
[MAX_WIDTH
], i
;
474 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
475 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
476 for (i
= 0; i
< count
; i
++) {
477 if (!mask
|| mask
[i
]) {
478 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
483 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
484 for (i
= 0; i
< count
; i
++) {
485 if (!mask
|| mask
[i
]) {
486 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
490 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
495 put_mono_row_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
496 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
498 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
499 const GLubyte val
= *((GLubyte
*) value
);
500 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
501 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
502 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
506 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
507 for (i
= 0; i
< count
; i
++) {
508 if (!mask
|| mask
[i
]) {
509 dst
[i
] = (dst
[i
] & 0xffffff00) | val
;
514 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
515 for (i
= 0; i
< count
; i
++) {
516 if (!mask
|| mask
[i
]) {
517 dst
[i
] = (dst
[i
] & 0xffffff) | (val
<< 24);
523 /* get, modify, put */
524 GLuint temp
[MAX_WIDTH
], i
;
525 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
526 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
527 for (i
= 0; i
< count
; i
++) {
528 if (!mask
|| mask
[i
]) {
529 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
534 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
535 for (i
= 0; i
< count
; i
++) {
536 if (!mask
|| mask
[i
]) {
537 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
541 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
546 put_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
547 const GLint x
[], const GLint y
[],
548 const void *values
, const GLubyte
*mask
)
550 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
551 const GLubyte
*src
= (const GLubyte
*) values
;
552 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
553 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
554 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
557 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
558 for (i
= 0; i
< count
; i
++) {
559 if (!mask
|| mask
[i
]) {
560 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
561 *dst
= (*dst
& 0xffffff00) | src
[i
];
566 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
567 for (i
= 0; i
< count
; i
++) {
568 if (!mask
|| mask
[i
]) {
569 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
570 *dst
= (*dst
& 0xffffff) | (src
[i
] << 24);
576 /* get, modify, put */
577 GLuint temp
[MAX_WIDTH
], i
;
578 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
579 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
580 for (i
= 0; i
< count
; i
++) {
581 if (!mask
|| mask
[i
]) {
582 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
587 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
588 for (i
= 0; i
< count
; i
++) {
589 if (!mask
|| mask
[i
]) {
590 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
594 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
599 put_mono_values_s8(GLcontext
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
600 const GLint x
[], const GLint y
[],
601 const void *value
, const GLubyte
*mask
)
603 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
604 GLuint temp
[MAX_WIDTH
], i
;
605 const GLubyte val
= *((GLubyte
*) value
);
606 /* get, modify, put */
607 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
608 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
609 for (i
= 0; i
< count
; i
++) {
610 if (!mask
|| mask
[i
]) {
611 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
616 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
617 for (i
= 0; i
< count
; i
++) {
618 if (!mask
|| mask
[i
]) {
619 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
623 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
628 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
629 * a stencil renderbuffer.
630 * \return new stencil renderbuffer
632 struct gl_renderbuffer
*
633 _mesa_new_s8_renderbuffer_wrapper(GLcontext
*ctx
, struct gl_renderbuffer
*dsrb
)
635 struct gl_renderbuffer
*s8rb
;
637 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
638 dsrb
->Format
== MESA_FORMAT_S8_Z24
);
639 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
641 s8rb
= _mesa_new_renderbuffer(ctx
, 0);
645 s8rb
->Wrapped
= dsrb
;
646 s8rb
->Name
= dsrb
->Name
;
648 s8rb
->Width
= dsrb
->Width
;
649 s8rb
->Height
= dsrb
->Height
;
650 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
651 s8rb
->Format
= MESA_FORMAT_S8
;
652 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
653 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
655 s8rb
->Delete
= delete_wrapper
;
656 s8rb
->AllocStorage
= alloc_wrapper_storage
;
657 s8rb
->GetPointer
= nop_get_pointer
;
658 s8rb
->GetRow
= get_row_s8
;
659 s8rb
->GetValues
= get_values_s8
;
660 s8rb
->PutRow
= put_row_s8
;
661 s8rb
->PutRowRGB
= NULL
;
662 s8rb
->PutMonoRow
= put_mono_row_s8
;
663 s8rb
->PutValues
= put_values_s8
;
664 s8rb
->PutMonoValues
= put_mono_values_s8
;
672 ** The following functions are useful for hardware drivers that only
673 ** implement combined depth/stencil buffers.
674 ** The GL_EXT_framebuffer_object extension allows indepedent depth and
675 ** stencil buffers to be used in any combination.
676 ** Therefore, we sometimes have to merge separate depth and stencil
677 ** renderbuffers into a single depth+stencil renderbuffer. And sometimes
678 ** we have to split combined depth+stencil renderbuffers into separate
684 * Extract stencil values from the combined depth/stencil renderbuffer, storing
685 * the values into a separate stencil renderbuffer.
686 * \param dsRb the source depth/stencil renderbuffer
687 * \param stencilRb the destination stencil renderbuffer
688 * (either 8-bit or 32-bit)
691 _mesa_extract_stencil(GLcontext
*ctx
,
692 struct gl_renderbuffer
*dsRb
,
693 struct gl_renderbuffer
*stencilRb
)
695 GLuint row
, width
, height
;
700 ASSERT(dsRb
->Format
== MESA_FORMAT_Z24_S8
);
701 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
702 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
||
703 stencilRb
->Format
== MESA_FORMAT_S8
);
704 ASSERT(dsRb
->Width
== stencilRb
->Width
);
705 ASSERT(dsRb
->Height
== stencilRb
->Height
);
708 height
= dsRb
->Height
;
710 for (row
= 0; row
< height
; row
++) {
711 GLuint depthStencil
[MAX_WIDTH
];
712 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
713 if (stencilRb
->Format
== MESA_FORMAT_S8
) {
715 GLubyte stencil
[MAX_WIDTH
];
717 for (i
= 0; i
< width
; i
++) {
718 stencil
[i
] = depthStencil
[i
] & 0xff;
720 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, stencil
, NULL
);
724 /* the 24 depth bits will be ignored */
725 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
);
726 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
727 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, row
, depthStencil
, NULL
);
734 * Copy stencil values from a stencil renderbuffer into a combined
735 * depth/stencil renderbuffer.
736 * \param dsRb the destination depth/stencil renderbuffer
737 * \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
740 _mesa_insert_stencil(GLcontext
*ctx
,
741 struct gl_renderbuffer
*dsRb
,
742 struct gl_renderbuffer
*stencilRb
)
744 GLuint row
, width
, height
;
749 ASSERT(dsRb
->Format
== MESA_FORMAT_Z24_S8
);
750 ASSERT(dsRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
751 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
||
752 stencilRb
->Format
== MESA_FORMAT_S8
);
754 ASSERT(dsRb
->Width
== stencilRb
->Width
);
755 ASSERT(dsRb
->Height
== stencilRb
->Height
);
758 height
= dsRb
->Height
;
760 for (row
= 0; row
< height
; row
++) {
761 GLuint depthStencil
[MAX_WIDTH
];
763 dsRb
->GetRow(ctx
, dsRb
, width
, 0, row
, depthStencil
);
765 if (stencilRb
->Format
== MESA_FORMAT_S8
) {
767 GLubyte stencil
[MAX_WIDTH
];
769 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
770 for (i
= 0; i
< width
; i
++) {
771 depthStencil
[i
] = (depthStencil
[i
] & 0xffffff00) | stencil
[i
];
775 /* 32bpp stencil buffer */
776 GLuint stencil
[MAX_WIDTH
], i
;
777 ASSERT(stencilRb
->Format
== MESA_FORMAT_Z24_S8
);
778 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
779 stencilRb
->GetRow(ctx
, stencilRb
, width
, 0, row
, stencil
);
780 for (i
= 0; i
< width
; i
++) {
782 = (depthStencil
[i
] & 0xffffff00) | (stencil
[i
] & 0xff);
786 dsRb
->PutRow(ctx
, dsRb
, width
, 0, row
, depthStencil
, NULL
);
792 * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
793 * \param stencilRb the stencil renderbuffer to promote
796 _mesa_promote_stencil(GLcontext
*ctx
, struct gl_renderbuffer
*stencilRb
)
798 const GLsizei width
= stencilRb
->Width
;
799 const GLsizei height
= stencilRb
->Height
;
803 ASSERT(stencilRb
->Format
== MESA_FORMAT_S8
);
804 ASSERT(stencilRb
->Data
);
806 data
= (GLubyte
*) stencilRb
->Data
;
807 stencilRb
->Data
= NULL
;
808 stencilRb
->AllocStorage(ctx
, stencilRb
, GL_DEPTH24_STENCIL8_EXT
,
811 ASSERT(stencilRb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
814 for (i
= 0; i
< height
; i
++) {
815 GLuint depthStencil
[MAX_WIDTH
];
816 for (j
= 0; j
< width
; j
++) {
817 depthStencil
[j
] = data
[k
++];
819 stencilRb
->PutRow(ctx
, stencilRb
, width
, 0, i
, depthStencil
, NULL
);