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
->PutRowRGB
= NULL
;
307 z24rb
->PutValues
= put_values_z24
;
314 get_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
315 GLint x
, GLint y
, void *values
)
317 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
318 GLfloat temp
[MAX_WIDTH
*2];
319 GLfloat
*dst
= (GLfloat
*) values
;
320 const GLfloat
*src
= (const GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
322 ASSERT(z32frb
->DataType
== GL_FLOAT
);
323 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
324 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
326 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
329 for (i
= 0; i
< count
; i
++) {
335 get_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
336 const GLint x
[], const GLint y
[], void *values
)
338 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
339 GLfloat temp
[MAX_WIDTH
*2];
340 GLfloat
*dst
= (GLfloat
*) values
;
342 ASSERT(z32frb
->DataType
== GL_FLOAT
);
343 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
344 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
345 ASSERT(count
<= MAX_WIDTH
);
346 /* don't bother trying direct access */
347 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
348 for (i
= 0; i
< count
; i
++) {
354 put_row_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
355 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
357 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
358 const GLfloat
*src
= (const GLfloat
*) values
;
359 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
360 ASSERT(z32frb
->DataType
== GL_FLOAT
);
361 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
362 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
366 for (i
= 0; i
< count
; i
++) {
367 if (!mask
|| mask
[i
]) {
373 /* get, modify, put */
374 GLfloat temp
[MAX_WIDTH
*2];
376 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
377 for (i
= 0; i
< count
; i
++) {
378 if (!mask
|| mask
[i
]) {
382 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
388 put_values_z32f(struct gl_context
*ctx
, struct gl_renderbuffer
*z32frb
, GLuint count
,
389 const GLint x
[], const GLint y
[],
390 const void *values
, const GLubyte
*mask
)
392 struct gl_renderbuffer
*dsrb
= z32frb
->Wrapped
;
393 const GLfloat
*src
= (const GLfloat
*) values
;
394 ASSERT(z32frb
->DataType
== GL_FLOAT
);
395 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
396 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
397 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
400 for (i
= 0; i
< count
; i
++) {
401 if (!mask
|| mask
[i
]) {
402 GLfloat
*dst
= (GLfloat
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
408 /* get, modify, put */
409 GLfloat temp
[MAX_WIDTH
*2];
411 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
412 for (i
= 0; i
< count
; i
++) {
413 if (!mask
|| mask
[i
]) {
417 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
423 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
424 * a depth renderbuffer.
425 * \return new depth renderbuffer
427 static struct gl_renderbuffer
*
428 new_z32f_renderbuffer_wrapper(struct gl_context
*ctx
,
429 struct gl_renderbuffer
*dsrb
)
431 struct gl_renderbuffer
*z32frb
;
433 ASSERT(dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
434 ASSERT(dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
436 z32frb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
440 /* NOTE: need to do manual refcounting here */
441 z32frb
->Wrapped
= dsrb
;
444 z32frb
->Name
= dsrb
->Name
;
445 z32frb
->RefCount
= 0;
446 z32frb
->Width
= dsrb
->Width
;
447 z32frb
->Height
= dsrb
->Height
;
448 z32frb
->RowStride
= dsrb
->RowStride
;
449 z32frb
->InternalFormat
= GL_DEPTH_COMPONENT32F
;
450 z32frb
->Format
= MESA_FORMAT_Z32_FLOAT
;
451 z32frb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
452 z32frb
->DataType
= GL_FLOAT
;
454 z32frb
->Delete
= delete_wrapper
;
455 z32frb
->AllocStorage
= alloc_wrapper_storage
;
456 z32frb
->GetPointer
= nop_get_pointer
;
457 z32frb
->GetRow
= get_row_z32f
;
458 z32frb
->GetValues
= get_values_z32f
;
459 z32frb
->PutRow
= put_row_z32f
;
460 z32frb
->PutRowRGB
= NULL
;
461 z32frb
->PutValues
= put_values_z32f
;
467 /*======================================================================
468 * Stencil wrapper around depth/stencil renderbuffer
472 get_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
473 GLint x
, GLint y
, void *values
)
475 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
476 GLuint temp
[MAX_WIDTH
*2], i
;
477 GLubyte
*dst
= (GLubyte
*) values
;
478 const GLuint
*src
= (const GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
479 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
480 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
481 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
483 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
486 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
487 for (i
= 0; i
< count
; i
++) {
488 dst
[i
] = src
[i
*2+1] & 0xff;
491 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
492 for (i
= 0; i
< count
; i
++) {
493 dst
[i
] = src
[i
] & 0xff;
497 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
498 for (i
= 0; i
< count
; i
++) {
499 dst
[i
] = src
[i
] >> 24;
505 get_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
506 const GLint x
[], const GLint y
[], void *values
)
508 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
509 GLuint temp
[MAX_WIDTH
*2], i
;
510 GLubyte
*dst
= (GLubyte
*) values
;
511 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
512 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
513 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
514 ASSERT(count
<= MAX_WIDTH
);
515 /* don't bother trying direct access */
516 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
517 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
518 for (i
= 0; i
< count
; i
++) {
519 dst
[i
] = temp
[i
*2+1] & 0xff;
522 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
523 for (i
= 0; i
< count
; i
++) {
524 dst
[i
] = temp
[i
] & 0xff;
528 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
529 for (i
= 0; i
< count
; i
++) {
530 dst
[i
] = temp
[i
] >> 24;
536 put_row_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
537 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
539 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
540 const GLubyte
*src
= (const GLubyte
*) values
;
541 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
, y
);
542 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
543 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
544 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
548 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
549 for (i
= 0; i
< count
; i
++) {
550 if (!mask
|| mask
[i
]) {
555 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
556 for (i
= 0; i
< count
; i
++) {
557 if (!mask
|| mask
[i
]) {
558 dst
[i
] = (dst
[i
] & 0xffffff00) | src
[i
];
563 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
564 for (i
= 0; i
< count
; i
++) {
565 if (!mask
|| mask
[i
]) {
566 dst
[i
] = (dst
[i
] & 0xffffff) | (src
[i
] << 24);
572 /* get, modify, put */
573 GLuint temp
[MAX_WIDTH
*2], i
;
574 dsrb
->GetRow(ctx
, dsrb
, count
, x
, y
, temp
);
575 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
576 for (i
= 0; i
< count
; i
++) {
577 if (!mask
|| mask
[i
]) {
578 temp
[i
*2+1] = src
[i
];
582 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
583 for (i
= 0; i
< count
; i
++) {
584 if (!mask
|| mask
[i
]) {
585 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
590 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
591 for (i
= 0; i
< count
; i
++) {
592 if (!mask
|| mask
[i
]) {
593 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
597 dsrb
->PutRow(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
603 put_values_s8(struct gl_context
*ctx
, struct gl_renderbuffer
*s8rb
, GLuint count
,
604 const GLint x
[], const GLint y
[],
605 const void *values
, const GLubyte
*mask
)
607 struct gl_renderbuffer
*dsrb
= s8rb
->Wrapped
;
608 const GLubyte
*src
= (const GLubyte
*) values
;
609 ASSERT(s8rb
->DataType
== GL_UNSIGNED_BYTE
);
610 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
611 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
612 if (dsrb
->GetPointer(ctx
, dsrb
, 0, 0)) {
615 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
616 for (i
= 0; i
< count
; i
++) {
617 if (!mask
|| mask
[i
]) {
618 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
623 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
624 for (i
= 0; i
< count
; i
++) {
625 if (!mask
|| mask
[i
]) {
626 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
627 *dst
= (*dst
& 0xffffff00) | src
[i
];
632 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
633 for (i
= 0; i
< count
; i
++) {
634 if (!mask
|| mask
[i
]) {
635 GLuint
*dst
= (GLuint
*) dsrb
->GetPointer(ctx
, dsrb
, x
[i
], y
[i
]);
636 *dst
= (*dst
& 0xffffff) | (src
[i
] << 24);
642 /* get, modify, put */
643 GLuint temp
[MAX_WIDTH
*2], i
;
644 dsrb
->GetValues(ctx
, dsrb
, count
, x
, y
, temp
);
645 if (dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
646 for (i
= 0; i
< count
; i
++) {
647 if (!mask
|| mask
[i
]) {
648 temp
[i
*2+1] = src
[i
];
652 else if (dsrb
->Format
== MESA_FORMAT_Z24_S8
) {
653 for (i
= 0; i
< count
; i
++) {
654 if (!mask
|| mask
[i
]) {
655 temp
[i
] = (temp
[i
] & 0xffffff00) | src
[i
];
660 assert(dsrb
->Format
== MESA_FORMAT_S8_Z24
);
661 for (i
= 0; i
< count
; i
++) {
662 if (!mask
|| mask
[i
]) {
663 temp
[i
] = (temp
[i
] & 0xffffff) | (src
[i
] << 24);
667 dsrb
->PutValues(ctx
, dsrb
, count
, x
, y
, temp
, mask
);
673 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
674 * a stencil renderbuffer.
675 * \return new stencil renderbuffer
677 static struct gl_renderbuffer
*
678 new_s8_renderbuffer_wrapper(struct gl_context
*ctx
, struct gl_renderbuffer
*dsrb
)
680 struct gl_renderbuffer
*s8rb
;
682 ASSERT(dsrb
->Format
== MESA_FORMAT_Z24_S8
||
683 dsrb
->Format
== MESA_FORMAT_S8_Z24
||
684 dsrb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
);
685 ASSERT(dsrb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
||
686 dsrb
->DataType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
688 s8rb
= ctx
->Driver
.NewRenderbuffer(ctx
, 0);
692 /* NOTE: need to do manual refcounting here */
693 s8rb
->Wrapped
= dsrb
;
696 s8rb
->Name
= dsrb
->Name
;
698 s8rb
->Width
= dsrb
->Width
;
699 s8rb
->Height
= dsrb
->Height
;
700 s8rb
->RowStride
= dsrb
->RowStride
;
701 s8rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
702 s8rb
->Format
= MESA_FORMAT_S8
;
703 s8rb
->_BaseFormat
= GL_STENCIL_INDEX
;
704 s8rb
->DataType
= GL_UNSIGNED_BYTE
;
706 s8rb
->Delete
= delete_wrapper
;
707 s8rb
->AllocStorage
= alloc_wrapper_storage
;
708 s8rb
->GetPointer
= nop_get_pointer
;
709 s8rb
->GetRow
= get_row_s8
;
710 s8rb
->GetValues
= get_values_s8
;
711 s8rb
->PutRow
= put_row_s8
;
712 s8rb
->PutRowRGB
= NULL
;
713 s8rb
->PutValues
= put_values_s8
;
720 * Update the framebuffer's _DepthBuffer field using the renderbuffer
721 * found at the given attachment index.
723 * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
724 * create and install a depth wrapper/adaptor.
726 * \param fb the framebuffer whose _DepthBuffer field to update
729 _swrast_update_depth_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
731 struct gl_renderbuffer
*depthRb
=
732 fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
734 if (depthRb
&& _mesa_is_format_packed_depth_stencil(depthRb
->Format
)) {
735 /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
736 if (!fb
->_DepthBuffer
737 || fb
->_DepthBuffer
->Wrapped
!= depthRb
738 || _mesa_get_format_base_format(fb
->_DepthBuffer
->Format
) != GL_DEPTH_COMPONENT
) {
739 /* need to update wrapper */
740 struct gl_renderbuffer
*wrapper
;
742 if (depthRb
->Format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
743 wrapper
= new_z32f_renderbuffer_wrapper(ctx
, depthRb
);
746 wrapper
= new_z24_renderbuffer_wrapper(ctx
, depthRb
);
748 _mesa_reference_renderbuffer(&fb
->_DepthBuffer
, wrapper
);
750 ASSERT(fb
->_DepthBuffer
->Wrapped
== depthRb
);
751 fb
->_DepthBuffer
->Width
= depthRb
->Width
;
752 fb
->_DepthBuffer
->Height
= depthRb
->Height
;
755 /* depthRb may be null */
756 _mesa_reference_renderbuffer(&fb
->_DepthBuffer
, depthRb
);
762 * Update the framebuffer's _StencilBuffer field using the renderbuffer
763 * found at the given attachment index.
765 * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
766 * create and install a stencil wrapper/adaptor.
768 * \param fb the framebuffer whose _StencilBuffer field to update
771 _swrast_update_stencil_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
773 struct gl_renderbuffer
*stencilRb
=
774 fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
776 if (stencilRb
&& _mesa_is_format_packed_depth_stencil(stencilRb
->Format
)) {
777 /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
778 if (!fb
->_StencilBuffer
779 || fb
->_StencilBuffer
->Wrapped
!= stencilRb
780 || _mesa_get_format_base_format(fb
->_StencilBuffer
->Format
) != GL_STENCIL_INDEX
) {
781 /* need to update wrapper */
782 struct gl_renderbuffer
*wrapper
783 = new_s8_renderbuffer_wrapper(ctx
, stencilRb
);
784 _mesa_reference_renderbuffer(&fb
->_StencilBuffer
, wrapper
);
786 ASSERT(fb
->_StencilBuffer
->Wrapped
== stencilRb
);
787 fb
->_StencilBuffer
->Width
= stencilRb
->Width
;
788 fb
->_StencilBuffer
->Height
= stencilRb
->Height
;
791 /* stencilRb may be null */
792 _mesa_reference_renderbuffer(&fb
->_StencilBuffer
, stencilRb
);