2
* Mesa 3-D graphics library
5
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice shall be included
15
* in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
#include "depthstencil.h"
31
#include "renderbuffer.h"
35
* Adaptor/wrappers for GL_DEPTH_STENCIL renderbuffers.
37
* The problem with a GL_DEPTH_STENCIL renderbuffer is that sometimes we
38
* want to treat it as a stencil buffer, other times we want to treat it
39
* as a depth/z buffer and still other times when we want to treat it as
40
* a combined Z+stencil buffer! That implies we need three different sets
41
* of Get/Put functions.
43
* We solve this by wrapping the Z24_S8 or S8_Z24 renderbuffer with depth and
44
* stencil adaptors, each with the right kind of depth/stencil Get/Put functions.
49
nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
60
* Delete a depth or stencil wrapper renderbuffer.
63
delete_wrapper(struct gl_renderbuffer *rb)
65
ASSERT(rb->Format == MESA_FORMAT_S8 ||
66
rb->Format == MESA_FORMAT_X8_Z24);
67
_mesa_reference_renderbuffer(&rb->Wrapped, NULL);
73
* Realloc storage for wrapper.
76
alloc_wrapper_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
77
GLenum internalFormat, GLuint width, GLuint height)
79
/* just pass this on to the wrapped renderbuffer */
80
struct gl_renderbuffer *dsrb = rb->Wrapped;
83
(void) internalFormat;
85
ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
86
dsrb->Format == MESA_FORMAT_Z24_X8 ||
87
dsrb->Format == MESA_FORMAT_S8_Z24 ||
88
dsrb->Format == MESA_FORMAT_X8_Z24);
90
retVal = dsrb->AllocStorage(ctx, dsrb, dsrb->InternalFormat, width, height);
94
rb->RowStride = dsrb->RowStride;
102
/*======================================================================
103
* Depth wrapper around depth/stencil renderbuffer
107
get_row_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
108
GLint x, GLint y, void *values)
110
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
111
GLuint temp[MAX_WIDTH], i;
112
GLuint *dst = (GLuint *) values;
113
const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
114
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
115
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
117
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
120
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
121
for (i = 0; i < count; i++) {
122
dst[i] = src[i] >> 8;
126
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
127
for (i = 0; i < count; i++) {
128
dst[i] = src[i] & 0xffffff;
134
get_values_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
135
const GLint x[], const GLint y[], void *values)
137
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
138
GLuint temp[MAX_WIDTH], i;
139
GLuint *dst = (GLuint *) values;
140
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
141
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
142
ASSERT(count <= MAX_WIDTH);
143
/* don't bother trying direct access */
144
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
145
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
146
for (i = 0; i < count; i++) {
147
dst[i] = temp[i] >> 8;
151
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
152
for (i = 0; i < count; i++) {
153
dst[i] = temp[i] & 0xffffff;
159
put_row_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
160
GLint x, GLint y, const void *values, const GLubyte *mask)
162
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
163
const GLuint *src = (const GLuint *) values;
164
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
165
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
166
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
170
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
171
for (i = 0; i < count; i++) {
172
if (!mask || mask[i]) {
173
dst[i] = (src[i] << 8) | (dst[i] & 0xff);
178
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
179
for (i = 0; i < count; i++) {
180
if (!mask || mask[i]) {
181
dst[i] = (src[i] & 0xffffff) | (dst[i] & 0xff000000);
187
/* get, modify, put */
188
GLuint temp[MAX_WIDTH], i;
189
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
190
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
191
for (i = 0; i < count; i++) {
192
if (!mask || mask[i]) {
193
temp[i] = (src[i] << 8) | (temp[i] & 0xff);
198
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
199
for (i = 0; i < count; i++) {
200
if (!mask || mask[i]) {
201
temp[i] = (src[i] & 0xffffff) | (temp[i] & 0xff000000);
205
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
210
put_mono_row_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
211
GLint x, GLint y, const void *value, const GLubyte *mask)
213
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
214
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
215
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
216
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
220
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
221
const GLuint shiftedVal = *((GLuint *) value) << 8;
222
for (i = 0; i < count; i++) {
223
if (!mask || mask[i]) {
224
dst[i] = shiftedVal | (dst[i] & 0xff);
229
const GLuint shiftedVal = *((GLuint *) value);
230
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
231
for (i = 0; i < count; i++) {
232
if (!mask || mask[i]) {
233
dst[i] = shiftedVal | (dst[i] & 0xff000000);
239
/* get, modify, put */
240
GLuint temp[MAX_WIDTH], i;
241
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
242
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
243
const GLuint shiftedVal = *((GLuint *) value) << 8;
244
for (i = 0; i < count; i++) {
245
if (!mask || mask[i]) {
246
temp[i] = shiftedVal | (temp[i] & 0xff);
251
const GLuint shiftedVal = *((GLuint *) value);
252
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
253
for (i = 0; i < count; i++) {
254
if (!mask || mask[i]) {
255
temp[i] = shiftedVal | (temp[i] & 0xff000000);
259
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
264
put_values_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
265
const GLint x[], const GLint y[],
266
const void *values, const GLubyte *mask)
268
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
269
const GLuint *src = (const GLuint *) values;
270
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
271
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
272
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
275
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
276
for (i = 0; i < count; i++) {
277
if (!mask || mask[i]) {
278
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
279
*dst = (src[i] << 8) | (*dst & 0xff);
284
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
285
for (i = 0; i < count; i++) {
286
if (!mask || mask[i]) {
287
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
288
*dst = (src[i] & 0xffffff) | (*dst & 0xff000000);
294
/* get, modify, put */
295
GLuint temp[MAX_WIDTH], i;
296
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
297
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
298
for (i = 0; i < count; i++) {
299
if (!mask || mask[i]) {
300
temp[i] = (src[i] << 8) | (temp[i] & 0xff);
305
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
306
for (i = 0; i < count; i++) {
307
if (!mask || mask[i]) {
308
temp[i] = (src[i] & 0xffffff) | (temp[i] & 0xff000000);
312
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
317
put_mono_values_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb,
318
GLuint count, const GLint x[], const GLint y[],
319
const void *value, const GLubyte *mask)
321
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
322
GLuint temp[MAX_WIDTH], i;
323
/* get, modify, put */
324
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
325
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
326
const GLuint shiftedVal = *((GLuint *) value) << 8;
327
for (i = 0; i < count; i++) {
328
if (!mask || mask[i]) {
329
temp[i] = shiftedVal | (temp[i] & 0xff);
334
const GLuint shiftedVal = *((GLuint *) value);
335
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
336
for (i = 0; i < count; i++) {
337
if (!mask || mask[i]) {
338
temp[i] = shiftedVal | (temp[i] & 0xff000000);
342
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
347
* Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
348
* a depth renderbuffer.
349
* \return new depth renderbuffer
351
struct gl_renderbuffer *
352
_mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
353
struct gl_renderbuffer *dsrb)
355
struct gl_renderbuffer *z24rb;
357
ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
358
dsrb->Format == MESA_FORMAT_Z24_X8 ||
359
dsrb->Format == MESA_FORMAT_S8_Z24 ||
360
dsrb->Format == MESA_FORMAT_X8_Z24);
361
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
363
z24rb = ctx->Driver.NewRenderbuffer(ctx, 0);
367
/* NOTE: need to do manual refcounting here */
368
z24rb->Wrapped = dsrb;
371
z24rb->Name = dsrb->Name;
373
z24rb->Width = dsrb->Width;
374
z24rb->Height = dsrb->Height;
375
z24rb->RowStride = dsrb->RowStride;
376
z24rb->InternalFormat = GL_DEPTH_COMPONENT24;
377
z24rb->Format = MESA_FORMAT_X8_Z24;
378
z24rb->_BaseFormat = GL_DEPTH_COMPONENT;
379
z24rb->DataType = GL_UNSIGNED_INT;
381
z24rb->Delete = delete_wrapper;
382
z24rb->AllocStorage = alloc_wrapper_storage;
383
z24rb->GetPointer = nop_get_pointer;
384
z24rb->GetRow = get_row_z24;
385
z24rb->GetValues = get_values_z24;
386
z24rb->PutRow = put_row_z24;
387
z24rb->PutRowRGB = NULL;
388
z24rb->PutMonoRow = put_mono_row_z24;
389
z24rb->PutValues = put_values_z24;
390
z24rb->PutMonoValues = put_mono_values_z24;
396
/*======================================================================
397
* Stencil wrapper around depth/stencil renderbuffer
401
get_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
402
GLint x, GLint y, void *values)
404
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
405
GLuint temp[MAX_WIDTH], i;
406
GLubyte *dst = (GLubyte *) values;
407
const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
408
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
409
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
411
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
414
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
415
for (i = 0; i < count; i++) {
416
dst[i] = src[i] & 0xff;
420
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
421
for (i = 0; i < count; i++) {
422
dst[i] = src[i] >> 24;
428
get_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
429
const GLint x[], const GLint y[], void *values)
431
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
432
GLuint temp[MAX_WIDTH], i;
433
GLubyte *dst = (GLubyte *) values;
434
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
435
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
436
ASSERT(count <= MAX_WIDTH);
437
/* don't bother trying direct access */
438
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
439
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
440
for (i = 0; i < count; i++) {
441
dst[i] = temp[i] & 0xff;
445
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
446
for (i = 0; i < count; i++) {
447
dst[i] = temp[i] >> 24;
453
put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
454
GLint x, GLint y, const void *values, const GLubyte *mask)
456
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
457
const GLubyte *src = (const GLubyte *) values;
458
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
459
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
460
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
464
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
465
for (i = 0; i < count; i++) {
466
if (!mask || mask[i]) {
467
dst[i] = (dst[i] & 0xffffff00) | src[i];
472
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
473
for (i = 0; i < count; i++) {
474
if (!mask || mask[i]) {
475
dst[i] = (dst[i] & 0xffffff) | (src[i] << 24);
481
/* get, modify, put */
482
GLuint temp[MAX_WIDTH], i;
483
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
484
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
485
for (i = 0; i < count; i++) {
486
if (!mask || mask[i]) {
487
temp[i] = (temp[i] & 0xffffff00) | src[i];
492
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
493
for (i = 0; i < count; i++) {
494
if (!mask || mask[i]) {
495
temp[i] = (temp[i] & 0xffffff) | (src[i] << 24);
499
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
504
put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
505
GLint x, GLint y, const void *value, const GLubyte *mask)
507
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
508
const GLubyte val = *((GLubyte *) value);
509
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
510
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
511
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
515
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
516
for (i = 0; i < count; i++) {
517
if (!mask || mask[i]) {
518
dst[i] = (dst[i] & 0xffffff00) | val;
523
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
524
for (i = 0; i < count; i++) {
525
if (!mask || mask[i]) {
526
dst[i] = (dst[i] & 0xffffff) | (val << 24);
532
/* get, modify, put */
533
GLuint temp[MAX_WIDTH], i;
534
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
535
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
536
for (i = 0; i < count; i++) {
537
if (!mask || mask[i]) {
538
temp[i] = (temp[i] & 0xffffff00) | val;
543
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
544
for (i = 0; i < count; i++) {
545
if (!mask || mask[i]) {
546
temp[i] = (temp[i] & 0xffffff) | (val << 24);
550
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
555
put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
556
const GLint x[], const GLint y[],
557
const void *values, const GLubyte *mask)
559
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
560
const GLubyte *src = (const GLubyte *) values;
561
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
562
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
563
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
566
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
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 & 0xffffff00) | src[i];
575
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
576
for (i = 0; i < count; i++) {
577
if (!mask || mask[i]) {
578
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
579
*dst = (*dst & 0xffffff) | (src[i] << 24);
585
/* get, modify, put */
586
GLuint temp[MAX_WIDTH], i;
587
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
588
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
589
for (i = 0; i < count; i++) {
590
if (!mask || mask[i]) {
591
temp[i] = (temp[i] & 0xffffff00) | src[i];
596
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
597
for (i = 0; i < count; i++) {
598
if (!mask || mask[i]) {
599
temp[i] = (temp[i] & 0xffffff) | (src[i] << 24);
603
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
608
put_mono_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
609
const GLint x[], const GLint y[],
610
const void *value, const GLubyte *mask)
612
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
613
GLuint temp[MAX_WIDTH], i;
614
const GLubyte val = *((GLubyte *) value);
615
/* get, modify, put */
616
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
617
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
618
for (i = 0; i < count; i++) {
619
if (!mask || mask[i]) {
620
temp[i] = (temp[i] & 0xffffff00) | val;
625
assert(dsrb->Format == MESA_FORMAT_S8_Z24);
626
for (i = 0; i < count; i++) {
627
if (!mask || mask[i]) {
628
temp[i] = (temp[i] & 0xffffff) | (val << 24);
632
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
637
* Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
638
* a stencil renderbuffer.
639
* \return new stencil renderbuffer
641
struct gl_renderbuffer *
642
_mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer *dsrb)
644
struct gl_renderbuffer *s8rb;
646
ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
647
dsrb->Format == MESA_FORMAT_S8_Z24);
648
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
650
s8rb = ctx->Driver.NewRenderbuffer(ctx, 0);
654
/* NOTE: need to do manual refcounting here */
655
s8rb->Wrapped = dsrb;
658
s8rb->Name = dsrb->Name;
660
s8rb->Width = dsrb->Width;
661
s8rb->Height = dsrb->Height;
662
s8rb->RowStride = dsrb->RowStride;
663
s8rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
664
s8rb->Format = MESA_FORMAT_S8;
665
s8rb->_BaseFormat = GL_STENCIL_INDEX;
666
s8rb->DataType = GL_UNSIGNED_BYTE;
668
s8rb->Delete = delete_wrapper;
669
s8rb->AllocStorage = alloc_wrapper_storage;
670
s8rb->GetPointer = nop_get_pointer;
671
s8rb->GetRow = get_row_s8;
672
s8rb->GetValues = get_values_s8;
673
s8rb->PutRow = put_row_s8;
674
s8rb->PutRowRGB = NULL;
675
s8rb->PutMonoRow = put_mono_row_s8;
676
s8rb->PutValues = put_values_s8;
677
s8rb->PutMonoValues = put_mono_values_s8;
685
** The following functions are useful for hardware drivers that only
686
** implement combined depth/stencil buffers.
687
** The GL_EXT_framebuffer_object extension allows indepedent depth and
688
** stencil buffers to be used in any combination.
689
** Therefore, we sometimes have to merge separate depth and stencil
690
** renderbuffers into a single depth+stencil renderbuffer. And sometimes
691
** we have to split combined depth+stencil renderbuffers into separate
697
* Extract stencil values from the combined depth/stencil renderbuffer, storing
698
* the values into a separate stencil renderbuffer.
699
* \param dsRb the source depth/stencil renderbuffer
700
* \param stencilRb the destination stencil renderbuffer
701
* (either 8-bit or 32-bit)
704
_mesa_extract_stencil(struct gl_context *ctx,
705
struct gl_renderbuffer *dsRb,
706
struct gl_renderbuffer *stencilRb)
708
GLuint row, width, height;
713
ASSERT(dsRb->Format == MESA_FORMAT_Z24_S8);
714
ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
715
ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8 ||
716
stencilRb->Format == MESA_FORMAT_S8);
717
ASSERT(dsRb->Width == stencilRb->Width);
718
ASSERT(dsRb->Height == stencilRb->Height);
721
height = dsRb->Height;
723
for (row = 0; row < height; row++) {
724
GLuint depthStencil[MAX_WIDTH];
725
dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
726
if (stencilRb->Format == MESA_FORMAT_S8) {
728
GLubyte stencil[MAX_WIDTH];
730
for (i = 0; i < width; i++) {
731
stencil[i] = depthStencil[i] & 0xff;
733
stencilRb->PutRow(ctx, stencilRb, width, 0, row, stencil, NULL);
737
/* the 24 depth bits will be ignored */
738
ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8);
739
ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
740
stencilRb->PutRow(ctx, stencilRb, width, 0, row, depthStencil, NULL);
747
* Copy stencil values from a stencil renderbuffer into a combined
748
* depth/stencil renderbuffer.
749
* \param dsRb the destination depth/stencil renderbuffer
750
* \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
753
_mesa_insert_stencil(struct gl_context *ctx,
754
struct gl_renderbuffer *dsRb,
755
struct gl_renderbuffer *stencilRb)
757
GLuint row, width, height;
762
ASSERT(dsRb->Format == MESA_FORMAT_Z24_S8);
763
ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
764
ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8 ||
765
stencilRb->Format == MESA_FORMAT_S8);
767
ASSERT(dsRb->Width == stencilRb->Width);
768
ASSERT(dsRb->Height == stencilRb->Height);
771
height = dsRb->Height;
773
for (row = 0; row < height; row++) {
774
GLuint depthStencil[MAX_WIDTH];
776
dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
778
if (stencilRb->Format == MESA_FORMAT_S8) {
780
GLubyte stencil[MAX_WIDTH];
782
stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
783
for (i = 0; i < width; i++) {
784
depthStencil[i] = (depthStencil[i] & 0xffffff00) | stencil[i];
788
/* 32bpp stencil buffer */
789
GLuint stencil[MAX_WIDTH], i;
790
ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8);
791
ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
792
stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
793
for (i = 0; i < width; i++) {
795
= (depthStencil[i] & 0xffffff00) | (stencil[i] & 0xff);
799
dsRb->PutRow(ctx, dsRb, width, 0, row, depthStencil, NULL);
805
* Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
806
* \param stencilRb the stencil renderbuffer to promote
809
_mesa_promote_stencil(struct gl_context *ctx, struct gl_renderbuffer *stencilRb)
811
const GLsizei width = stencilRb->Width;
812
const GLsizei height = stencilRb->Height;
816
ASSERT(stencilRb->Format == MESA_FORMAT_S8);
817
ASSERT(stencilRb->Data);
819
data = (GLubyte *) stencilRb->Data;
820
stencilRb->Data = NULL;
821
stencilRb->AllocStorage(ctx, stencilRb, GL_DEPTH24_STENCIL8_EXT,
824
ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
827
for (i = 0; i < height; i++) {
828
GLuint depthStencil[MAX_WIDTH];
829
for (j = 0; j < width; j++) {
830
depthStencil[j] = data[k++];
832
stencilRb->PutRow(ctx, stencilRb, width, 0, i, depthStencil, NULL);