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

« back to all changes in this revision

Viewing changes to src/mesa/swrast/s_renderbuffer.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
 
 
26
/**
 
27
 * Functions for allocating/managing software-based renderbuffers.
 
28
 * Also, routines for reading/writing software-based renderbuffer data as
 
29
 * ubytes, ushorts, uints, etc.
 
30
 */
 
31
 
 
32
 
 
33
#include "main/glheader.h"
 
34
#include "main/imports.h"
 
35
#include "main/context.h"
 
36
#include "main/fbobject.h"
 
37
#include "main/formats.h"
 
38
#include "main/mtypes.h"
 
39
#include "main/renderbuffer.h"
 
40
#include "swrast/s_context.h"
 
41
#include "swrast/s_renderbuffer.h"
 
42
 
 
43
 
 
44
/**
 
45
 * This is a software fallback for the gl_renderbuffer->AllocStorage
 
46
 * function.
 
47
 * Device drivers will typically override this function for the buffers
 
48
 * which it manages (typically color buffers, Z and stencil).
 
49
 * Other buffers (like software accumulation and aux buffers) which the driver
 
50
 * doesn't manage can be handled with this function.
 
51
 *
 
52
 * This one multi-purpose function can allocate stencil, depth, accum, color
 
53
 * or color-index buffers!
 
54
 */
 
55
static GLboolean
 
56
soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
 
57
                          GLenum internalFormat,
 
58
                          GLuint width, GLuint height)
 
59
{
 
60
   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
 
61
   GLuint bpp;
 
62
 
 
63
   switch (internalFormat) {
 
64
   case GL_RGB:
 
65
   case GL_R3_G3_B2:
 
66
   case GL_RGB4:
 
67
   case GL_RGB5:
 
68
   case GL_RGB8:
 
69
   case GL_RGB10:
 
70
   case GL_RGB12:
 
71
   case GL_RGB16:
 
72
      rb->Format = MESA_FORMAT_RGB888;
 
73
      break;
 
74
   case GL_RGBA:
 
75
   case GL_RGBA2:
 
76
   case GL_RGBA4:
 
77
   case GL_RGB5_A1:
 
78
   case GL_RGBA8:
 
79
#if 1
 
80
   case GL_RGB10_A2:
 
81
   case GL_RGBA12:
 
82
#endif
 
83
      if (_mesa_little_endian())
 
84
         rb->Format = MESA_FORMAT_RGBA8888_REV;
 
85
      else
 
86
         rb->Format = MESA_FORMAT_RGBA8888;
 
87
      break;
 
88
   case GL_RGBA16:
 
89
   case GL_RGBA16_SNORM:
 
90
      /* for accum buffer */
 
91
      rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
 
92
      break;
 
93
   case GL_STENCIL_INDEX:
 
94
   case GL_STENCIL_INDEX1_EXT:
 
95
   case GL_STENCIL_INDEX4_EXT:
 
96
   case GL_STENCIL_INDEX8_EXT:
 
97
   case GL_STENCIL_INDEX16_EXT:
 
98
      rb->Format = MESA_FORMAT_S8;
 
99
      break;
 
100
   case GL_DEPTH_COMPONENT:
 
101
   case GL_DEPTH_COMPONENT16:
 
102
      rb->Format = MESA_FORMAT_Z16;
 
103
      break;
 
104
   case GL_DEPTH_COMPONENT24:
 
105
      rb->Format = MESA_FORMAT_X8_Z24;
 
106
      break;
 
107
   case GL_DEPTH_COMPONENT32:
 
108
      rb->Format = MESA_FORMAT_Z32;
 
109
      break;
 
110
   case GL_DEPTH_STENCIL_EXT:
 
111
   case GL_DEPTH24_STENCIL8_EXT:
 
112
      rb->Format = MESA_FORMAT_Z24_S8;
 
113
      break;
 
114
   default:
 
115
      /* unsupported format */
 
116
      return GL_FALSE;
 
117
   }
 
118
 
 
119
   bpp = _mesa_get_format_bytes(rb->Format);
 
120
 
 
121
   /* free old buffer storage */
 
122
   if (srb->Buffer) {
 
123
      free(srb->Buffer);
 
124
      srb->Buffer = NULL;
 
125
   }
 
126
 
 
127
   srb->RowStride = width * bpp;
 
128
 
 
129
   if (width > 0 && height > 0) {
 
130
      /* allocate new buffer storage */
 
131
      srb->Buffer = malloc(srb->RowStride * height);
 
132
 
 
133
      if (srb->Buffer == NULL) {
 
134
         rb->Width = 0;
 
135
         rb->Height = 0;
 
136
         _mesa_error(ctx, GL_OUT_OF_MEMORY,
 
137
                     "software renderbuffer allocation (%d x %d x %d)",
 
138
                     width, height, bpp);
 
139
         return GL_FALSE;
 
140
      }
 
141
   }
 
142
 
 
143
   rb->Width = width;
 
144
   rb->Height = height;
 
145
   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
 
146
 
 
147
   if (rb->Name == 0 &&
 
148
       internalFormat == GL_RGBA16_SNORM &&
 
149
       rb->_BaseFormat == 0) {
 
150
      /* NOTE: This is a special case just for accumulation buffers.
 
151
       * This is a very limited use case- there's no snorm texturing or
 
152
       * rendering going on.
 
153
       */
 
154
      rb->_BaseFormat = GL_RGBA;
 
155
   }
 
156
   else {
 
157
      /* the internalFormat should have been error checked long ago */
 
158
      ASSERT(rb->_BaseFormat);
 
159
   }
 
160
 
 
161
   return GL_TRUE;
 
162
}
 
