~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i915tex/intel_fbo.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
 
4
 * All Rights Reserved.
 
5
 * 
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * copy of this software and associated documentation files (the
 
8
 * "Software"), to deal in the Software without restriction, including
 
9
 * without limitation the rights to use, copy, modify, merge, publish,
 
10
 * distribute, sub license, and/or sell copies of the Software, and to
 
11
 * permit persons to whom the Software is furnished to do so, subject to
 
12
 * the following conditions:
 
13
 * 
 
14
 * The above copyright notice and this permission notice (including the
 
15
 * next paragraph) shall be included in all copies or substantial portions
 
16
 * of the Software.
 
17
 * 
 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
21
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 * 
 
26
 **************************************************************************/
 
27
 
 
28
 
 
29
#include "imports.h"
 
30
#include "mtypes.h"
 
31
#include "fbobject.h"
 
32
#include "framebuffer.h"
 
33
#include "renderbuffer.h"
 
34
#include "context.h"
 
35
#include "texformat.h"
 
36
#include "texrender.h"
 
37
 
 
38
#include "intel_context.h"
 
39
#include "intel_buffers.h"
 
40
#include "intel_depthstencil.h"
 
41
#include "intel_fbo.h"
 
42
#include "intel_mipmap_tree.h"
 
43
#include "intel_regions.h"
 
44
#include "intel_span.h"
 
45
 
 
46
 
 
47
#define FILE_DEBUG_FLAG DEBUG_FBO
 
48
 
 
49
#define INTEL_RB_CLASS 0x12345678
 
50
 
 
51
 
 
52
/* XXX FBO: move this to intel_context.h (inlined) */
 
53
/**
 
54
 * Return a gl_renderbuffer ptr casted to intel_renderbuffer.
 
55
 * NULL will be returned if the rb isn't really an intel_renderbuffer.
 
56
 * This is determiend by checking the ClassID.
 
57
 */
 
58
struct intel_renderbuffer *
 
59
intel_renderbuffer(struct gl_renderbuffer *rb)
 
60
{
 
61
   struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
 
62
   if (irb && irb->Base.ClassID == INTEL_RB_CLASS) {
 
63
      /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/
 
64
      return irb;
 
65
   }
 
66
   else
 
67
      return NULL;
 
68
}
 
69
 
 
70
 
 
71
struct intel_renderbuffer *
 
72
intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex)
 
73
{
 
74
   return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
 
75
}
 
76
 
 
77
 
 
78
struct intel_region *
 
79
intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
 
80
{
 
81
   struct intel_renderbuffer *irb
 
82
      = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
 
83
   if (irb)
 
84
      return irb->region;
 
85
   else
 
86
      return NULL;
 
87
}
 
88
 
 
89
 
 
90
 
 
91
/**
 
92
 * Create a new framebuffer object.
 
93
 */
 
94
static struct gl_framebuffer *
 
95
intel_new_framebuffer(GLcontext * ctx, GLuint name)
 
96
{
 
97
   /* there's no intel_framebuffer at this time, just use Mesa's class */
 
98
   return _mesa_new_framebuffer(ctx, name);
 
99
}
 
100
 
 
101
 
 
102
static void
 
103
intel_delete_renderbuffer(struct gl_renderbuffer *rb)
 
104
{
 
105
   GET_CURRENT_CONTEXT(ctx);
 
106
   struct intel_context *intel = intel_context(ctx);
 
107
   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
108
 
 
109
   ASSERT(irb);
 
110
 
 
111
   if (irb->PairedStencil || irb->PairedDepth) {
 
112
      intel_unpair_depth_stencil(ctx, irb);
 
113
   }
 
114
 
 
115
   if (intel && irb->region) {
 
116
      intel_region_release(&irb->region);
 
117
   }
 
118
 
 
119
   _mesa_free(irb);
 
120
}
 
