[i965] multiple rendering target support
authorZou Nan hai <nanhai.zou@intel.com>
Thu, 13 Mar 2008 06:46:38 +0000 (14:46 +0800)
committerZou Nan hai <nanhai.zou@intel.com>
Thu, 13 Mar 2008 06:46:38 +0000 (14:46 +0800)
15 files changed:
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_fallback.c
src/mesa/drivers/dri/i965/brw_metaops.c
src/mesa/drivers/dri/i965/brw_vtbl.c
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_fp.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c
src/mesa/drivers/dri/i965/brw_wm_pass0.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_buffers.c
src/mesa/drivers/dri/intel/intel_context.h

index 9bc868b..1f4bc91 100644 (file)
@@ -609,11 +609,12 @@ i830_state_draw_region(struct intel_context *intel,
 
 static void
 i830_set_draw_region(struct intel_context *intel,
-                     struct intel_region *color_region,
-                     struct intel_region *depth_region)
+                     struct intel_region *color_regions[],
+                     struct intel_region *depth_region,
+                    GLuint num_regions)
 {
    struct i830_context *i830 = i830_context(&intel->ctx);
-   i830_state_draw_region(intel, &i830->state, color_region, depth_region);
+   i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region);
 }
 
 #if 0
index c856a86..40c5de2 100644 (file)
@@ -532,11 +532,12 @@ i915_state_draw_region(struct intel_context *intel,
 
 static void
 i915_set_draw_region(struct intel_context *intel,
-                     struct intel_region *color_region,
-                     struct intel_region *depth_region)
+                     struct intel_region *color_regions[],
+                     struct intel_region *depth_region,
+                    GLuint num_regions)
 {
    struct i915_context *i915 = i915_context(&intel->ctx);
-   i915_state_draw_region(intel, &i915->state, color_region, depth_region);
+   i915_state_draw_region(intel, &i915->state, color_regions[0], depth_region);
 }
 
 
index 49e739b..4e6b471 100644 (file)
@@ -240,7 +240,7 @@ struct brw_vs_ouput_sizes {
 
 
 #define BRW_MAX_TEX_UNIT 8
-#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1
+#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + MAX_DRAW_BUFFERS
 
 enum brw_cache_id {
    BRW_CC_VP,
@@ -425,8 +425,8 @@ struct brw_context
       struct brw_tracked_state **atoms;
       GLuint nr_atoms;
 
-
-      struct intel_region *draw_region;
+      GLuint nr_draw_regions;
+      struct intel_region *draw_regions[MAX_DRAW_BUFFERS];
       struct intel_region *depth_region;
    } state;
 
@@ -461,6 +461,7 @@ struct brw_context
       struct gl_buffer_object *vbo;
 
       struct intel_region *saved_draw_region;
+      GLuint saved_nr_draw_regions;
       struct intel_region *saved_depth_region;
 
       GLuint restore_draw_buffers[MAX_DRAW_BUFFERS];
index 58aeeb4..ce0df03 100644 (file)
@@ -57,16 +57,6 @@ static GLboolean do_check_fallback(struct brw_context *brw)
       return GL_TRUE;
    }
 
-   /* _NEW_BUFFERS
-    */
-   /* We can only handle a single draw buffer at the moment, and only as the
-    * first color buffer.
-    */
-   if (fb->_NumColorDrawBuffers > 1) {
-      DBG("FALLBACK: multiple color draw buffers\n");
-      return GL_TRUE;
-   }
-
    /* _NEW_RENDERMODE
     *
     * XXX: need to save/restore RenderMode in metaops state, or
index 7b34f0f..252a899 100644 (file)
@@ -362,11 +362,13 @@ static void meta_draw_region( struct intel_context *intel,
    struct brw_context *brw = brw_context(&intel->ctx);
 
    if (!brw->metaops.saved_draw_region) {
-      brw->metaops.saved_draw_region = brw->state.draw_region;
+      brw->metaops.saved_draw_region = brw->state.draw_regions[0];
+      brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions;
       brw->metaops.saved_depth_region = brw->state.depth_region;
    }
 
-   brw->state.draw_region = draw_region;
+   brw->state.draw_regions[0] = draw_region;
+   brw->state.nr_draw_regions = 1;
    brw->state.depth_region = depth_region;
 
    if (intel->frame_buffer_texobj != NULL)
@@ -509,7 +511,8 @@ static void install_meta_state( struct intel_context *intel )
 
    /* This works without adjusting refcounts.  Fix later? 
     */