163
 
 
164
 
 
165
/**
 
166
 * Called via gl_renderbuffer::Delete()
 
167
 */
 
168
static void
 
169
soft_renderbuffer_delete(struct gl_renderbuffer *rb)
 
170
{
 
171
   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
 
172
 
 
173
   if (srb->Buffer) {
 
174
      free(srb->Buffer);
 
175
      srb->Buffer = NULL;
 
176
   }
 
177
   free(srb);
 
178
}
 
179
 
 
180
 
 
181
void
 
182
_swrast_map_soft_renderbuffer(struct gl_context *ctx,
 
183
                              struct gl_renderbuffer *rb,
 
184
                              GLuint x, GLuint y, GLuint w, GLuint h,
 
185
                              GLbitfield mode,
 
186
                              GLubyte **out_map,
 
187
                              GLint *out_stride)
 
188
{
 
189
   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
 
190
   GLubyte *map = srb->Buffer;
 
191
   int cpp = _mesa_get_format_bytes(rb->Format);
 
192
   int stride = rb->Width * cpp;
 
193
 
 
194
   if (!map) {
 
195
      *out_map = NULL;
 
196
      *out_stride = 0;
 
197
   }
 
198
 
 
199
   map += y * stride;
 
200
   map += x * cpp;
 
201
 
 
202
   *out_map = map;
 
203
   *out_stride = stride;
 
204
}
 
205
 
 
206
 
 
207
void
 
208
_swrast_unmap_soft_renderbuffer(struct gl_context *ctx,
 
209
                                struct gl_renderbuffer *rb)
 
210
{
 
211
}
 
212
 
 
213
 
 
214
 
 
215
/**
 
216
 * Allocate a software-based renderbuffer.  This is called via the
 
217
 * ctx->Driver.NewRenderbuffer() function when the user creates a new
 
218
 * renderbuffer.
 
219
 * This would not be used for hardware-based renderbuffers.
 
220
 */
 
221
struct gl_renderbuffer *
 
222
_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
 
223
{
 
224
   struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer);
 
225
   if (srb) {
 
226
      _mesa_init_renderbuffer(&srb->Base, name);
 
227
      srb->Base.AllocStorage = soft_renderbuffer_storage;
 
228
      srb->Base.Delete = soft_renderbuffer_delete;
 
229
   }
 
230
   return &srb->Base;
 
231
}
 
232
 
 
233
 
 
234
/**
 
235
 * Add software-based color renderbuffers to the given framebuffer.
 
236
 * This is a helper routine for device drivers when creating a
 
237
 * window system framebuffer (not a user-created render/framebuffer).
 
238
 * Once this function is called, you can basically forget about this
 
239
 * renderbuffer; core Mesa will handle all the buffer management and
 
240
 * rendering!
 
241
 */
 