121
 
 
122
 
 
123
 
 
124
/**
 
125
 * Return a pointer to a specific pixel in a renderbuffer.
 
126
 */
 
127
static void *
 
128
intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb,
 
129
                  GLint x, GLint y)
 
130
{
 
131
   /* By returning NULL we force all software rendering to go through
 
132
    * the span routines.
 
133
    */
 
134
   return NULL;
 
135
}
 
136
 
 
137
 
 
138
 
 
139
/**
 
140
 * Called via glRenderbufferStorageEXT() to set the format and allocate
 
141
 * storage for a user-created renderbuffer.
 
142
 */
 
143
static GLboolean
 
144
intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 
145
                                 GLenum internalFormat,
 
146
                                 GLuint width, GLuint height)
 
147
{
 
148
   struct intel_context *intel = intel_context(ctx);
 
149
   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
150
   GLboolean softwareBuffer = GL_FALSE;
 
151
   int cpp;
 
152
 
 
153
   ASSERT(rb->Name != 0);
 
154
 
 
155
   switch (internalFormat) {
 
156
   case GL_R3_G3_B2:
 
157
   case GL_RGB4:
 
158
   case GL_RGB5:
 
159
      rb->_ActualFormat = GL_RGB5;
 
160
      rb->DataType = GL_UNSIGNED_BYTE;
 
161
      rb->RedBits = 5;
 
162
      rb->GreenBits = 6;
 
163
      rb->BlueBits = 5;
 
164
      cpp = 2;
 
165
      break;
 
166
   case GL_RGB:
 
167
   case GL_RGB8:
 
168
   case GL_RGB10:
 
169
   case GL_RGB12:
 
170
   case GL_RGB16:
 
171
   case GL_RGBA:
 
172
   case GL_RGBA2:
 
173
   case GL_RGBA4:
 
174
   case GL_RGB5_A1:
 
175
   case GL_RGBA8:
 
176
   case GL_RGB10_A2:
 
177
   case GL_RGBA12:
 
178
   case GL_RGBA16:
 
179
      rb->_ActualFormat = GL_RGBA8;
 
180
      rb->DataType = GL_UNSIGNED_BYTE;
 
181
      rb->RedBits = 8;
 
182
      rb->GreenBits = 8;
 
183
      rb->BlueBits = 8;
 
184
      rb->AlphaBits = 8;
 
185
      cpp = 4;
 
186
      break;
 
187
   case GL_STENCIL_INDEX:
 
188
   case GL_STENCIL_INDEX1_EXT:
 
189
   case GL_STENCIL_INDEX4_EXT:
 
190
   case GL_STENCIL_INDEX8_EXT:
 
191
   case GL_STENCIL_INDEX16_EXT:
 
192
      /* alloc a depth+stencil buffer */
 
193
      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
 
194
      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
 
195
      rb->StencilBits = 8;
 
196
      cpp = 4;
 
197
      break;
 
198
   case GL_DEPTH_COMPONENT16:
 
199
      rb->_ActualFormat = GL_DEPTH_COMPONENT16;
 
200
      rb->DataType = GL_UNSIGNED_SHORT;
 
201
      rb->DepthBits = 16;
 
202
      cpp = 2;
 
203
      break;
 
204
   case GL_DEPTH_COMPONENT:
 
205
   case GL_DEPTH_COMPONENT24:
 
206
   case GL_DEPTH_COMPONENT32:
 
207
      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
 
208
      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
 
209
      rb->DepthBits = 24;
 
210
      cpp = 4;
 
211
      break;
 
212
   case GL_DEPTH_STENCIL_EXT:
 
213
   case GL_DEPTH24_STENCIL8_EXT:
 
214
      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
 
215
      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
 
216
      rb->DepthBits = 24;
 
217
      rb->StencilBits = 8;
 
218
      cpp = 4;
 
219
      break;
 
220
   default:
 
221
      _mesa_problem(ctx,
 
222
                    "Unexpected format in intel_alloc_renderbuffer_storage");
 
223
      return GL_FALSE;
 
224
   }
 
225
 
 
226
   intelFlush(ctx);
 
227
 
 
228
   /* free old region */
 
229
   if (irb->region) {
 
230
      intel_region_release(&irb->region);
 
231
   }
 
232
 
 
233
   /* allocate new memory region/renderbuffer */
 
234
   if (softwareBuffer) {
 
235
      return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat,
 
236
                                             width, height);
 
237
   }
 
