~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/main/depthstencil.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Mesa 3-D graphics library
3
 
 * Version:  6.5
4
 
 *
5
 
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6
 
 *
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:
13
 
 *
14
 
 * The above copyright notice and this permission notice shall be included
15
 
 * in all copies or substantial portions of the Software.
16
 
 *
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.
23
 
 */
24
 
 
25
 
#include "glheader.h"
26
 
#include "imports.h"
27
 
#include "context.h"
28
 
#include "formats.h"
29
 
#include "mtypes.h"
30
 
#include "depthstencil.h"
31
 
#include "renderbuffer.h"
32
 
 
33
 
 
34
 
/**
35
 
 * Adaptor/wrappers for GL_DEPTH_STENCIL renderbuffers.
36
 
 *
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.
42
 
 *
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.
45
 
 */
46
 
 
47
 
 
48
 
static void *
49
 
nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
50
 
{
51
 
   (void) ctx;
52
 
   (void) rb;
53
 
   (void) x;
54
 
   (void) y;
55
 
   return NULL;
56
 
}
57
 
 
58
 
 
59
 
/**
60
 
 * Delete a depth or stencil wrapper renderbuffer.
61
 
 */
62
 
static void
63
 
delete_wrapper(struct gl_renderbuffer *rb)
64
 
{
65
 
   ASSERT(rb->Format == MESA_FORMAT_S8 ||
66
 
          rb->Format == MESA_FORMAT_X8_Z24);
67
 
   _mesa_reference_renderbuffer(&rb->Wrapped, NULL);
68
 
   free(rb);
69
 
}
70
 
 
71
 
 
72
 
/**
73
 
 * Realloc storage for wrapper.
74
 
 */
75
 
static GLboolean
76
 
alloc_wrapper_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
77
 
                      GLenum internalFormat, GLuint width, GLuint height)
78
 
{
79
 
   /* just pass this on to the wrapped renderbuffer */
80
 
   struct gl_renderbuffer *dsrb = rb->Wrapped;
81
 
   GLboolean retVal;
82
 
 
83
 
   (void) internalFormat;
84
 
 
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);
89
 
 
90
 
   retVal = dsrb->AllocStorage(ctx, dsrb, dsrb->InternalFormat, width, height);
91
 
   if (retVal) {
92
 
      rb->Width = width;
93
 
      rb->Height = height;
94
 
      rb->RowStride = dsrb->RowStride;
95
 
   }
96
 
   return retVal;
97
 
}
98
 
 
99
 
 
100
 
 
101
 
 
102
 
/*======================================================================
103
 
 * Depth wrapper around depth/stencil renderbuffer
104
 
 */
105
 
 
106
 
static void
107
 
get_row_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
108
 
            GLint x, GLint y, void *values)
109
 
{
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);
116
 
   if (!src) {
117
 
      dsrb->GetRow(ctx, dsrb, count, x, y, temp);
118
 
      src = temp;
119
 
   }
120
 
   if (dsrb->Format == MESA_FORMAT_Z24_S8) {
121
 
      for (i = 0; i < count; i++) {
122
 
         dst[i] = src[i] >> 8;
123
 
      }
124
 
   }
125
 
   else {
126
 
      assert(dsrb->Format == MESA_FORMAT_S8_Z24);
127
 
      for (i = 0; i < count; i++) {
128
 
         dst[i] = src[i] & 0xffffff;
129
 
      }
130
 
   }
131
 
}
132
 
 
133
 
static void
134
 
get_values_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count,
135
 
               const GLint x[], const GLint y[], void *values)
136
 
{
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;
148
 
      }
149
 
   }
150
 
   else {
151
 
      assert(dsrb->Format == MESA_FORMAT_S8_Z24);
152
 
      for (i = 0; i < count; i++) {
153
 
         dst[i] = temp[i] & 0xffffff;
154
 
      }
155
 
   }
156
 
}
157
 
 
158
 
static void
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)
161
 
{
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);
167
 
   if (dst) {
168
 
      /* direct access */
169
 
      GLuint i;
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);
174
 
            }
175
 
         }
176
 
      }
177
 
      else {
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);
182
 
            }
183
 
         }
184
 
      }
185
 
   }
186
 
   else {
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);
194
 
            }
195
 
         }
196
 
      }
197
 
      else {
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);
202
 
            }
203
 
         }
204
 
      }
205
 
      dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
206
 
   }
207
 
}
208
 
 
209
 
static void
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)
212
 
{
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);
217
 
   if (dst) {
218
 
      /* direct access */
219
 
      GLuint i;
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);
225
 
            }
226
 
         }
227
 
      }
228
 
      else {
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);
234
 
            }
235
 
         }
236
 
      }
237
 
   }
238
 
   else {
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);
247
 
            }
248
 
         }
249
 
      }
250
 
      else {
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);
256
 
            }
257
 
         }
258
 
      }
259
 
      dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
260
 
   }
261
 
}
262
 
 
263
 
static void
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)
267
 