242
static GLboolean
 
243
add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
 
244
                        GLuint rgbBits, GLuint alphaBits,
 
245
                        GLboolean frontLeft, GLboolean backLeft,
 
246
                        GLboolean frontRight, GLboolean backRight)
 
247
{
 
248
   gl_buffer_index b;
 
249
 
 
250
   if (rgbBits > 16 || alphaBits > 16) {
 
251
      _mesa_problem(ctx,
 
252
                    "Unsupported bit depth in add_color_renderbuffers");
 
253
      return GL_FALSE;
 
254
   }
 
255
 
 
256
   assert(MAX_COLOR_ATTACHMENTS >= 4);
 
257
 
 
258
   for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
 
259
      struct gl_renderbuffer *rb;
 
260
 
 
261
      if (b == BUFFER_FRONT_LEFT && !frontLeft)
 
262
         continue;
 
263
      else if (b == BUFFER_BACK_LEFT && !backLeft)
 
264
         continue;
 
265
      else if (b == BUFFER_FRONT_RIGHT && !frontRight)
 
266
         continue;
 
267
      else if (b == BUFFER_BACK_RIGHT && !backRight)
 
268
         continue;
 
269
 
 
270
      assert(fb->Attachment[b].Renderbuffer == NULL);
 
271
 
 
272
      rb = ctx->Driver.NewRenderbuffer(ctx, 0);
 
273
      if (!rb) {
 
274
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
 
275
         return GL_FALSE;
 
276
      }
 
277
 
 
278
      rb->InternalFormat = GL_RGBA;
 
279
 
 
280
      rb->AllocStorage = soft_renderbuffer_storage;
 
281
      _mesa_add_renderbuffer(fb, b, rb);
 
282
   }
 
283
 
 
284
   return GL_TRUE;
 
285
}
 
286
 
 
287
 
 
288
/**
 
289
 * Add a software-based depth renderbuffer to the given framebuffer.
 
290
 * This is a helper routine for device drivers when creating a
 
291
 * window system framebuffer (not a user-created render/framebuffer).
 
292
 * Once this function is called, you can basically forget about this
 
293
 * renderbuffer; core Mesa will handle all the buffer management and
 
294
 * rendering!
 
295
 */
 
296
static GLboolean
 
297
add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
 
298
                       GLuint depthBits)
 
299
{
 
300
   struct gl_renderbuffer *rb;
 
301
 
 
302
   if (depthBits > 32) {
 
303
      _mesa_problem(ctx,
 
304
                    "Unsupported depthBits in add_depth_renderbuffer");
 
305
      return GL_FALSE;
 
306
   }
 
307
 
 
308
   assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
 
309
 
 
310
   rb = _swrast_new_soft_renderbuffer(ctx, 0);
 
311
   if (!rb) {
 
312
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
 
313
      return GL_FALSE;
 
314
   }
 
315
 
 
316
   if (depthBits <= 16) {
 
317
      rb->InternalFormat = GL_DEPTH_COMPONENT16;
 
318
   }
 
319
   else if (depthBits <= 24) {
 
320
      rb->InternalFormat = GL_DEPTH_COMPONENT24;
 
321
   }
 
322
   else {
 
323
      rb->InternalFormat = GL_DEPTH_COMPONENT32;
 
324
   }
 
325
 
 
326
   rb->AllocStorage = soft_renderbuffer_storage;
 
327
   _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
 
328
 
 
329
   return GL_TRUE;
 
330
}
 
331
 
 
332
 
 
333
/**
 
334
 * Add a software-based stencil renderbuffer to the given framebuffer.
 
335
 * This is a helper routine for device drivers when creating a
 
336
 * window system framebuffer (not a user-created render/framebuffer).
 
337
 * Once this function is called, you can basically forget about this
 
338
 * renderbuffer; core Mesa will handle all the buffer management and
 
339
 * rendering!
 
340
 */
 
341
static GLboolean
 
342
add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
 
343
                         GLuint stencilBits)
 