238
   else {
 
239
      /* Choose a pitch to match hardware requirements:
 
240
       */
 
241
      GLuint pitch = ((cpp * width + 63) & ~63) / cpp;
 
242
 
 
243
      /* alloc hardware renderbuffer */
 
244
      DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width,
 
245
          height, pitch);
 
246
 
 
247
      irb->region = intel_region_alloc(intel->intelScreen, cpp, pitch, height);
 
248
      if (!irb->region)
 
249
         return GL_FALSE;       /* out of memory? */
 
250
 
 
251
      ASSERT(irb->region->buffer);
 
252
 
 
253
      rb->Width = width;
 
254
      rb->Height = height;
 
255
 
 
256
      /* This sets the Get/PutRow/Value functions */
 
257
      intel_set_span_functions(&irb->Base);
 
258
 
 
259
      return GL_TRUE;
 
260
   }
 
261
}
 
262
 
 
263
 
 
264
 
 
265
/**
 
266
 * Called for each hardware renderbuffer when a _window_ is resized.
 
267
 * Just update fields.
 
268
 * Not used for user-created renderbuffers!
 
269
 */
 
270
static GLboolean
 
271
intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 
272
                           GLenum internalFormat, GLuint width, GLuint height)
 
273
{
 
274
   ASSERT(rb->Name == 0);
 
275
   rb->Width = width;
 
276
   rb->Height = height;
 
277
   rb->_ActualFormat = internalFormat;
 
278
   return GL_TRUE;
 
279
}
 
280
 
 
281
 
 
282
static GLboolean
 
283
intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 
284
                        GLenum internalFormat, GLuint width, GLuint height)
 
285
{
 
286
   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
 
287
   return GL_FALSE;
 
288
}
 
289
 
 
290
 
 
291
 
 
292
/**
 
293
 * Create a new intel_renderbuffer which corresponds to an on-screen window,
 
294
 * not a user-created renderbuffer.
 
295
 * \param width  the screen width
 
296
 * \param height  the screen height
 
297
 */
 
298
struct intel_renderbuffer *
 
299
intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height,
 
300
                          int offset, int pitch, int cpp, void *map)
 
