From fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 13 Mar 2008 14:46:38 +0800 Subject: [PATCH] [i965] multiple rendering target support --- src/mesa/drivers/dri/i915/i830_vtbl.c | 7 +-- src/mesa/drivers/dri/i915/i915_vtbl.c | 7 +-- src/mesa/drivers/dri/i965/brw_context.h | 7 +-- src/mesa/drivers/dri/i965/brw_fallback.c | 10 ---- src/mesa/drivers/dri/i965/brw_metaops.c | 12 +++-- src/mesa/drivers/dri/i965/brw_vtbl.c | 15 +++--- src/mesa/drivers/dri/i965/brw_wm.c | 5 +- src/mesa/drivers/dri/i965/brw_wm.h | 2 + src/mesa/drivers/dri/i965/brw_wm_emit.c | 24 +++++---- src/mesa/drivers/dri/i965/brw_wm_fp.c | 28 +++++++--- src/mesa/drivers/dri/i965/brw_wm_glsl.c | 23 ++++---- src/mesa/drivers/dri/i965/brw_wm_pass0.c | 2 + .../drivers/dri/i965/brw_wm_surface_state.c | 54 ++++++++++--------- src/mesa/drivers/dri/intel/intel_buffers.c | 32 +++++++---- src/mesa/drivers/dri/intel/intel_context.h | 5 +- 15 files changed, 135 insertions(+), 98 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 9bc868b043b..1f4bc91d77e 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -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 diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index c856a8627de..40c5de26c63 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -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); } diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 49e739b0ad8..4e6b471fdde 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -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]; diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 58aeeb4228c..ce0df0357b6 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -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 diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 7b34f0f3bd6..252a8996e26 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -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; diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index cdbbe7b6994..31e96a250ac 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -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; } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 47665692e3b..abdc92bf014 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -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; diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 441fbd33fb4..5ca2a634c07 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -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*/ }; diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index df51f73dd84..4c0bd67c923 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -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: diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 77cb3b27e3e..682b16d74dd 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -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); + } + } } diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index fd237ee0287..58520838826 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c index 1bfae5a069b..205a7160d39 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c @@ -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: */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f2ae210c386..d0f86b5687b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -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), - ®ion_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), + ®ion_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), ®ion_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; } } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 5199f833e2c..2a25f079e95 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -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) { diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 809cb6ea578..1348b0adcf0 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -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); -- 2.30.2