344
{
 
345
   struct gl_renderbuffer *rb;
 
346
 
 
347
   if (stencilBits > 16) {
 
348
      _mesa_problem(ctx,
 
349
                  "Unsupported stencilBits in add_stencil_renderbuffer");
 
350
      return GL_FALSE;
 
351
   }
 
352
 
 
353
   assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
 
354
 
 
355
   rb = _swrast_new_soft_renderbuffer(ctx, 0);
 
356
   if (!rb) {
 
357
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
 
358
      return GL_FALSE;
 
359
   }
 
360
 
 
361
   assert(stencilBits <= 8);
 
362
   rb->InternalFormat = GL_STENCIL_INDEX8;
 
363
 
 
364
   rb->AllocStorage = soft_renderbuffer_storage;
 
365
   _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
 
366
 
 
367
   return GL_TRUE;
 
368
}
 
369
 
 
370
 
 
371
static GLboolean
 
372
add_depth_stencil_renderbuffer(struct gl_context *ctx,
 
373
                               struct gl_framebuffer *fb)
 
374
{
 
375
   struct gl_renderbuffer *rb;
 
376
 
 
377
   assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
 
378
   assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
 
379
 
 
380
   rb = _swrast_new_soft_renderbuffer(ctx, 0);
 
381
   if (!rb) {
 
382
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer");
 
383
      return GL_FALSE;
 
384
   }
 
385
 
 
386
   rb->InternalFormat = GL_DEPTH_STENCIL;
 
387
 
 
388
   rb->AllocStorage = soft_renderbuffer_storage;
 
389
   _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
 
390
   _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
 
391
 
 
392
   return GL_TRUE;
 
393
}
 
394
 
 
395
 
 
396
/**
 
397
 * Add a software-based accumulation renderbuffer to the given framebuffer.
 
398
 * This is a helper routine for device drivers when creating a
 
399
 * window system framebuffer (not a user-created render/framebuffer).
 
400
 * Once this function is called, you can basically forget about this
 
401
 * renderbuffer; core Mesa will handle all the buffer management and
 
402
 * rendering!
 
403
 */
 
404
static GLboolean
 
405
add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
 
406
                       GLuint redBits, GLuint greenBits,
 
407
                       GLuint blueBits, GLuint alphaBits)
 
408
{
 
409
   struct gl_renderbuffer *rb;
 
410
 
 
411
   if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
 
412
      _mesa_problem(ctx,
 
413
                    "Unsupported accumBits in add_accum_renderbuffer");
 
414
      return GL_FALSE;
 
415
   }
 
416
 
 
417
   assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
 
418
 
 
419
   rb = _swrast_new_soft_renderbuffer(ctx, 0);
 
420
   if (!rb) {
 
421
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
 
422
      return GL_FALSE;
 
423
   }
 
424
 
 
425
   rb->InternalFormat = GL_RGBA16_SNORM;
 
426
   rb->AllocStorage = soft_renderbuffer_storage;
 
427
   _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
 
428
 
 
429
   return GL_TRUE;
 
430
}
 
431
 
 
432
 
 
433
 
 
434
/**
 
435
 * Add a software-based aux renderbuffer to the given framebuffer.
 
436
 * This is a helper routine for device drivers when creating a
 
437
 * window system framebuffer (not a user-created render/framebuffer).
 
438
 * Once this function is called, you can basically forget about this
 
439
 * renderbuffer; core Mesa will handle all the buffer management and
 
440
 * rendering!
 
441
 *
 
442
 * NOTE: color-index aux buffers not supported.
 
443
 */
 
444
static GLboolean
 
445
add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
 
446
                      GLuint colorBits, GLuint numBuffers)
 