-   brw->metaops.saved_draw_region = brw->state.draw_region;
+   brw->metaops.saved_draw_region = brw->state.draw_regions[0];
+   brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions;
    brw->metaops.saved_depth_region = brw->state.depth_region;
    brw->metaops.active = 1;
    
@@ -532,7 +535,8 @@ static void leave_meta_state( struct intel_context *intel )
 
    ctx->FragmentProgram.Current = brw->metaops.restore_fp;
 
-   brw->state.draw_region = brw->metaops.saved_draw_region;
+   brw->state.draw_regions[0] = brw->metaops.saved_draw_region;
+   brw->state.nr_draw_regions = brw->metaops.saved_nr_draw_regions;
    brw->state.depth_region = brw->metaops.saved_depth_region;
    brw->metaops.saved_draw_region = NULL;
    brw->metaops.saved_depth_region = NULL;
index cdbbe7b..31e96a2 100644 (file)
@@ -70,18 +70,21 @@ static void brw_destroy_context( struct intel_context *intel )
 /* called from intelDrawBuffer()
  */
 static void brw_set_draw_region( struct intel_context *intel, 
-                                 struct intel_region *draw_region,
-                                 struct intel_region *depth_region)
+                                 struct intel_region *draw_regions[],
+                                 struct intel_region *depth_region,
+                               GLuint num_regions)
 {
    struct brw_context *brw = brw_context(&intel->ctx);
-
+   int i;
    if (brw->state.depth_region != depth_region)
       brw->state.dirty.brw |= BRW_NEW_DEPTH_BUFFER;
-
-   intel_region_release(&brw->state.draw_region);
+   for (i = 0; i < brw->state.nr_draw_regions; i++)
+       intel_region_release(&brw->state.draw_regions[i]);
    intel_region_release(&brw->state.depth_region);
-   intel_region_reference(&brw->state.draw_region, draw_region);
+   for (i = 0; i < num_regions; i++)
+       intel_region_reference(&brw->state.draw_regions[i], draw_regions[i]);
    intel_region_reference(&brw->state.depth_region, depth_region);
+   brw->state.nr_draw_regions = num_regions;
 }
 
 