301
{
 
302
   GET_CURRENT_CONTEXT(ctx);
 
303
 
 
304
   struct intel_renderbuffer *irb;
 
305
   const GLuint name = 0;
 
306
 
 
307
   irb = CALLOC_STRUCT(intel_renderbuffer);
 
308
   if (!irb) {
 
309
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
 
310
      return NULL;
 
311
   }
 
312
 
 
313
   _mesa_init_renderbuffer(&irb->Base, name);
 
314
   irb->Base.ClassID = INTEL_RB_CLASS;
 
315
 
 
316
   switch (intFormat) {
 
317
   case GL_RGB5:
 
318
      irb->Base._ActualFormat = GL_RGB5;
 
319
      irb->Base._BaseFormat = GL_RGBA;
 
320
      irb->Base.RedBits = 5;
 
321
      irb->Base.GreenBits = 6;
 
322
      irb->Base.BlueBits = 5;
 
323
      irb->Base.DataType = GL_UNSIGNED_BYTE;
 
324
      cpp = 2;
 
325
      break;
 
326
   case GL_RGBA8:
 
327
      irb->Base._ActualFormat = GL_RGBA8;
 
328
      irb->Base._BaseFormat = GL_RGBA;
 
329
      irb->Base.RedBits = 8;
 
330
      irb->Base.GreenBits = 8;
 
331
      irb->Base.BlueBits = 8;
 
332
      irb->Base.AlphaBits = 8;
 
333
      irb->Base.DataType = GL_UNSIGNED_BYTE;
 
334
      cpp = 4;
 
335
      break;
 
336
   case GL_STENCIL_INDEX8_EXT:
 
337
      irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT;
 
338
      irb->Base._BaseFormat = GL_STENCIL_INDEX;
 
339
      irb->Base.StencilBits = 8;
 
340
      irb->Base.DataType = GL_UNSIGNED_BYTE;
 
341
      cpp = 1;
 
342
      break;
 
343
   case GL_DEPTH_COMPONENT16:
 
344
      irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;
 
345
      irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
 
346
      irb->Base.DepthBits = 16;
 
347
      irb->Base.DataType = GL_UNSIGNED_SHORT;
 
348
      cpp = 2;
 
349
      break;
 
350
   case GL_DEPTH_COMPONENT24:
 
351
      irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
 
352
      irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
 
353
      irb->Base.DepthBits = 24;
 
354
      irb->Base.DataType = GL_UNSIGNED_INT;
 
355
      cpp = 4;
 
356
      break;
 
357
   case GL_DEPTH24_STENCIL8_EXT:
 
358
      irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
 
359
      irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
 
360
      irb->Base.DepthBits = 24;
 
361
      irb->Base.StencilBits = 8;
 
362
      irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
 
363
      cpp = 4;
 
364
      break;
 
365
   default:
 
366
      _mesa_problem(NULL,
 
367
                    "Unexpected intFormat in intel_create_renderbuffer");
 
368
      return NULL;
 
369
   }
 
370
 
 
371
   irb->Base.InternalFormat = intFormat;
 
372
 
 
373
   /* intel-specific methods */
 
374
   irb->Base.Delete = intel_delete_renderbuffer;
 
375
   irb->Base.AllocStorage = intel_alloc_window_storage;
 
376
   irb->Base.GetPointer = intel_get_pointer;
 
377
   /* This sets the Get/PutRow/Value functions */
 
378
   intel_set_span_functions(&irb->Base);
 
379
 
 
380
   irb->pfMap = map;
 
381
   irb->pfPitch = pitch / cpp;  /* in pixels */
 
382
 
 
383
#if 00
 
384
   irb->region = intel_region_create_static(intel,
 
385
                                            DRM_MM_TT,
 
386
                                            offset, map, cpp, width, height);
 
387
#endif
 
388
 
 
389
   return irb;
 
390
}
 
391
 
 
392
 
 
393
/**
 
394
 * Create a new renderbuffer object.
 
395
 * Typically called via glBindRenderbufferEXT().
 
396
 */
 
397
static struct gl_renderbuffer *
 
398
intel_new_renderbuffer(GLcontext * ctx, GLuint name)
 
399
{
 
400
   /*struct intel_context *intel = intel_context(ctx); */
 
401
   struct intel_renderbuffer *irb;
 
402
 
 
403
   irb = CALLOC_STRUCT(intel_renderbuffer);
 
404
   if (!irb) {
 
405
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
 
406
      return NULL;
 
407
   }
 
408
 
 
409
   _mesa_init_renderbuffer(&irb->Base, name);
 
410
   irb->Base.ClassID = INTEL_RB_CLASS;
 
411
 
 
412
   /* intel-specific methods */
 
413
   irb->Base.Delete = intel_delete_renderbuffer;
 
414
   irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
 
415
   irb->Base.GetPointer = intel_get_pointer;
 
416
   /* span routines set in alloc_storage function */
 
417
 
 
418
   return &irb->Base;
 
419
}
 
420
 
 
421
 
 
422
/**
 
423
 * Called via glBindFramebufferEXT().
 
424
 */
 
425
static void
 