447
{
 
448
   GLuint i;
 
449
 
 
450
   if (colorBits > 16) {
 
451
      _mesa_problem(ctx,
 
452
                    "Unsupported colorBits in add_aux_renderbuffers");
 
453
      return GL_FALSE;
 
454
   }
 
455
 
 
456
   assert(numBuffers <= MAX_AUX_BUFFERS);
 
457
 
 
458
   for (i = 0; i < numBuffers; i++) {
 
459
      struct gl_renderbuffer *rb = _swrast_new_soft_renderbuffer(ctx, 0);
 
460
 
 
461
      assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
 
462
 
 
463
      if (!rb) {
 
464
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
 
465
         return GL_FALSE;
 
466
      }
 
467
 
 
468
      assert (colorBits <= 8);
 
469
      rb->InternalFormat = GL_RGBA;
 
470
 
 
471
      rb->AllocStorage = soft_renderbuffer_storage;
 
472
      _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
 
473
   }
 
474
   return GL_TRUE;
 
475
}
 
476
 
 
477
 
 
478
/**
 
479
 * Create/attach software-based renderbuffers to the given framebuffer.
 
480
 * This is a helper routine for device drivers.  Drivers can just as well
 
481
 * call the individual _mesa_add_*_renderbuffer() routines directly.
 
482
 */
 
483
void
 
484
_swrast_add_soft_renderbuffers(struct gl_framebuffer *fb,
 
485
                               GLboolean color,
 
486
                               GLboolean depth,
 
487
                               GLboolean stencil,
 
488
                               GLboolean accum,
 
489
                               GLboolean alpha,
 
490
                               GLboolean aux)
 
491
{
 
492
   GLboolean frontLeft = GL_TRUE;
 
493
   GLboolean backLeft = fb->Visual.doubleBufferMode;
 
494
   GLboolean frontRight = fb->Visual.stereoMode;
 
495
   GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
 
496
 
 
497
   if (color) {
 
498
      assert(fb->Visual.redBits == fb->Visual.greenBits);
 
499
      assert(fb->Visual.redBits == fb->Visual.blueBits);
 
500
      add_color_renderbuffers(NULL, fb,
 
501
                              fb->Visual.redBits,
 
502
                              fb->Visual.alphaBits,
 
503
                              frontLeft, backLeft,
 
504
                              frontRight, backRight);
 
505
   }
 
506
 
 
507
#if 0
 
508
   /* This is pretty much for debugging purposes only since there's a perf
 
509
    * hit for using combined depth/stencil in swrast.
 
510
    */
 
511
   if (depth && fb->Visual.depthBits == 24 &&
 
512
       stencil && fb->Visual.stencilBits == 8) {
 
513
      /* use combined depth/stencil buffer */
 
514
      add_depth_stencil_renderbuffer(NULL, fb);
 
515
   }
 
516
   else
 
517
#else
 
518
   (void) add_depth_stencil_renderbuffer;
 
519
#endif
 
520
   {
 
521
      if (depth) {
 
522
         assert(fb->Visual.depthBits > 0);
 
523
         add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
 
524
      }
 
525
 
 
526
      if (stencil) {
 
527
         assert(fb->Visual.stencilBits > 0);
 
528
         add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
 
529
      }
 
530
   }
 
531
 
 
532
   if (accum) {
 
533
      assert(fb->Visual.accumRedBits > 0);
 
534
      assert(fb->Visual.accumGreenBits > 0);
 
535
      assert(fb->Visual.accumBlueBits > 0);
 
536
      add_accum_renderbuffer(NULL, fb,
 
537
                             fb->Visual.accumRedBits,
 
538
                             fb->Visual.accumGreenBits,
 
539
                             fb->Visual.accumBlueBits,
 
540
                             fb->Visual.accumAlphaBits);
 
541
   }
 
542
 
 
543
   if (aux) {
 
544
      assert(fb->Visual.numAuxBuffers > 0);
 
545
      add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
 
546
                            fb->Visual.numAuxBuffers);
 
547
   }
 
548
 
 
549
#if 0
 
550
   if (multisample) {
 
551
      /* maybe someday */
 
552
   }
 
553
#endif
 
554
}
 
555
 
 
556
 
 
557
 
 
558
static void
 
559
map_attachment(struct gl_context *ctx,
 
560
                 struct gl_framebuffer *fb,
 
561
                 gl_buffer_index buffer)
 