index 4766569..abdc92b 100644 (file)
@@ -139,6 +139,7 @@ static void do_wm_prog( struct brw_context *brw,
    c->fp = fp;
    c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
 
+    brw_init_compile(brw, &c->func);
    if (brw_wm_is_glsl(&c->fp->program)) {
        brw_wm_glsl_emit(brw, c);
    } else {
@@ -160,10 +161,6 @@ static void do_wm_prog( struct brw_context *brw,
        */
        c->grf_limit = BRW_WM_MAX_GRF/2;
 
-       /* This is where we start emitting gen4 code:
-       */
-       brw_init_compile(brw, &c->func);
-
        brw_wm_pass2(c);
 
        c->prog_data.total_grf = c->max_wm_grf;
index 441fbd3..5ca2a63 100644 (file)
@@ -143,6 +143,8 @@ struct brw_wm_instruction {
    GLuint writemask:4;
    GLuint tex_unit:4;   /* texture unit for TEX, TXD, TXP instructions */
    GLuint tex_idx:3;    /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */
+   GLuint eot:1;       /* End of thread indicator for FB_WRITE*/
+   GLuint target:10;    /* target binding table index for FB_WRITE*/
 };
 
 
index df51f73..4c0bd67 100644 (file)
@@ -696,7 +696,7 @@ static void emit_tex( struct brw_wm_compile *c,
              retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
              1,
              retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
-             inst->tex_unit + 1, /* surface */
+             inst->tex_unit + MAX_DRAW_BUFFERS, /* surface */
              inst->tex_unit,     /* sampler */
              inst->writemask,
              (shadow ? 
@@ -749,7 +749,7 @@ static void emit_txb( struct brw_wm_compile *c,
              retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
              1,
              retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
-             inst->tex_unit + 1, /* surface */
+             inst->tex_unit + MAX_DRAW_BUFFERS, /* surface */
              inst->tex_unit,     /* sampler */
              inst->writemask,
              BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
@@ -822,7 +822,9 @@ static void emit_kil( struct brw_wm_compile *c,
 
 static void fire_fb_write( struct brw_wm_compile *c,
                           GLuint base_reg,
-                          GLuint nr )
+                          GLuint nr,
+                          GLuint target,
+                          GLuint eot )
 {
    struct brw_compile *p = &c->func;
    
@@ -845,10 +847,10 @@ static void fire_fb_write( struct brw_wm_compile *c,
                retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW),
                base_reg,
                retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
-               0,              /* render surface always 0 */
+               target,         
                nr,
                0, 
-               1);
+               eot);
 }
 
 static void emit_aa( struct brw_wm_compile *c,
@@ -873,7 +875,9 @@ static void emit_aa( struct brw_wm_compile *c,
 static void emit_fb_write( struct brw_wm_compile *c,
                           struct brw_reg *arg0,
                           struct brw_reg *arg1,
-                          struct brw_reg *arg2)
+                          struct brw_reg *arg2,
+                          GLuint target,
+                          GLuint eot)
 {
    struct brw_compile *p = &c->func;
    GLuint nr = 2;
@@ -946,7 +950,7 @@ static void emit_fb_write( struct brw_wm_compile *c,
       if (c->key.aa_dest_stencil_reg)
         emit_aa(c, arg1, 2);
 
-      fire_fb_write(c, 0, nr);
+      fire_fb_write(c, 0, nr, target, eot);
    }
    else {
       struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
@@ -963,14 +967,14 @@ static void emit_fb_write( struct brw_wm_compile *c,
       jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
       {
         emit_aa(c, arg1, 2);
-        fire_fb_write(c, 0, nr);
+        fire_fb_write(c, 0, nr, target, eot);
         /* note - thread killed in subroutine */
       }
       brw_land_fwd_jump(p, jmp);
 
       /* ELSE: Shuffle up one register to fill in the hole left for AA:
        */
-      fire_fb_write(c, 1, nr-1);
+      fire_fb_write(c, 1, nr-1, target, eot);
    }
 }
 
@@ -1138,7 +1142,7 @@ void brw_wm_emit( struct brw_wm_compile *c )
         break;
 
       case WM_FB_WRITE:
-        emit_fb_write(c, args[0], args[1], args[2]);
+        emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot);
         break;
 
         /* Straightforward arithmetic:
index 77cb3b2..682b16d 100644 (file)
@@ -861,14 +861,28 @@ static void emit_fb_write( struct brw_wm_compile *c )
    struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
    struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
    struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR);
+   GLuint i;
 
-   emit_op(c,
-          WM_FB_WRITE,
-          dst_mask(dst_undef(),0),
-          0, 0, 0,
-          outcolor,
-          payload_r0_depth,
-          outdepth);
+   struct prog_instruction *inst;
+   struct brw_context *brw = c->func.brw;
+
+   /* inst->Sampler is not used by backend, 
+      use it for fb write target and eot */
+
+   inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
+           0, 0, 0, outcolor, payload_r0_depth, outdepth);
+   inst->Sampler = (brw->state.nr_draw_regions > 1 ? 0: 1)|(0<<1);
+
+   if (brw->state.nr_draw_regions > 1) {
+       for (i = 0 ; i < brw->state.nr_draw_regions; i++) {
+          outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
+          inst = emit_op(c,
+                  WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0,
+                  outcolor, payload_r0_depth, outdepth);
+          inst->Sampler = ((i == brw->state.nr_draw_regions - 1) ? 1: 0);
+          inst->Sampler |= (i<<1);
+       }
+   }
 }
 
 
index fd237ee..5852083 100644 (file)
@@ -274,10 +274,11 @@ static void emit_delta_xy(struct brw_wm_compile *c,
 
 static void fire_fb_write( struct brw_wm_compile *c,
                            GLuint base_reg,
-                           GLuint nr )
+                           GLuint nr,
+                           GLuint target,
+                           GLuint eot)
 {
     struct brw_compile *p = &c->func;
-
     /* Pass through control information:
      */
     /*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
@@ -294,10 +295,10 @@ static void fire_fb_write( struct brw_wm_compile *c,
            retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
            base_reg,
            retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
-           0,              /* render surface always 0 */
+           target,              
            nr,
            0,
-           1);
+           eot);
 }
 
 static void emit_fb_write(struct brw_wm_compile *c,
@@ -306,7 +307,8 @@ static void emit_fb_write(struct brw_wm_compile *c,
     struct brw_compile *p = &c->func;
     int nr = 2;
     int channel;
-    struct brw_reg src0;//, src1, src2, dst;
+    GLuint target, eot;
+    struct brw_reg src0;
 
     /* Reserve a space for AA - may not be needed:
      */
@@ -337,8 +339,9 @@ static void emit_fb_write(struct brw_wm_compile *c,
 
       nr += 2;
    }
-
-    fire_fb_write(c, 0, nr);
+    target = inst->Sampler >> 1;
+    eot = inst->Sampler & 1;
+    fire_fb_write(c, 0, nr, target, eot);
 }
 
 static void emit_pixel_w( struct brw_wm_compile *c,
@@ -1026,7 +1029,7 @@ static void emit_txb(struct brw_wm_compile *c,
            retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
            1,
            retype(payload_reg, BRW_REGISTER_TYPE_UW),
-           inst->TexSrcUnit + 1, /* surface */
+           inst->TexSrcUnit + MAX_DRAW_BUFFERS, /* surface */
            inst->TexSrcUnit,     /* sampler */
            inst->DstReg.WriteMask,
            BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
@@ -1088,7 +1091,7 @@ static void emit_tex(struct brw_wm_compile *c,
            retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
            1,
            retype(payload_reg, BRW_REGISTER_TYPE_UW),
-           inst->TexSrcUnit + 1, /* surface */
+           inst->TexSrcUnit + MAX_DRAW_BUFFERS, /* surface */
            inst->TexSrcUnit,     /* sampler */
            inst->DstReg.WriteMask,
            BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
@@ -1125,7 +1128,6 @@ static void post_wm_emit( struct brw_wm_compile *c )
 }
 
 static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
-
 {
 #define MAX_IFSN 32
 #define MAX_LOOP_DEPTH 32
@@ -1135,7 +1137,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
     struct brw_compile *p = &c->func;
     struct brw_indirect stack_index = brw_indirect(0, 0);
 
-    brw_init_compile(brw, &c->func);
     c->reg_index = 0;
     prealloc_reg(c);
     brw_set_compression_control(p, BRW_COMPRESSION_NONE);
index 1bfae5a..205a716 100644 (file)
@@ -348,6 +348,8 @@ static struct brw_wm_instruction *translate_insn( struct brw_wm_compile *c,
    out->saturate = (inst->SaturateMode != SATURATE_OFF);
    out->tex_unit = inst->TexSrcUnit;
    out->tex_idx = inst->TexSrcTarget;
+   out->eot = inst->Sampler & 1;
+   out->target = inst->Sampler>>1;
 
    /* Args:
     */
index f2ae210..d0f86b5 100644 (file)
@@ -226,13 +226,13 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
    key.depth = firstImage->Depth;
    key.tiled = intelObj->mt->region->tiled;
 
-   dri_bo_unreference(brw->wm.surf_bo[unit + 1]);
-   brw->wm.surf_bo[unit + 1] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
+   dri_bo_unreference(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]);
+   brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
                                                &key, sizeof(key),
                                                &key.bo, 1,
                                                NULL);
-   if (brw->wm.surf_bo[unit + 1] == NULL)
-      brw->wm.surf_bo[unit + 1] = brw_create_texture_surface(brw, &key);
+   if (brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] == NULL)
+      brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_create_texture_surface(brw, &key);
 }
 
 /**
@@ -242,7 +242,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
  */
 static void
 brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
-                         unsigned int unit)
+                         unsigned int unit, GLboolean cached)
 {
    dri_bo *region_bo = NULL;
 
@@ -254,8 +254,6 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
       GLboolean tiled, color_blend;
    } key;
 