426
intel_bind_framebuffer(GLcontext * ctx, GLenum target,
 
427
                       struct gl_framebuffer *fb)
 
428
{
 
429
   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
 
430
      intel_draw_buffer(ctx, fb);
 
431
      /* Integer depth range depends on depth buffer bits */
 
432
      ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far);
 
433
   }
 
434
   else {
 
435
      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
 
436
   }
 
437
}
 
438
 
 
439
 
 
440
/**
 
441
 * Called via glFramebufferRenderbufferEXT().
 
442
 */
 
443
static void
 
444
intel_framebuffer_renderbuffer(GLcontext * ctx,
 
445
                               struct gl_framebuffer *fb,
 
446
                               GLenum attachment, struct gl_renderbuffer *rb)
 
447
{
 
448
   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
 
449
 
 
450
   intelFlush(ctx);
 
451
 
 
452
   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
 
453
   intel_draw_buffer(ctx, fb);
 
454
}
 
455
 
 
456
 
 
457
/**
 
458
 * When glFramebufferTexture[123]D is called this function sets up the
 
459
 * gl_renderbuffer wrapp around the texture image.
 
460
 * This will have the region info needed for hardware rendering.
 
461
 */
 
462
static struct intel_renderbuffer *
 
463
intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)
 
464
{
 
465
   const GLuint name = ~0;      /* not significant, but distinct for debugging */
 
466
   struct intel_renderbuffer *irb;
 
467
 
 
468
   /* make an intel_renderbuffer to wrap the texture image */
 
469
   irb = CALLOC_STRUCT(intel_renderbuffer);
 
470
   if (!irb) {
 
471
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
 
472
      return NULL;
 
473
   }
 
474
 
 
475
   _mesa_init_renderbuffer(&irb->Base, name);
 
476
   irb->Base.ClassID = INTEL_RB_CLASS;
 
477
 
 
478
   if (texImage->TexFormat == &_mesa_texformat_argb8888) {
 
479
      irb->Base._ActualFormat = GL_RGBA8;
 
480
      irb->Base._BaseFormat = GL_RGBA;
 
481
      DBG("Render to RGBA8 texture OK\n");
 
482
   }
 
483
   else if (texImage->TexFormat == &_mesa_texformat_rgb565) {
 
484
      irb->Base._ActualFormat = GL_RGB5;
 
485
      irb->Base._BaseFormat = GL_RGB;
 
486
      DBG("Render to RGB5 texture OK\n");
 
487
   }
 
488
   else if (texImage->TexFormat == &_mesa_texformat_z16) {
 
489
      irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;
 
490
      irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
 
491
      DBG("Render to DEPTH16 texture OK\n");
 
492
   }
 
493
   else {
 
494
      DBG("Render to texture BAD FORMAT %d\n",
 
495
          texImage->TexFormat->MesaFormat);
 
496
      _mesa_free(irb);
 
497
      return NULL;
 
498
   }
 
499
 
 
500
   irb->Base.InternalFormat = irb->Base._ActualFormat;
 
501
   irb->Base.Width = texImage->Width;
 
502
   irb->Base.Height = texImage->Height;
 
503
   irb->Base.DataType = GL_UNSIGNED_BYTE;       /* FBO XXX fix */
 
504
   irb->Base.RedBits = texImage->TexFormat->RedBits;
 
505
   irb->Base.GreenBits = texImage->TexFormat->GreenBits;
 
506
   irb->Base.BlueBits = texImage->TexFormat->BlueBits;
 
507
   irb->Base.AlphaBits = texImage->TexFormat->AlphaBits;
 
508
   irb->Base.DepthBits = texImage->TexFormat->DepthBits;
 
509
 
 
510
   irb->Base.Delete = intel_delete_renderbuffer;
 
511
   irb->Base.AllocStorage = intel_nop_alloc_storage;
 
512
   intel_set_span_functions(&irb->Base);
 
513
 
 
514
   irb->RenderToTexture = GL_TRUE;
 
515
 
 
516
   return irb;
 
517
}
 
