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.
25 #include "main/glheader.h"
26 #include "main/imports.h"
27 #include "main/context.h"
28 #include "main/formats.h"
29 #include "main/mtypes.h"
30 #include "main/renderbuffer.h"
31 #include "swrast/s_depthstencil.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
);
212 put_values_z24(struct gl_context
*ctx
, struct gl_renderbuffer
*z24rb
, GLuint count
,
213 const GLint x
[], const GLint y
[],
214 const void *values
, const GLubyte
*mask
)
216 struct gl_renderbuffer
*dsrb
= z24rb
->Wrapped
;
217 const GLuint
*src
= (const GLuint
*) values
;
218 ASSERT(z24rb
->DataType
== GL_UNSIGNED_INT
);
219 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
220 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
223 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
224 for (i
= 0; i
< count
; i
++) {
225 if (!mask
|| mask
[i
]) {
226 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
227 *dst
= (src
[i
] << 8) | (*dst
& 0xff);
232 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
233 for (i
= 0; i
< count
; i
++) {
234 if (!mask
|| mask
[i
]) {
235 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
236 *dst
= (src
[i
] & 0xffffff) | (*dst
& 0xff000000);
242 /* get, modify, put */
243 GLuint temp
[MAX_WIDTH
], i
;
244 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
245 if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
246 for (i
= 0; i
< count
; i
++) {
247 if (!mask
|| mask
[i
]) {
248 temp
[i
] = (src
[i
] << 8) | (temp
[i
] & 0xff);
253 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
254 for (i
= 0; i
< count
; i
++) {
255 if (!mask
|| mask
[i
]) {
256 temp
[i
] = (src
[i
] & 0xffffff) | (temp
[i
] & 0xff000000);
260 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
266 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
267 * a depth renderbuffer.
268 * \return new depth renderbuffer
270 static struct gl_renderbuffer
*
271 new_z24_renderbuffer_wrapper(struct gl_context
*ctx
,
272 struct gl_renderbuffer
*dsrb
)
274 struct gl_renderbuffer
*z24rb
;
276 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
277 dsrb
->Format
== MESA_FORMAT_Z24_X8
||
278 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
279 dsrb
->Format
== MESA_FORMAT_X8_Z24
);
280 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
282 z24rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
286 /* NOTE: need to do manual refcounting here */
287 z24rb
->Wrapped
= dsrb
;
290 z24rb
->Name
= dsrb
->Name
;
292 z24rb
->Width
= dsrb
->Width
;
293 z24rb
->Height
= dsrb
->Height
;
294 z24rb
->RowStride
= dsrb
->RowStride
;
295 z24rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
296 z24rb
->Format
= MESA_FORMAT_X8_Z24
;
297 z24rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
298 z24rb
->DataType
= GL_UNSIGNED_INT
;
300 z24rb
->Delete
= delete_wrapper
;
301 z24rb
->AllocStorage
= alloc_wrapper_storage
;
302 z24rb
->GetPointer
= nop_get_pointer
;
303 z24rb
->GetRow
= get_row_z24
;
304 z24rb
->GetValues
= get_values_z24
;
305 z24rb
->PutRow
= put_row_z24
;
306 z24rb
->PutValues
= put_values_z24
;
313 get_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
314 GLint x
, GLint y
, void *values
)
316 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
317 GLfloat temp
[MAX_WIDTH
*2];
318 GLfloat
*dst
= (GLfloat
*) values
;
319 const GLfloat
*src
= (const GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
321 ASSERT(z32frb
->DataType
== GL_FLOAT
);
322 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
323 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
325 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
328 for (i
= 0; i
< count
; i
++) {
334 get_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
335 const GLint x
[], const GLint y
[], void *values
)
337 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
338 GLfloat temp
[MAX_WIDTH
*2];
339 GLfloat
*dst
= (GLfloat
*) values
;
341 ASSERT(z32frb
->DataType
== GL_FLOAT
);
342 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
343 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
344 ASSERT(count
<= MAX_WIDTH
);
345 /* don't bother trying direct access */
346 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
347 for (i
= 0; i
< count
; i
++) {
353 put_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
354 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
356 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
357 const GLfloat
*src
= (const GLfloat
*) values
;
358 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
359 ASSERT(z32frb
->DataType
== GL_FLOAT
);
360 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
361 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
365 for (i
= 0; i
< count
; i
++) {
366 if (!mask
|| mask
[i
]) {
372 /* get, modify, put */
373 GLfloat temp
[MAX_WIDTH
*2];
375 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
376 for (i
= 0; i
< count
; i
++) {
377 if (!mask
|| mask
[i
]) {
381 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
387 put_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
388 const GLint x
[], const GLint y
[],
389 const void *values
, const GLubyte
*mask
)
391 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
392 const GLfloat
*src
= (const GLfloat
*) values
;
393 ASSERT(z32frb
->DataType
== GL_FLOAT
);
394 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
395 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
396 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
399 for (i
= 0; i
< count
; i
++) {
400 if (!mask
|| mask
[i
]) {
401 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
407 /* get, modify, put */
408 GLfloat temp
[MAX_WIDTH
*2];
410 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
411 for (i
= 0; i
< count
; i
++) {
412 if (!mask
|| mask
[i
]) {
416 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
422 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
423 * a depth renderbuffer.
424 * \return new depth renderbuffer
426 static struct gl_renderbuffer
*
427 new_z32f_renderbuffer_wrapper(struct gl_context
*ctx
,
428 struct gl_renderbuffer
*dsrb
)
430 struct gl_renderbuffer
*z32frb
;
432 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
433 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
435 z32frb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
439 /* NOTE: need to do manual refcounting here */
440 z32frb
->Wrapped
= dsrb
;
443 z32frb
->Name
= dsrb
->Name
;
444 z32frb
->RefCount
= 0;
445 z32frb
->Width
= dsrb
->Width
;
446 z32frb
->Height
= dsrb
->Height
;
447 z32frb
->RowStride
= dsrb
->RowStride
;
448 z32frb
->InternalFormat
= GL_DEPTH_COMPONENT32F
;
449 z32frb
->Format
= MESA_FORMAT_Z32_FLOAT
;
450 z32frb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
451 z32frb
->DataType
= GL_FLOAT
;
453 z32frb
->Delete
= delete_wrapper
;
454 z32frb
->AllocStorage
= alloc_wrapper_storage
;
455 z32frb
->GetPointer
= nop_get_pointer
;
456 z32frb
->GetRow
= get_row_z32f
;
457 z32frb
->GetValues
= get_values_z32f
;
458 z32frb
->PutRow
= put_row_z32f
;
459 z32frb
->PutValues
= put_values_z32f
;
465 /*======================================================================
466 * Stencil wrapper around depth/stencil renderbuffer
470 get_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
471 GLint x
, GLint y
, void *values
)
473 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
474 GLuint temp
[MAX_WIDTH
*2], i
;
475 GLubyte
*dst
= (GLubyte
*) values
;
476 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
477 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
478 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
479 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
481 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
484 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
485 for (i
= 0; i
< count
; i
++) {
486 dst
[i
] = src
[i
*2+1] & 0xff;
489 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
490 for (i
= 0; i
< count
; i
++) {
491 dst
[i
] = src
[i
] & 0xff;
495 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
496 for (i
= 0; i
< count
; i
++) {
497 dst
[i
] = src
[i
] >> 24;
503 get_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
504 const GLint x
[], const GLint y
[], void *values
)
506 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
507 GLuint temp
[MAX_WIDTH
*2], i
;
508 GLubyte
*dst
= (GLubyte
*) values
;
509 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
510 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
511 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
512 ASSERT(count
<= MAX_WIDTH
);
513 /* don't bother trying direct access */
514 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
515 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
516 for (i
= 0; i
< count
; i
++) {
517 dst
[i
] = temp
[i
*2+1] & 0xff;
520 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
521 for (i
= 0; i
< count
; i
++) {
522 dst
[i
] = temp
[i
] & 0xff;
526 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
527 for (i
= 0; i
< count
; i
++) {
528 dst
[i
] = temp
[i
] >> 24;
534 put_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
535 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
537 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
538 const GLubyte
*src
= (const GLubyte
*) values
;
539 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
540 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
541 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
542 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
546 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
547 for (i
= 0; i
< count
; i
++) {
548 if (!mask
|| mask
[i
]) {
553 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
554 for (i
= 0; i
< count
; i
++) {
555 if (!mask
|| mask
[i
]) {
556 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
561 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
562 for (i
= 0; i
< count
; i
++) {
563 if (!mask
|| mask
[i
]) {
564 dst
[i
] = (dst
[i
] & 0xffffff) | (src
[i
] << 24);
570 /* get, modify, put */
571 GLuint temp
[MAX_WIDTH
*2], i
;
572 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
573 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
574 for (i
= 0; i
< count
; i
++) {
575 if (!mask
|| mask
[i
]) {
576 temp
[i
*2+1] = src
[i
];
580 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
581 for (i
= 0; i
< count
; i
++) {
582 if (!mask
|| mask
[i
]) {
583 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
588 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
589 for (i
= 0; i
< count
; i
++) {
590 if (!mask
|| mask
[i
]) {
591 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
595 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
601 put_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
602 const GLint x
[], const GLint y
[],
603 const void *values
, const GLubyte
*mask
)
605 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
606 const GLubyte
*src
= (const GLubyte
*) values
;
607 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
608 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
609 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
610 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
613 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
614 for (i
= 0; i
< count
; i
++) {
615 if (!mask
|| mask
[i
]) {
616 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
621 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
622 for (i
= 0; i
< count
; i
++) {
623 if (!mask
|| mask
[i
]) {
624 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
625 *dst
= (*dst
& 0xffffff00) | src
[i
];
630 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
631 for (i
= 0; i
< count
; i
++) {
632 if (!mask
|| mask
[i
]) {
633 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
634 *dst
= (*dst
& 0xffffff) | (src
[i
] << 24);
640 /* get, modify, put */
641 GLuint temp
[MAX_WIDTH
*2], i
;
642 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
643 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
644 for (i
= 0; i
< count
; i
++) {
645 if (!mask
|| mask
[i
]) {
646 temp
[i
*2+1] = src
[i
];
650 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
651 for (i
= 0; i
< count
; i
++) {
652 if (!mask
|| mask
[i
]) {
653 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
658 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
659 for (i
= 0; i
< count
; i
++) {
660 if (!mask
|| mask
[i
]) {
661 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
665 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
671 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
672 * a stencil renderbuffer.
673 * \return new stencil renderbuffer
675 static struct gl_renderbuffer
*
676 new_s8_renderbuffer_wrapper(struct gl_context
*ctx
, struct gl_renderbuffer
*dsrb
)
678 struct gl_renderbuffer
*s8rb
;
680 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
681 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
682 dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
683 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
684 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
686 s8rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
690 /* NOTE: need to do manual refcounting here */
691 s8rb
->Wrapped
= dsrb
;
694 s8rb
->Name
= dsrb
->Name
;
696 s8rb
->Width
= dsrb
->Width
;
697 s8rb
->Height
= dsrb
->Height
;
698 s8rb
->RowStride
= dsrb
->RowStride
;
699 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
700 s8rb
->Format
= MESA_FORMAT_S8
;
701 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
702 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
704 s8rb
->Delete
= delete_wrapper
;
705 s8rb
->AllocStorage
= alloc_wrapper_storage
;
706 s8rb
->GetPointer
= nop_get_pointer
;
707 s8rb
->GetRow
= get_row_s8
;
708 s8rb
->GetValues
= get_values_s8
;
709 s8rb
->PutRow
= put_row_s8
;
710 s8rb
->PutValues
= put_values_s8
;
717 * Update the framebuffer's _DepthBuffer field using the renderbuffer
718 * found at the given attachment index.
720 * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
721 * create and install a depth wrapper/adaptor.
723 * \param fb the framebuffer whose _DepthBuffer field to update
726 _swrast_update_depth_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
728 struct gl_renderbuffer
*depthRb
=
729 fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
731 if (depthRb
&& _mesa_is_format_packed_depth_stencil(depthRb
->Format
)) {
732 /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
733 if (!fb
->_DepthBuffer
734 || fb
->_DepthBuffer
->Wrapped
!= depthRb
735 || _mesa_get_format_base_format(fb
->_DepthBuffer
->Format
) != GL_DEPTH_COMPONENT
) {
736 /* need to update wrapper */
737 struct gl_renderbuffer
*wrapper
;
739 if (depthRb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
740 wrapper
= new_z32f_renderbuffer_wrapper(ctx
, depthRb
);
743 wrapper
= new_z24_renderbuffer_wrapper(ctx
, depthRb
);
745 _mesa_reference_renderbuffer(&fb
->_DepthBuffer
, wrapper
);
747 ASSERT(fb
->_DepthBuffer
->Wrapped
== depthRb
);
748 fb
->_DepthBuffer
->Width
= depthRb
->Width
;
749 fb
->_DepthBuffer
->Height
= depthRb
->Height
;
752 /* depthRb may be null */
753 _mesa_reference_renderbuffer(&fb
->_DepthBuffer
, depthRb
);
759 * Update the framebuffer's _StencilBuffer field using the renderbuffer
760 * found at the given attachment index.
762 * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
763 * create and install a stencil wrapper/adaptor.
765 * \param fb the framebuffer whose _StencilBuffer field to update
768 _swrast_update_stencil_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
770 struct gl_renderbuffer
*stencilRb
=
771 fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
773 if (stencilRb
&& _mesa_is_format_packed_depth_stencil(stencilRb
->Format
)) {
774 /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
775 if (!fb
->_StencilBuffer
776 || fb
->_StencilBuffer
->Wrapped
!= stencilRb
777 || _mesa_get_format_base_format(fb
->_StencilBuffer
->Format
) != GL_STENCIL_INDEX
) {
778 /* need to update wrapper */
779 struct gl_renderbuffer
*wrapper
780 = new_s8_renderbuffer_wrapper(ctx
, stencilRb
);
781 _mesa_reference_renderbuffer(&fb
->_StencilBuffer
, wrapper
);
783 ASSERT(fb
->_StencilBuffer
->Wrapped
== stencilRb
);
784 fb
->_StencilBuffer
->Width
= stencilRb
->Width
;
785 fb
->_StencilBuffer
->Height
= stencilRb
->Height
;
788 /* stencilRb may be null */
789 _mesa_reference_renderbuffer(&fb
->_StencilBuffer
, stencilRb
);