-   memset(&key, 0, sizeof(key));
-
    if (region != NULL) {
       region_bo = region->buffer;
 
@@ -276,17 +274,19 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
       key.height = 1;
       key.cpp = 4;
    }
-
    memcpy(key.color_mask, brw->attribs.Color->ColorMask,
          sizeof(key.color_mask));
    key.color_blend = (!brw->attribs.Color->_LogicOpEnabled &&
                      brw->attribs.Color->BlendEnabled);
 
    dri_bo_unreference(brw->wm.surf_bo[unit]);
-   brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
-                                           &key, sizeof(key),
-                                           &region_bo, 1,
-                                           NULL);
+   brw->wm.surf_bo[unit] = NULL;
+   if (cached) 
+       brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
+              &key, sizeof(key),
+              &region_bo, 1,
+              NULL);
+
    if (brw->wm.surf_bo[unit] == NULL) {
       struct brw_surface_state surf;
 
@@ -312,11 +312,10 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
 
       /* Key size will never match key size for textures, so we're safe. */
       brw->wm.surf_bo[unit] = brw_upload_cache(&brw->cache, BRW_SS_SURFACE,
-                                              &key, sizeof(key),
+                                             &key, sizeof(key),
                                               &region_bo, 1,
                                               &surf, sizeof(surf),
                                               NULL, NULL);
-
       if (region_bo != NULL) {
         dri_emit_reloc(brw->wm.surf_bo[unit],
                        DRM_BO_FLAG_MEM_TT |
@@ -345,7 +344,7 @@ brw_wm_get_binding_table(struct brw_context *brw)
                              NULL);
 
    if (bind_bo == NULL) {
-      GLuint data_size = brw->wm.nr_surfaces * 4;
+      GLuint data_size = brw->wm.nr_surfaces * sizeof(GLuint);
       uint32_t *data = malloc(data_size);
       int i;
 
@@ -369,7 +368,7 @@ brw_wm_get_binding_table(struct brw_context *brw)
                           DRM_BO_FLAG_READ |
                           DRM_BO_FLAG_WRITE,
                           0,
-                          i * 4,
+                          i * sizeof(GLuint),
                           brw->wm.surf_bo[i]);
         }
       }