{
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)) {
273
 
      /* direct access */
274
 
      GLuint i;
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);
280
 
            }
281
 
         }
282
 
      }
283
 
      else {
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);
289
 
            }
290
 
         }
291
 
      }
292
 
   }
293
 
   else {
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);
301
 
            }
302
 
         }
303
 
      }
304
 
      else {
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);
309
 
            }
310
 
         }
311
 
      }
312
 
      dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
313
 
   }
314
 
}
315
 
 
316
 
static void
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)
320
 
{
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);
330
 
         }
331
 
      }
332
 
   }
333
 
   else {
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);
339
 
         }
340
 
      }
341
 
   }
342
 
   dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
343
 
}
344
 
 
345
 
 
346
 
/**
347
 
 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
348
 
 * a depth renderbuffer.
349
 
 * \return new depth renderbuffer
350
 
 */
351
 
struct gl_renderbuffer *
352
 
_mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
353
 
                                   struct gl_renderbuffer *dsrb)
354
 
{
355
 
   struct gl_renderbuffer *z24rb;
356
 
 
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);
362
 
 
363
 
   z24rb = ctx->Driver.NewRenderbuffer(ctx, 0);
364
 
   if (!z24rb)
365
 
      return NULL;
366
 
 
367
 
   /* NOTE: need to do manual refcounting here */
368
 
   z24rb->Wrapped = dsrb;
369
 
   dsrb->RefCount++;
370
 
 
371
 
   z24rb->Name = dsrb->Name;
372
 
   z24rb->RefCount = 0;
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;
380
 
   z24rb->Data = NULL;
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;
391
 
 
392
 
   return z24rb;
393
 
}
394
 
 
395
 
 
396
 
/*======================================================================
397
 
 * Stencil wrapper around depth/stencil renderbuffer
398
 
 */
399
 
 
400
 
static void
401
 
get_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
402
 
           GLint x, GLint y, void *values)
403
 
{
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);
410
 
   if (!src) {
411
 
      dsrb->GetRow(ctx, dsrb, count, x, y, temp);
412
 
      src = temp;
413
 
   }
414
 
   if (dsrb->Format == MESA_FORMAT_Z24_S8) {
415
 
      for (i = 0; i < count; i++) {
416
 
         dst[i] = src[i] & 0xff;
417
 
      }
418
 
   }
419
 
   else {
420
 
      assert(dsrb->Format == MESA_FORMAT_S8_Z24);
421
 
      for (i = 0; i < count; i++) {
422
 
         dst[i] = src[i] >> 24;
423
 
      }
424
 
   }
425
 
}
426
 
 
427
 
static void
428
 
get_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
429
 
              const GLint x[], const GLint y[], void *values)
430
 
{
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;
442
 
      }
443
 
   }
444
 
   else {
445
 
      assert(dsrb->Format == MESA_FORMAT_S8_Z24);
446
 
      for (i = 0; i < count; i++) {
447
 
         dst[i] = temp[i] >> 24;
448
 
      }
449
 
   }
450
 
}
451
 
 
452
 
static void
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)
455
 
{
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);
461
 
   if (dst) {
462
 
      /* direct access */
463
 
      GLuint i;
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];
468
 
            }
469
 
         }
470
 
      }
471
 
      else {
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);
476
 
            }
477
 
         }
478
 
      }
479
 
   }
480
 
   else {
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];
488
 
            }
489
 
         }
490
 
      }
491
 
      else {
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);
496
 
            }
497
 
         }
498
 
      }
499
 
      dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
500
 
   }
501
 
}
502
 
 
503
 
static void
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)
506
 
{
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);
512
 
   if (dst) {
513
 
      /* direct access */
514
 
      GLuint i;
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;
519
 
            }
520
 
         }
521
 
      }
522
 
      else {
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);
527
 
            }
528
 
         }
529
 
      }
530
 
   }
531
 
   else {
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;
539
 
            }
540
 
         }
541
 
      }
542
 
      else {
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);
547
 
            }
548
 
         }
549
 
      }
550
 
      dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
551
 
   }
552
 
}
553
 
 
554
 
static void
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)
558
 
{
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)) {
564
 
      /* direct access */
565
 
      GLuint i;
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];
571
 
            }
572
 
         }
573
 
      }
574
 
      else {
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);
580
 
            }
581
 
         }
582
 
      }
583
 
   }
584
 
   else {
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];
592
 
            }
593
 
         }
594
 
      }
595
 
      else {
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);
600
 
            }
601
 
         }
602
 
      }
603
 
      dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
604
 
   }
605
 
}
606
 
 
607
 
static void
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)
611
 
{
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;
621
 
         }
622
 
      }
623
 
   }
624
 
   else {
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);
629
 
         }
630
 
      }
631
 
   }
632
 
   dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
633
 
}
634
 
 
635
 
 
636
 
/**
637
 
 * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
638
 
 * a stencil renderbuffer.
639
 
 * \return new stencil renderbuffer
640
 
 */
641
 
struct gl_renderbuffer *
642
 
_mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer *dsrb)
643
 
{
644
 
   struct gl_renderbuffer *s8rb;
645
 
 
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);
649
 
 
650
 
   s8rb = ctx->Driver.NewRenderbuffer(ctx, 0);
651
 
   if (!s8rb)
652
 
      return NULL;
653
 
 
654
 
   /* NOTE: need to do manual refcounting here */
655
 
   s8rb->Wrapped = dsrb;
656
 
   dsrb->RefCount++;
657
 
 
658
 
   s8rb->Name = dsrb->Name;
659
 
   s8rb->RefCount = 0;
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;
667
 
   s8rb->Data = NULL;
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;
678
 
 
679
 
   return s8rb;
680
 
}
681
 
 
682
 
 
683
 
 
684
 
/**
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
692
 
 ** renderbuffers.
693
 
 **/
694
 
 
695
 
 
696
 
/**
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)
702
 
 */
703
 
void
704
 
_mesa_extract_stencil(struct gl_context *ctx,
705
 
                      struct gl_renderbuffer *dsRb,
706
 
                      struct gl_renderbuffer *stencilRb)
707
 
{
708
 
   GLuint row, width, height;
709
 
 
710
 
   ASSERT(dsRb);
711
 
   ASSERT(stencilRb);
712
 
 
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);
719
 
 
720
 
   width = dsRb->Width;
721
 
   height = dsRb->Height;
722
 
 
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) {
727
 
         /* 8bpp stencil */
728
 
         GLubyte stencil[MAX_WIDTH];
729
 
         GLuint i;
730
 
         for (i = 0; i < width; i++) {
731
 
            stencil[i] = depthStencil[i] & 0xff;
732
 
         }
733
 
         stencilRb->PutRow(ctx, stencilRb, width, 0, row, stencil, NULL);
734
 
      }
735
 
      else {
736
 
         /* 32bpp stencil */
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);
741
 
      }
742
 
   }
743
 
}
744
 
 
745
 
 
746
 
/**
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)
751
 
 */
752
 
void
753
 
_mesa_insert_stencil(struct gl_context *ctx,
754
 
                     struct gl_renderbuffer *dsRb,
755
 
                     struct gl_renderbuffer *stencilRb)
756
 
{
757
 
   GLuint row, width, height;
758
 
 
759
 
   ASSERT(dsRb);
760
 
   ASSERT(stencilRb);
761
 
 
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);
766
 
 
767
 
   ASSERT(dsRb->Width == stencilRb->Width);
768
 
   ASSERT(dsRb->Height == stencilRb->Height);
769
 
 
770
 
   width = dsRb->Width;
771
 
   height = dsRb->Height;
772
 
 
773
 
   for (row = 0; row < height; row++) {
774
 
      GLuint depthStencil[MAX_WIDTH];
775
 
 
776
 
      dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
777
 
 
778
 
      if (stencilRb->Format == MESA_FORMAT_S8) {
779
 
         /* 8bpp stencil */
780
 
         GLubyte stencil[MAX_WIDTH];
781
 
         GLuint i;
782
 
         stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
783
 
         for (i = 0; i < width; i++) {
784
 
            depthStencil[i] = (depthStencil[i] & 0xffffff00) | stencil[i];
785
 
         }
786
 
      }
787
 
      else {
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++) {
794
 
            depthStencil[i]
795
 
               = (depthStencil[i] & 0xffffff00) | (stencil[i] & 0xff);
796
 
         }
797
 
      }
798
 
 
799
 
      dsRb->PutRow(ctx, dsRb, width, 0, row, depthStencil, NULL);
800
 
   }
801
 
}
802
 
 
803
 
 
804
 
/**
805
 
 * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
806
 
 * \param stencilRb  the stencil renderbuffer to promote
807
 
 */
808
 
void
809
 
_mesa_promote_stencil(struct gl_context *ctx, struct gl_renderbuffer *stencilRb)
810
 
{
811
 
   const GLsizei width = stencilRb->Width;
812
 
   const GLsizei height = stencilRb->Height;
813
 
   GLubyte *data;
814
 
   GLint i, j, k;
815
 
 
816
 
   ASSERT(stencilRb->Format == MESA_FORMAT_S8);
817
 
   ASSERT(stencilRb->Data);
818
 
 
819
 
   data = (GLubyte *) stencilRb->Data;
820
 
   stencilRb->Data = NULL;
821
 
   stencilRb->AllocStorage(ctx, stencilRb, GL_DEPTH24_STENCIL8_EXT,
822
 
                           width, height);
823
 
 
824
 
   ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
825
 
 
826
 
   k = 0;
827
 
   for (i = 0; i < height; i++) {
828
 
      GLuint depthStencil[MAX_WIDTH];
829
 
      for (j = 0; j < width; j++) {
830
 
         depthStencil[j] = data[k++];
831
 
      }
832
 
      stencilRb->PutRow(ctx, stencilRb, width, 0, i, depthStencil, NULL);
833
 
   }
834
 
   free(data);
835
 
}