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 rb
->Format
== MESA_FORMAT_Z32_FLOAT
);
68 _mesa_reference_renderbuffer(&rb
->Wrapped
, NULL
);
74 * Realloc storage for wrapper.
77 alloc_wrapper_storage(struct gl_context
*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_Z24_X8
||
88 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
89 dsrb
->Format
== MESA_FORMAT_X8_Z24
);
91 retVal
= dsrb
->AllocStorage(ctx
, dsrb
, dsrb
->InternalFormat
, width
, height
);
95 rb
->RowStride
= dsrb
->RowStride
;
103 /*======================================================================
104 * Depth wrapper around depth/stencil renderbuffer
108 get_row_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
109 GLint x
, GLint y
, void *values
)
111 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
112 GLuint temp
[MAX_WIDTH
], i
;
113 GLuint
*dst
= (GLuint
*) values
;
114 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
115 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
116 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
118 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
121 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
122 for (i
= 0; i
< count
; i
++) {
123 dst
[i
] = src
[i
] >> 8;
127 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
128 for (i
= 0; i
< count
; i
++) {
129 dst
[i
] = src
[i
] & 0xffffff;
135 get_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
136 const GLint x
[], const GLint y
[], void *values
)
138 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
139 GLuint temp
[MAX_WIDTH
], i
;
140 GLuint
*dst
= (GLuint
*) values
;
141 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
142 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
143 ASSERT(count
<= MAX_WIDTH
);
144 /* don't bother trying direct access */
145 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
146 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
147 for (i
= 0; i
< count
; i
++) {
148 dst
[i
] = temp
[i
] >> 8;
152 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
153 for (i
= 0; i
< count
; i
++) {
154 dst
[i
] = temp
[i
] & 0xffffff;
160 put_row_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
161 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
163 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
164 const GLuint
*src
= (const GLuint
*) values
;
165 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
166 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
167 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
171 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
172 for (i
= 0; i
< count
; i
++) {
173 if (!mask
|| mask
[i
]) {
174 dst
[i
] = (src
[i
] << 8) | (dst
[i
] & 0xff);
179 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
180 for (i
= 0; i
< count
; i
++) {
181 if (!mask
|| mask
[i
]) {
182 dst
[i
] = (src
[i
] & 0xffffff) | (dst
[i
] & 0xff000000);
188 /* get, modify, put */
189 GLuint temp
[MAX_WIDTH
], i
;
190 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
191 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
192 for (i
= 0; i
< count
; i
++) {
193 if (!mask
|| mask
[i
]) {
194 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
199 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
200 for (i
= 0; i
< count
; i
++) {
201 if (!mask
|| mask
[i
]) {
202 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
206 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
211 put_mono_row_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
212 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
214 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
215 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
216 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
217 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
221 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
222 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
223 for (i
= 0; i
< count
; i
++) {
224 if (!mask
|| mask
[i
]) {
225 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff);
230 const GLuint shiftedVal
= *((GLuint
*) value
);
231 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
232 for (i
= 0; i
< count
; i
++) {
233 if (!mask
|| mask
[i
]) {
234 dst
[i
] = shiftedVal
| (dst
[i
] & 0xff000000);
240 /* get, modify, put */
241 GLuint temp
[MAX_WIDTH
], i
;
242 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
243 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
244 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
245 for (i
= 0; i
< count
; i
++) {
246 if (!mask
|| mask
[i
]) {
247 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
252 const GLuint shiftedVal
= *((GLuint
*) value
);
253 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
254 for (i
= 0; i
< count
; i
++) {
255 if (!mask
|| mask
[i
]) {
256 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
260 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
265 put_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
266 const GLint x
[], const GLint y
[],
267 const void *values
, const GLubyte
*mask
)
269 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
270 const GLuint
*src
= (const GLuint
*) values
;
271 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
272 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
273 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
276 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
277 for (i
= 0; i
< count
; i
++) {
278 if (!mask
|| mask
[i
]) {
279 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
280 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
285 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
286 for (i
= 0; i
< count
; i
++) {
287 if (!mask
|| mask
[i
]) {
288 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
289 *dst
= (src
[i
] & 0xffffff) | (*dst
& 0xff000000);
295 /* get, modify, put */
296 GLuint temp
[MAX_WIDTH
], i
;
297 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
298 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
299 for (i
= 0; i
< count
; i
++) {
300 if (!mask
|| mask
[i
]) {
301 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
306 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
307 for (i
= 0; i
< count
; i
++) {
308 if (!mask
|| mask
[i
]) {
309 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
313 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
318 put_mono_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
,
319 GLuint count
, const GLint x
[], const GLint y
[],
320 const void *value
, const GLubyte
*mask
)
322 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
323 GLuint temp
[MAX_WIDTH
], i
;
324 /* get, modify, put */
325 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
326 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
327 const GLuint shiftedVal
= *((GLuint
*) value
) << 8;
328 for (i
= 0; i
< count
; i
++) {
329 if (!mask
|| mask
[i
]) {
330 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff);
335 const GLuint shiftedVal
= *((GLuint
*) value
);
336 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
337 for (i
= 0; i
< count
; i
++) {
338 if (!mask
|| mask
[i
]) {
339 temp
[i
] = shiftedVal
| (temp
[i
] & 0xff000000);
343 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
348 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
349 * a depth renderbuffer.
350 * \return new depth renderbuffer
352 static struct gl_renderbuffer
*
353 new_z24_renderbuffer_wrapper(struct gl_context
*ctx
,
354 struct gl_renderbuffer
*dsrb
)
356 struct gl_renderbuffer
*z24rb
;
358 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
359 dsrb
->Format
== MESA_FORMAT_Z24_X8
||
360 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
361 dsrb
->Format
== MESA_FORMAT_X8_Z24
);
362 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
364 z24rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
368 /* NOTE: need to do manual refcounting here */
369 z24rb
->Wrapped
= dsrb
;
372 z24rb
->Name
= dsrb
->Name
;
374 z24rb
->Width
= dsrb
->Width
;
375 z24rb
->Height
= dsrb
->Height
;
376 z24rb
->RowStride
= dsrb
->RowStride
;
377 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
378 z24rb
->Format
= MESA_FORMAT_X8_Z24
;
379 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
380 z24rb
->DataType
= GL_UNSIGNED_INT
;
382 z24rb
->Delete
= delete_wrapper
;
383 z24rb
->AllocStorage
= alloc_wrapper_storage
;
384 z24rb
->GetPointer
= nop_get_pointer
;
385 z24rb
->GetRow
= get_row_z24
;
386 z24rb
->GetValues
= get_values_z24
;
387 z24rb
->PutRow
= put_row_z24
;
388 z24rb
->PutRowRGB
= NULL
;
389 z24rb
->PutMonoRow
= put_mono_row_z24
;
390 z24rb
->PutValues
= put_values_z24
;
391 z24rb
->PutMonoValues
= put_mono_values_z24
;
398 get_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
399 GLint x
, GLint y
, void *values
)
401 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
402 GLfloat temp
[MAX_WIDTH
*2];
403 GLfloat
*dst
= (GLfloat
*) values
;
404 const GLfloat
*src
= (const GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
406 ASSERT(z32frb
->DataType
== GL_FLOAT
);
407 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
408 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
410 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
413 for (i
= 0; i
< count
; i
++) {
419 get_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
420 const GLint x
[], const GLint y
[], void *values
)
422 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
423 GLfloat temp
[MAX_WIDTH
*2];
424 GLfloat
*dst
= (GLfloat
*) values
;
426 ASSERT(z32frb
->DataType
== GL_FLOAT
);
427 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
428 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
429 ASSERT(count
<= MAX_WIDTH
);
430 /* don't bother trying direct access */
431 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
432 for (i
= 0; i
< count
; i
++) {
438 put_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
439 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
441 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
442 const GLfloat
*src
= (const GLfloat
*) values
;
443 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
444 ASSERT(z32frb
->DataType
== GL_FLOAT
);
445 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
446 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
450 for (i
= 0; i
< count
; i
++) {
451 if (!mask
|| mask
[i
]) {
457 /* get, modify, put */
458 GLfloat temp
[MAX_WIDTH
*2];
460 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
461 for (i
= 0; i
< count
; i
++) {
462 if (!mask
|| mask
[i
]) {
466 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
471 put_mono_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
472 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
474 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
475 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
476 ASSERT(z32frb
->DataType
== GL_FLOAT
);
477 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
478 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
482 const GLfloat val
= *(GLfloat
*)value
;
483 for (i
= 0; i
< count
; i
++) {
484 if (!mask
|| mask
[i
]) {
490 /* get, modify, put */
491 GLfloat temp
[MAX_WIDTH
*2];
493 const GLfloat val
= *(GLfloat
*)value
;
494 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
495 for (i
= 0; i
< count
; i
++) {
496 if (!mask
|| mask
[i
]) {
500 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
505 put_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
506 const GLint x
[], const GLint y
[],
507 const void *values
, const GLubyte
*mask
)
509 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
510 const GLfloat
*src
= (const GLfloat
*) values
;
511 ASSERT(z32frb
->DataType
== GL_FLOAT
);
512 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
513 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
514 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
517 for (i
= 0; i
< count
; i
++) {
518 if (!mask
|| mask
[i
]) {
519 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
525 /* get, modify, put */
526 GLfloat temp
[MAX_WIDTH
*2];
528 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
529 for (i
= 0; i
< count
; i
++) {
530 if (!mask
|| mask
[i
]) {
534 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
539 put_mono_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
,
540 GLuint count
, const GLint x
[], const GLint y
[],
541 const void *value
, const GLubyte
*mask
)
543 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
544 GLfloat temp
[MAX_WIDTH
*2];
546 const GLfloat val
= *(GLfloat
*)value
;
547 ASSERT(z32frb
->DataType
== GL_FLOAT
);
548 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
549 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
550 /* get, modify, put */
551 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
552 for (i
= 0; i
< count
; i
++) {
553 if (!mask
|| mask
[i
]) {
557 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
562 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
563 * a depth renderbuffer.
564 * \return new depth renderbuffer
566 static struct gl_renderbuffer
*
567 new_z32f_renderbuffer_wrapper(struct gl_context
*ctx
,
568 struct gl_renderbuffer
*dsrb
)
570 struct gl_renderbuffer
*z32frb
;
572 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
573 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
575 z32frb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
579 /* NOTE: need to do manual refcounting here */
580 z32frb
->Wrapped
= dsrb
;
583 z32frb
->Name
= dsrb
->Name
;
584 z32frb
->RefCount
= 0;
585 z32frb
->Width
= dsrb
->Width
;
586 z32frb
->Height
= dsrb
->Height
;
587 z32frb
->RowStride
= dsrb
->RowStride
;
588 z32frb
->InternalFormat
= GL_DEPTH_COMPONENT32F
;
589 z32frb
->Format
= MESA_FORMAT_Z32_FLOAT
;
590 z32frb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
591 z32frb
->DataType
= GL_FLOAT
;
593 z32frb
->Delete
= delete_wrapper
;
594 z32frb
->AllocStorage
= alloc_wrapper_storage
;
595 z32frb
->GetPointer
= nop_get_pointer
;
596 z32frb
->GetRow
= get_row_z32f
;
597 z32frb
->GetValues
= get_values_z32f
;
598 z32frb
->PutRow
= put_row_z32f
;
599 z32frb
->PutRowRGB
= NULL
;
600 z32frb
->PutMonoRow
= put_mono_row_z32f
;
601 z32frb
->PutValues
= put_values_z32f
;
602 z32frb
->PutMonoValues
= put_mono_values_z32f
;
608 /*======================================================================
609 * Stencil wrapper around depth/stencil renderbuffer
613 get_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
614 GLint x
, GLint y
, void *values
)
616 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
617 GLuint temp
[MAX_WIDTH
*2], i
;
618 GLubyte
*dst
= (GLubyte
*) values
;
619 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
620 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
621 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
622 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
624 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
627 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
628 for (i
= 0; i
< count
; i
++) {
629 dst
[i
] = src
[i
*2+1] & 0xff;
632 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
633 for (i
= 0; i
< count
; i
++) {
634 dst
[i
] = src
[i
] & 0xff;
638 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
639 for (i
= 0; i
< count
; i
++) {
640 dst
[i
] = src
[i
] >> 24;
646 get_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
647 const GLint x
[], const GLint y
[], void *values
)
649 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
650 GLuint temp
[MAX_WIDTH
*2], i
;
651 GLubyte
*dst
= (GLubyte
*) values
;
652 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
653 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
654 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
655 ASSERT(count
<= MAX_WIDTH
);
656 /* don't bother trying direct access */
657 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
658 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
659 for (i
= 0; i
< count
; i
++) {
660 dst
[i
] = temp
[i
*2+1] & 0xff;
663 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
664 for (i
= 0; i
< count
; i
++) {
665 dst
[i
] = temp
[i
] & 0xff;
669 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
670 for (i
= 0; i
< count
; i
++) {
671 dst
[i
] = temp
[i
] >> 24;
677 put_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
678 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
680 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
681 const GLubyte
*src
= (const GLubyte
*) values
;
682 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
683 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
684 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
685 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
689 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
690 for (i
= 0; i
< count
; i
++) {
691 if (!mask
|| mask
[i
]) {
696 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
697 for (i
= 0; i
< count
; i
++) {
698 if (!mask
|| mask
[i
]) {
699 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
704 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
705 for (i
= 0; i
< count
; i
++) {
706 if (!mask
|| mask
[i
]) {
707 dst
[i
] = (dst
[i
] & 0xffffff) | (src
[i
] << 24);
713 /* get, modify, put */
714 GLuint temp
[MAX_WIDTH
*2], i
;
715 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
716 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
717 for (i
= 0; i
< count
; i
++) {
718 if (!mask
|| mask
[i
]) {
719 temp
[i
*2+1] = src
[i
];
723 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
724 for (i
= 0; i
< count
; i
++) {
725 if (!mask
|| mask
[i
]) {
726 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
731 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
732 for (i
= 0; i
< count
; i
++) {
733 if (!mask
|| mask
[i
]) {
734 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
738 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
743 put_mono_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
744 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
746 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
747 const GLubyte val
= *((GLubyte
*) value
);
748 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
749 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
750 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
751 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
755 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
756 for (i
= 0; i
< count
; i
++) {
757 if (!mask
|| mask
[i
]) {
762 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
763 for (i
= 0; i
< count
; i
++) {
764 if (!mask
|| mask
[i
]) {
765 dst
[i
] = (dst
[i
] & 0xffffff00) | val
;
770 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
771 for (i
= 0; i
< count
; i
++) {
772 if (!mask
|| mask
[i
]) {
773 dst
[i
] = (dst
[i
] & 0xffffff) | (val
<< 24);
779 /* get, modify, put */
780 GLuint temp
[MAX_WIDTH
*2], i
;
781 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
782 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
783 for (i
= 0; i
< count
; i
++) {
784 if (!mask
|| mask
[i
]) {
789 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
790 for (i
= 0; i
< count
; i
++) {
791 if (!mask
|| mask
[i
]) {
792 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
797 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
798 for (i
= 0; i
< count
; i
++) {
799 if (!mask
|| mask
[i
]) {
800 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
804 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
809 put_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
810 const GLint x
[], const GLint y
[],
811 const void *values
, const GLubyte
*mask
)
813 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
814 const GLubyte
*src
= (const GLubyte
*) values
;
815 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
816 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
817 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
818 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
821 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
822 for (i
= 0; i
< count
; i
++) {
823 if (!mask
|| mask
[i
]) {
824 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
829 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
830 for (i
= 0; i
< count
; i
++) {
831 if (!mask
|| mask
[i
]) {
832 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
833 *dst
= (*dst
& 0xffffff00) | src
[i
];
838 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
839 for (i
= 0; i
< count
; i
++) {
840 if (!mask
|| mask
[i
]) {
841 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
842 *dst
= (*dst
& 0xffffff) | (src
[i
] << 24);
848 /* get, modify, put */
849 GLuint temp
[MAX_WIDTH
*2], i
;
850 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
851 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
852 for (i
= 0; i
< count
; i
++) {
853 if (!mask
|| mask
[i
]) {
854 temp
[i
*2+1] = src
[i
];
858 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
859 for (i
= 0; i
< count
; i
++) {
860 if (!mask
|| mask
[i
]) {
861 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
866 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
867 for (i
= 0; i
< count
; i
++) {
868 if (!mask
|| mask
[i
]) {
869 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
873 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
878 put_mono_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
879 const GLint x
[], const GLint y
[],
880 const void *value
, const GLubyte
*mask
)
882 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
883 GLuint temp
[MAX_WIDTH
*2], i
;
884 const GLubyte val
= *((GLubyte
*) value
);
885 /* get, modify, put */
886 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
887 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
888 for (i
= 0; i
< count
; i
++) {
889 if (!mask
|| mask
[i
]) {
894 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
895 for (i
= 0; i
< count
; i
++) {
896 if (!mask
|| mask
[i
]) {
897 temp
[i
] = (temp
[i
] & 0xffffff00) | val
;
902 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
903 for (i
= 0; i
< count
; i
++) {
904 if (!mask
|| mask
[i
]) {
905 temp
[i
] = (temp
[i
] & 0xffffff) | (val
<< 24);
909 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
914 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
915 * a stencil renderbuffer.
916 * \return new stencil renderbuffer
918 static struct gl_renderbuffer
*
919 new_s8_renderbuffer_wrapper(struct gl_context
*ctx
, struct gl_renderbuffer
*dsrb
)
921 struct gl_renderbuffer
*s8rb
;
923 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
924 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
925 dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
926 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
927 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
929 s8rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
933 /* NOTE: need to do manual refcounting here */
934 s8rb
->Wrapped
= dsrb
;
937 s8rb
->Name
= dsrb
->Name
;
939 s8rb
->Width
= dsrb
->Width
;
940 s8rb
->Height
= dsrb
->Height
;
941 s8rb
->RowStride
= dsrb
->RowStride
;
942 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
943 s8rb
->Format
= MESA_FORMAT_S8
;
944 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
945 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
947 s8rb
->Delete
= delete_wrapper
;
948 s8rb
->AllocStorage
= alloc_wrapper_storage
;
949 s8rb
->GetPointer
= nop_get_pointer
;
950 s8rb
->GetRow
= get_row_s8
;
951 s8rb
->GetValues
= get_values_s8
;
952 s8rb
->PutRow
= put_row_s8
;
953 s8rb
->PutRowRGB
= NULL
;
954 s8rb
->PutMonoRow
= put_mono_row_s8
;
955 s8rb
->PutValues
= put_values_s8
;
956 s8rb
->PutMonoValues
= put_mono_values_s8
;
963 * Update the framebuffer's _DepthBuffer field using the renderbuffer
964 * found at the given attachment index.
966 * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
967 * create and install a depth wrapper/adaptor.
969 * \param fb the framebuffer whose _DepthBuffer field to update
972 _mesa_update_depth_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
974 struct gl_renderbuffer
*depthRb
=
975 fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
977 if (depthRb
&& _mesa_is_format_packed_depth_stencil(depthRb
->Format
)) {
978 /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
979 if (!fb
->_DepthBuffer
980 || fb
->_DepthBuffer
->Wrapped
!= depthRb
981 || _mesa_get_format_base_format(fb
->_DepthBuffer
->Format
) != GL_DEPTH_COMPONENT
) {
982 /* need to update wrapper */
983 struct gl_renderbuffer
*wrapper
;
985 if (depthRb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
986 wrapper
= new_z32f_renderbuffer_wrapper(ctx
, depthRb
);
989 wrapper
= new_z24_renderbuffer_wrapper(ctx
, depthRb
);
991 _mesa_reference_renderbuffer(&fb
->_DepthBuffer
, wrapper
);
992 ASSERT(fb
->_DepthBuffer
->Wrapped
== depthRb
);
996 /* depthRb may be null */
997 _mesa_reference_renderbuffer(&fb
->_DepthBuffer
, depthRb
);
1003 * Update the framebuffer's _StencilBuffer field using the renderbuffer
1004 * found at the given attachment index.
1006 * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
1007 * create and install a stencil wrapper/adaptor.
1009 * \param fb the framebuffer whose _StencilBuffer field to update
1012 _mesa_update_stencil_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
1014 struct gl_renderbuffer
*stencilRb
=
1015 fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
1017 if (stencilRb
&& _mesa_is_format_packed_depth_stencil(stencilRb
->Format
)) {
1018 /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
1019 if (!fb
->_StencilBuffer
1020 || fb
->_StencilBuffer
->Wrapped
!= stencilRb
1021 || _mesa_get_format_base_format(fb
->_StencilBuffer
->Format
) != GL_STENCIL_INDEX
) {
1022 /* need to update wrapper */
1023 struct gl_renderbuffer
*wrapper
1024 = new_s8_renderbuffer_wrapper(ctx
, stencilRb
);
1025 _mesa_reference_renderbuffer(&fb
->_StencilBuffer
, wrapper
);
1026 ASSERT(fb
->_StencilBuffer
->Wrapped
== stencilRb
);
1030 /* stencilRb may be null */
1031 _mesa_reference_renderbuffer(&fb
->_StencilBuffer
, stencilRb
);