@@ -385,9 +384,14 @@ static void upload_wm_surfaces(struct brw_context *brw )
    GLcontext *ctx = &brw->intel.ctx;
    struct intel_context *intel = &brw->intel;
    GLuint i;
+   if (brw->state.nr_draw_regions  > 1) {
+       for (i = 0; i < brw->state.nr_draw_regions; i++) 
+          brw_update_region_surface(brw, brw->state.draw_regions[i], i, 
+               GL_FALSE);
+   }else
+       brw_update_region_surface(brw, brw->state.draw_regions[0], 0, GL_TRUE);
 
-   brw_update_region_surface(brw, brw->state.draw_region, 0);
-   brw->wm.nr_surfaces = 1;
+   brw->wm.nr_surfaces = MAX_DRAW_BUFFERS;
 
    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
       struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];
@@ -396,16 +400,16 @@ static void upload_wm_surfaces(struct brw_context *brw )
       if(texUnit->_ReallyEnabled &&
         texUnit->_Current == intel->frame_buffer_texobj)
       {
-        dri_bo_unreference(brw->wm.surf_bo[i+1]);
-        brw->wm.surf_bo[i+1] = brw->wm.surf_bo[0];
-        dri_bo_reference(brw->wm.surf_bo[i+1]);
-        brw->wm.nr_surfaces = i+2;
+        dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
+        brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = brw->wm.surf_bo[0];
+        dri_bo_reference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
+        brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;
       } else if (texUnit->_ReallyEnabled) {
         brw_update_texture_surface(ctx, i);
-        brw->wm.nr_surfaces = i+2;
+        brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;
       } else {
-        dri_bo_unreference(brw->wm.surf_bo[i+1]);
-        brw->wm.surf_bo[i+1] = NULL;
+        dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
+        brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = NULL;
       }
    }
 