562
{
 
563
   struct gl_texture_object *texObj = fb->Attachment[buffer].Texture;
 
564
   struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer;
 
565
   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
 
566
 
 
567
   if (texObj) {
 
568
      /* map texture image (render to texture) */
 
569
      const GLuint level = fb->Attachment[buffer].TextureLevel;
 
570
      const GLuint face = fb->Attachment[buffer].CubeMapFace;
 
571
      const GLuint slice = fb->Attachment[buffer].Zoffset;
 
572
      struct gl_texture_image *texImage = texObj->Image[face][level];
 
573
      if (texImage) {
 
574
         ctx->Driver.MapTextureImage(ctx, texImage, slice,
 
575
                                     0, 0, texImage->Width, texImage->Height,
 
576
                                     GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
 
577
                                     &srb->Map, &srb->RowStride);
 
578
      }
 
579
   }
 
580
   else if (rb) {
 
581
      /* Map ordinary renderbuffer */
 
582
      ctx->Driver.MapRenderbuffer(ctx, rb,
 
583
                                  0, 0, rb->Width, rb->Height,
 
584
                                  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
 
585
                                  &srb->Map, &srb->RowStride);
 
586
   }
 
587
 
 
588
   assert(srb->Map);
 
589
}
 
590
 
 
591
 
 
592
static void
 
593
unmap_attachment(struct gl_context *ctx,
 
594
                   struct gl_framebuffer *fb,
 
595
                   gl_buffer_index buffer)
 
596
{
 
597
   struct gl_texture_object *texObj = fb->Attachment[buffer].Texture;
 
598
   struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer;
 
599
   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
 
600
 
 
601
   if (texObj) {
 
602
      /* unmap texture image (render to texture) */
 
603
      const GLuint level = fb->Attachment[buffer].TextureLevel;
 
604
      const GLuint face = fb->Attachment[buffer].CubeMapFace;
 
605
      const GLuint slice = fb->Attachment[buffer].Zoffset;
 
606
      struct gl_texture_image *texImage = texObj->Image[face][level];
 
607
      if (texImage) {
 
608
         ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
 
609
      }
 
610
   }
 
611
   else if (rb) {
 
612
      /* unmap ordinary renderbuffer */
 
613
      ctx->Driver.UnmapRenderbuffer(ctx, rb);
 
614
   }
 
615
 
 
616
   srb->Map = NULL;
 
617
}
 
618
 
 
619
 
 
620
/**
 
621
 * Map the renderbuffers we'll use for tri/line/point rendering.
 
622
 */
 
623
void
 
624
_swrast_map_renderbuffers(struct gl_context *ctx)
 
625
{
 
626
   struct gl_framebuffer *fb = ctx->DrawBuffer;
 
627
   struct gl_renderbuffer *depthRb, *stencilRb;
 
628
   GLuint buf;
 
629
 
 
630
   depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
 
631
   if (depthRb) {
 
632
      /* map depth buffer */
 
633
      map_attachment(ctx, fb, BUFFER_DEPTH);
 
634
   }
 
635
 
 
636
   stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
 
637
   if (stencilRb && stencilRb != depthRb) {
 
638
      /* map stencil buffer */
 
639
      map_attachment(ctx, fb, BUFFER_STENCIL);
 
640
   }
 
641
 
 
642
   for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
 
643
      map_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]);
 
644
   }
 
645
}
 
646
 
 
647
 
 
648
/**
 
649
 * Unmap renderbuffers after rendering.
 
650
 */
 
651
void
 
652
_swrast_unmap_renderbuffers(struct gl_context *ctx)
 
653
{
 
654
   struct gl_framebuffer *fb = ctx->DrawBuffer;
 
655
   struct gl_renderbuffer *depthRb, *stencilRb;
 
656
   GLuint buf;
 
657
 
 
658
   depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
 
659
   if (depthRb) {
 
660
      /* map depth buffer */
 
661
      unmap_attachment(ctx, fb, BUFFER_DEPTH);
 
662
   }
 
663
 
 
664
   stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
 
665
   if (stencilRb && stencilRb != depthRb) {
 
666
      /* map stencil buffer */
 
667
      unmap_attachment(ctx, fb, BUFFER_STENCIL);
 
668
   }
 
669
 
 
670
   for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
 
671
      unmap_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]);
 
672
   }
 
673
}