518
 
 
519
 
 
520
/**
 
521
 * Called by glFramebufferTexture[123]DEXT() (and other places) to
 
522
 * prepare for rendering into texture memory.  This might be called
 
523
 * many times to choose different texture levels, cube faces, etc
 
524
 * before intel_finish_render_texture() is ever called.
 
525
 */
 
526
static void
 
527
intel_render_texture(GLcontext * ctx,
 
528
                     struct gl_framebuffer *fb,
 
529
                     struct gl_renderbuffer_attachment *att)
 
530
{
 
531
   struct gl_texture_image *newImage
 
532
      = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
 
533
   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
 
534
   struct intel_texture_image *intel_image;
 
535
   GLuint imageOffset;
 
536
 
 
537
   (void) fb;
 
538
 
 
539
   ASSERT(newImage);
 
540
 
 
541
   if (!irb) {
 
542
      irb = intel_wrap_texture(ctx, newImage);
 
543
      if (irb) {
 
544
         /* bind the wrapper to the attachment point */
 
545
         att->Renderbuffer = &irb->Base;
 
546
      }
 
547
      else {
 
548
         /* fallback to software rendering */
 
549
         _mesa_render_texture(ctx, fb, att);
 
550
         return;
 
551
      }
 
552
   }
 
553
 
 
554
   DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
 
555
       _glthread_GetID(),
 
556
       att->Texture->Name, newImage->Width, newImage->Height,
 
557
       irb->Base.RefCount);
 
558
 
 
559
   /* point the renderbufer's region to the texture image region */
 
560
   intel_image = intel_texture_image(newImage);
 
561
   if (irb->region != intel_image->mt->region) {
 
562
      if (irb->region)
 
563
         intel_region_release(&irb->region);
 
564
      intel_region_reference(&irb->region, intel_image->mt->region);
 
565
   }
 
566
 
 
567
   /* compute offset of the particular 2D image within the texture region */
 
568
   imageOffset = intel_miptree_image_offset(intel_image->mt,
 
569
                                            att->CubeMapFace,
 
570
                                            att->TextureLevel);
 
571
 
 
572
   if (att->Texture->Target == GL_TEXTURE_3D) {
 
573
      const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt,
 
574
                                                          att->TextureLevel);
 
575
      imageOffset += offsets[att->Zoffset];
 
576
   }
 
577
 
 
578
   /* store that offset in the region */
 
579
   intel_image->mt->region->draw_offset = imageOffset;
 
580
 
 
581
   /* update drawing region, etc */
 
582
   intel_draw_buffer(ctx, fb);
 
583
}
 
584
 
 
585
 
 
586
/**
 
587
 * Called by Mesa when rendering to a texture is done.
 
588
 */
 
589
static void
 
590
intel_finish_render_texture(GLcontext * ctx,
 
591
                            struct gl_renderbuffer_attachment *att)
 
592
{
 
593
   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
 
594
 
 
595
   DBG("End render texture (tid %x) tex %u\n", _glthread_GetID(), att->Texture->Name);
 
596
 
 
597
   if (irb) {
 
598
      /* just release the region */
 
599
      intel_region_release(&irb->region);
 
600
   }
 
601
   else if (att->Renderbuffer) {
 
602
      /* software fallback */
 
603
      _mesa_finish_render_texture(ctx, att);
 
604
      /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */
 
605
   }
 
606
}
 
607
 
 
608
 
 
609
/**
 
610
 * Do one-time context initializations related to GL_EXT_framebuffer_object.
 
611
 * Hook in device driver functions.
 
612
 */
 
613
void
 
614
intel_fbo_init(struct intel_context *intel)
 
615
{
 
616
   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
 
617
   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
 
618
   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
 
619
   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
 
620
   intel->ctx.Driver.RenderTexture = intel_render_texture;
 
621
   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
 
622
}