index 5199f83..2a25f07 100644 (file)
@@ -300,6 +300,7 @@ intelWindowMoved(struct intel_context *intel)
       default:
          intelSetFrontClipRects(intel);
       }
+       
    }
 
    if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
@@ -894,7 +895,7 @@ void
 intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
 {
    struct intel_context *intel = intel_context(ctx);
-   struct intel_region *colorRegion, *depthRegion = NULL;
+   struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL;
    struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;
    int front = 0;               /* drawing to front color buffer? */
 
@@ -933,14 +934,24 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
    /*
     * How many color buffers are we drawing into?
     */
-   if (fb->_NumColorDrawBuffers != 1) {
-      /* writing to 0 or 2 or 4 color buffers */
-      /*_mesa_debug(ctx, "Software rendering\n");*/
+   if (fb->_NumColorDrawBuffers == 0) {
+      /* writing to 0  */
       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
-      colorRegion = NULL;
+      colorRegions[0] = NULL;
 
       if (fb->Name != 0)
         intelSetRenderbufferClipRects(intel);
+   } else if (fb->_NumColorDrawBuffers > 1) {
+       int i;
+       struct intel_renderbuffer *irb;
+       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
+
+       if (fb->Name != 0)
+           intelSetRenderbufferClipRects(intel);
+       for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
+           irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
+           colorRegions[i] = (irb && irb->region) ? irb->region : NULL;
+       }
    }
    else {
       /* draw to exactly one color buffer */
@@ -958,11 +969,11 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
         /* drawing to window system buffer */
         if (front) {
            intelSetFrontClipRects(intel);
-           colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
+           colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
         }
         else {
            intelSetBackClipRects(intel);
-           colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
+           colorRegions[0]= intel_get_rb_region(fb, BUFFER_BACK_LEFT);
         }
       }
       else {
@@ -970,7 +981,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
         struct intel_renderbuffer *irb;
         intelSetRenderbufferClipRects(intel);
         irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
-        colorRegion = (irb && irb->region) ? irb->region : NULL;
+        colorRegions[0] = (irb && irb->region) ? irb->region : NULL;
       }
    }
 
@@ -982,7 +993,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
    else
       ctx->NewState |= _NEW_POLYGON;
 
-   if (!colorRegion) {
+   if (!colorRegions[0]) {
       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
    }
    else {
@@ -1055,7 +1066,8 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
       ctx->NewState |= _NEW_DEPTH;
    }
 
-   intel->vtbl.set_draw_region(intel, colorRegion, depthRegion);
+   intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, 
+       fb->_NumColorDrawBuffers);
 
    /* update viewport since it depends on window size */
    if (ctx->Driver.Viewport) {
index 809cb6e..1348b0a 100644 (file)
@@ -94,8 +94,9 @@ struct intel_context
       void (*render_start) (struct intel_context * intel);
       void (*render_prevalidate) (struct intel_context * intel);
       void (*set_draw_region) (struct intel_context * intel,
-                               struct intel_region * draw_region,
-                               struct intel_region * depth_region);
+                               struct intel_region * draw_regions[],
+                               struct intel_region * depth_region,
+                              GLuint num_regions);
 
       GLuint (*flush_cmd) (void);
       void (*emit_flush) (struct intel_context *intel, GLuint unused);