diff options
Diffstat (limited to 'src/mesa/drivers/dri/i965')
35 files changed, 1172 insertions, 300 deletions
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index e4fb451cc09..213eac895cb 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -16,6 +16,8 @@ DRIVER_SOURCES = \ intel_regions.c \ intel_screen.c \ intel_span.c \ + intel_pixel_copy.c \ + intel_pixel_bitmap.c \ intel_state.c \ intel_tex.c \ intel_tex_validate.c \ diff --git a/src/mesa/drivers/dri/i965/brw_aub_playback.c b/src/mesa/drivers/dri/i965/brw_aub_playback.c index 49cc967716e..2433d50c116 100644 --- a/src/mesa/drivers/dri/i965/brw_aub_playback.c +++ b/src/mesa/drivers/dri/i965/brw_aub_playback.c @@ -39,7 +39,7 @@ static void flush_and_fence( struct aub_state *s ) buf[0] = intel->vtbl.flush_cmd(); buf[1] = 0; - intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf), GL_TRUE); + intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf)); intelWaitIrq( intel, intelEmitIrqLocked( intel )); } @@ -64,7 +64,7 @@ static void flush_cmds( struct aub_state *s, * This differs slightly from how the stream was executed * initially as this would have been a batchbuffer. */ - intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE); + intel_cmd_ioctl(s->intel, (void *)data, len); if (1) flush_and_fence(s); @@ -345,7 +345,7 @@ static int parse_block_header( struct aub_state *s ) } case BH_COMMAND_WRITE: #if 0 - intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE); + intel_cmd_ioctl(s->intel, (void *)data, len); #else if (parse_commands(s, data, len) != 0) _mesa_printf("parse_commands failed\n"); diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index f12fb4c7f3e..5c0c5da7eaa 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -123,6 +123,23 @@ static GLuint trim(GLenum prim, GLuint length) } +static void brw_emit_cliprect( struct brw_context *brw, + const drm_clip_rect_t *rect ) +{ + struct brw_drawrect bdr; + + bdr.header.opcode = CMD_DRAW_RECT; + bdr.header.length = sizeof(bdr)/4 - 2; + bdr.xmin = rect->x1; + bdr.xmax = rect->x2 - 1; + bdr.ymin = rect->y1; + bdr.ymax = rect->y2 - 1; + bdr.xorg = brw->intel.drawX; + bdr.yorg = brw->intel.drawY; + + intel_batchbuffer_data( brw->intel.batch, &bdr, sizeof(bdr), + INTEL_BATCH_NO_CLIPRECTS); +} static void brw_emit_prim( struct brw_context *brw, @@ -149,7 +166,7 @@ static void brw_emit_prim( struct brw_context *brw, if (prim_packet.verts_per_instance) { intel_batchbuffer_data( brw->intel.batch, &prim_packet, sizeof(prim_packet), - INTEL_BATCH_CLIPRECTS); + INTEL_BATCH_NO_CLIPRECTS); } } @@ -277,7 +294,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, struct intel_context *intel = intel_context(ctx); struct brw_context *brw = brw_context(ctx); GLboolean retval = GL_FALSE; - GLuint i; + GLuint i, j; if (ctx->NewState) _mesa_update_state( ctx ); @@ -294,8 +311,17 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, */ LOCK_HARDWARE(intel); + + if (brw->intel.numClipRects == 0) { + assert(intel->batch->ptr == intel->batch->map + intel->batch->offset); + UNLOCK_HARDWARE(intel); + return GL_TRUE; + } + { assert(intel->locked); + + /* Set the first primitive early, ahead of validate_state: */ @@ -322,12 +348,28 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, goto out; } - /* Emit prims to batchbuffer: + /* For single cliprect, state is already emitted: */ - for (i = 0; i < nr_prims; i++) { - brw_emit_prim(brw, &prim[i]); + if (brw->intel.numClipRects == 1) { + for (i = 0; i < nr_prims; i++) { + brw_emit_prim(brw, &prim[i]); + } + } + else { + /* Otherwise, explicitly do the cliprects at this point: + */ + for (j = 0; j < brw->intel.numClipRects; j++) { + brw_emit_cliprect(brw, &brw->intel.pClipRects[j]); + + /* Emit prims to batchbuffer: + */ + for (i = 0; i < nr_prims; i++) { + brw_emit_prim(brw, &prim[i]); + } + } } + intel->need_flush = GL_TRUE; retval = GL_TRUE; } @@ -400,7 +442,7 @@ GLboolean brw_draw_prims( GLcontext *ctx, retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); } - if (intel->aub_file) { + if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { intelFinish( &intel->ctx ); intel->aub_wrap = 1; } diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 8c6b5a6d2c4..cde0aa6481b 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -435,6 +435,7 @@ GLboolean brw_upload_vertices( struct brw_context *brw, ptr = input->glarray->Ptr; } else if (interleave != input->glarray->StrideB || + (const char *)input->glarray->Ptr - (const char *)ptr < 0 || (const char *)input->glarray->Ptr - (const char *)ptr > interleave) { interleave = 0; } diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c index ca012dbcd8a..470fa6f4177 100644 --- a/src/mesa/drivers/dri/i965/brw_exec_api.c +++ b/src/mesa/drivers/dri/i965/brw_exec_api.c @@ -394,7 +394,7 @@ static void GLAPIENTRY brw_exec_EvalCoord1f( GLfloat u ) for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { if (exec->eval.map1[i].map) - if (exec->vtx.attrsz[i] != exec->eval.map1[i].sz) + if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) brw_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); } } diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 29296c17e9e..6a6c4503c74 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -74,7 +74,6 @@ const struct brw_tracked_state brw_blend_constant_color = { /*********************************************************************** * Drawing rectangle -- Need for AUB file only. */ - static void upload_drawing_rect(struct brw_context *brw) { struct intel_context *intel = &brw->intel; @@ -83,13 +82,12 @@ static void upload_drawing_rect(struct brw_context *brw) int x1, y1; int x2, y2; - if (!brw->intel.aub_file) + /* If there is a single cliprect, set it here. Otherwise iterate + * over them in brw_draw_prim(). + */ + if (brw->intel.numClipRects > 1) return; - /* Basically calculate a single cliprect for the whole window. - * Don't bother iterating over cliprects at the moment. - */ - x1 = dPriv->x; y1 = dPriv->y; x2 = dPriv->x + dPriv->w; @@ -110,7 +108,10 @@ static void upload_drawing_rect(struct brw_context *brw) bdr.xorg = dPriv->x; bdr.yorg = dPriv->y; - BRW_CACHED_BATCH_STRUCT(brw, &bdr); + /* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted + * uncached in brw_draw.c: + */ + BRW_BATCH_STRUCT(brw, &bdr); } const struct brw_tracked_state brw_drawing_rect = { diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index d70b2ea87a5..8332d869e1d 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -49,34 +49,57 @@ static const struct gl_texture_format * brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, - GLenum format, GLenum type ) + GLenum srcFormat, GLenum srcType ) { switch ( internalFormat ) { case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: + if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) + return &_mesa_texformat_argb4444; + else if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) + return &_mesa_texformat_argb1555; + else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8)) + return &_mesa_texformat_rgba8888_rev; + else + return &_mesa_texformat_argb8888; + case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - case GL_RGBA4: - case GL_RGBA2: - case GL_RGB5_A1: return &_mesa_texformat_argb8888; -/* return &_mesa_texformat_rgba8888_rev; */ - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: case GL_RGB8: case GL_RGB10: case GL_RGB12: case GL_RGB16: + /* Broadwater doesn't support RGB888 textures, so these must be + * stored as ARGB. + */ + return &_mesa_texformat_argb8888; + + case 3: + case GL_COMPRESSED_RGB: + case GL_RGB: + if (srcFormat == GL_RGB && + srcType == GL_UNSIGNED_SHORT_5_6_5) + return &_mesa_texformat_rgb565; + else + return &_mesa_texformat_argb8888; + + case GL_RGB5: - case GL_RGB4: + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + case GL_R3_G3_B2: -/* return &_mesa_texformat_rgb888; */ - return &_mesa_texformat_argb8888; + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB4: + return &_mesa_texformat_argb4444; case GL_ALPHA: case GL_ALPHA4: @@ -115,8 +138,8 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, return &_mesa_texformat_i8; case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_MESA || - type == GL_UNSIGNED_BYTE) + if (srcType == GL_UNSIGNED_SHORT_8_8_MESA || + srcType == GL_UNSIGNED_BYTE) return &_mesa_texformat_ycbcr; else return &_mesa_texformat_ycbcr_rev; diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index f8aa068241b..1353325afff 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -138,13 +138,16 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) /* Layout_below: step right after second mipmap. */ - if (level == mt->first_level + 1) + if (level == mt->first_level + 1) { x += mt->pitch / 2; + x = (x + 3) & ~ 3; + } else { y += img_height; + y += align_h - 1; + y &= ~(align_h - 1); } - width = minify(width); height = minify(height); } diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c index 5957b717218..9d12c26486d 100644 --- a/src/mesa/drivers/dri/i965/brw_util.c +++ b/src/mesa/drivers/dri/i965/brw_util.c @@ -98,6 +98,8 @@ static GLuint brw_parameter_state_flags(const enum state_index state[]) switch (state[1]) { case STATE_NORMAL_SCALE: return _NEW_MODELVIEW; + case STATE_TEXRECT_SCALE: + return _NEW_TEXTURE; default: assert(0); return 0; diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index 2a94ac64965..e5a28b96e32 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -105,6 +105,11 @@ static void brw_upload_vs_prog( struct brw_context *brw ) key.copy_edgeflag = (brw->attribs.Polygon->FrontMode != GL_FILL || brw->attribs.Polygon->BackMode != GL_FILL); + /* BRW_NEW_METAOPS + */ + if (brw->metaops.active) + key.know_w_is_one = 1; + /* Make an early check for the key. */ if (brw_search_cache(&brw->cache[BRW_VS_PROG], @@ -122,7 +127,7 @@ static void brw_upload_vs_prog( struct brw_context *brw ) const struct brw_tracked_state brw_vs_prog = { .dirty = { .mesa = _NEW_TRANSFORM | _NEW_POLYGON, - .brw = BRW_NEW_VERTEX_PROGRAM, + .brw = BRW_NEW_VERTEX_PROGRAM | BRW_NEW_METAOPS, .cache = 0 }, .update = brw_upload_vs_prog diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index d355681b5ea..fdb5785d67d 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -43,7 +43,8 @@ struct brw_vs_prog_key { GLuint program_string_id; GLuint nr_userclip:4; GLuint copy_edgeflag:1; - GLuint pad:27; + GLuint know_w_is_one:1; + GLuint pad:26; }; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index a22740084d3..da9d3bacb0e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -797,13 +797,21 @@ static void emit_vertex_write( struct brw_vs_compile *c) /* Build ndc coords? TODO: Shortcircuit when w is known to be one. */ - ndc = get_tmp(c); - emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); - brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc); + if (!c->key.know_w_is_one) { + ndc = get_tmp(c); + emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); + brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc); + } + else { + ndc = pos; + } /* This includes the workaround for -ve rhw, so is no longer an * optional step: */ + if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) || + c->key.nr_userclip || + !c->key.know_w_is_one) { struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); GLuint i; @@ -836,20 +844,17 @@ static void emit_vertex_write( struct brw_vs_compile *c) * Later, clipping will detect ucp[6] and ensure the primitive is * clipped against all fixed planes. */ - brw_CMP(p, - vec8(brw_null_reg()), - BRW_CONDITIONAL_L, - brw_swizzle1(ndc, 3), - brw_imm_f(0)); + if (!c->key.know_w_is_one) { + brw_CMP(p, + vec8(brw_null_reg()), + BRW_CONDITIONAL_L, + brw_swizzle1(ndc, 3), + brw_imm_f(0)); - brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<6)); - brw_MOV(p, ndc, brw_imm_f(0)); - brw_set_predicate_control(p, BRW_PREDICATE_NONE); - - - - - + brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<6)); + brw_MOV(p, ndc, brw_imm_f(0)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } brw_set_access_mode(p, BRW_ALIGN_1); /* why? */ brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), header1); @@ -857,6 +862,9 @@ static void emit_vertex_write( struct brw_vs_compile *c) release_tmp(c, header1); } + else { + brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), brw_imm_ud(0)); + } /* Emit the (interleaved) headers for the two vertices - an 8-reg diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index c1099d4c676..1df111f6457 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -535,6 +535,7 @@ static void emit_op3fn(struct tnl_program *p, { struct prog_instruction *inst = &p->program->Base.Instructions[nr]; + memset(inst, 0, sizeof(*inst)); inst->Opcode = op; inst->StringPos = 0; inst->Data = 0; diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 74c3bbe2047..ec6ad6105ca 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -167,6 +167,7 @@ struct brw_wm_instruction { #define WM_CINTERP (MAX_OPCODE + 5) #define WM_WPOSXY (MAX_OPCODE + 6) #define WM_FB_WRITE (MAX_OPCODE + 7) +#define MAX_WM_OPCODE (MAX_OPCODE + 8) #define PROGRAM_PAYLOAD (PROGRAM_FILE_MAX) #define PAYLOAD_DEPTH (FRAG_ATTRIB_MAX) diff --git a/src/mesa/drivers/dri/i965/brw_wm_debug.c b/src/mesa/drivers/dri/i965/brw_wm_debug.c index 6b0096eca58..9a6154b3336 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_debug.c +++ b/src/mesa/drivers/dri/i965/brw_wm_debug.c @@ -36,66 +36,6 @@ #include "shader/arbprogparse.h" #include "shader/program_instruction.h" -static const char *fp_opcode_string[] = { - "ABS", /* ARB_f_p only */ - "ADD", - "CMP", /* ARB_f_p only */ - "COS", - "DDX", /* NV_f_p only */ - "DDY", /* NV_f_p only */ - "DP3", - "DP4", - "DPH", /* ARB_f_p only */ - "DST", - "END", /* private opcode */ - "EX2", - "FLR", - "FRC", - "KIL", /* ARB_f_p only */ - "KIL_NV", /* NV_f_p only */ - "LG2", - "LIT", - "LRP", - "MAD", - "MAX", - "MIN", - "MOV", - "MUL", - "PK2H", /* NV_f_p only */ - "PK2US", /* NV_f_p only */ - "PK4B", /* NV_f_p only */ - "PK4UB", /* NV_f_p only */ - "POW", - "PRINT", /* Mesa only */ - "RCP", - "RFL", /* NV_f_p only */ - "RSQ", - "SCS", /* ARB_f_p only */ - "SEQ", /* NV_f_p only */ - "SFL", /* NV_f_p only */ - "SGE", /* NV_f_p only */ - "SGT", /* NV_f_p only */ - "SIN", - "SLE", /* NV_f_p only */ - "SLT", - "SNE", /* NV_f_p only */ - "STR", /* NV_f_p only */ - "SUB", - "SWZ", /* ARB_f_p only */ - "TEX", - "TXB", /* ARB_f_p only */ - "TXD", /* NV_f_p only */ - "TXP", /* ARB_f_p only */ - "TXP_NV", /* NV_f_p only */ - "UP2H", /* NV_f_p only */ - "UP2US", /* NV_f_p only */ - "UP4B", /* NV_f_p only */ - "UP4UB", /* NV_f_p only */ - "X2D", /* NV_f_p only - 2d mat mul */ - "XPD", /* ARB_f_p only - cross product */ -}; - - void brw_wm_print_value( struct brw_wm_compile *c, struct brw_wm_value *value ) @@ -194,7 +134,7 @@ void brw_wm_print_insn( struct brw_wm_compile *c, _mesa_printf(" = FB_WRITE"); break; default: - _mesa_printf(" = %s", fp_opcode_string[inst->opcode]); + _mesa_printf(" = %s", _mesa_opcode_string(inst->opcode)); break; } diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 203eeead0f3..04c7555b9b8 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -60,9 +60,11 @@ static const char *wm_opcode_strings[] = { "FB_WRITE" }; +#if 0 static const char *wm_file_strings[] = { "PAYLOAD" }; +#endif /*********************************************************************** @@ -520,6 +522,35 @@ static void precalc_lit( struct brw_wm_compile *c, static void precalc_tex( struct brw_wm_compile *c, const struct prog_instruction *inst ) { + struct prog_src_register coord; + struct prog_dst_register tmpcoord; + + if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { + struct prog_src_register scale = + search_or_add_param6( c, + STATE_INTERNAL, + STATE_TEXRECT_SCALE, + inst->TexSrcUnit, + 0,0,0 ); + + tmpcoord = get_temp(c); + + /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height } + */ + emit_op(c, + OPCODE_MUL, + tmpcoord, + 0, 0, 0, + inst->SrcReg[0], + scale, + src_undef()); + + coord = src_reg_from_dst(tmpcoord); + } + else { + coord = inst->SrcReg[0]; + } + /* Need to emit YUV texture conversions by hand. Probably need to * do this here - the alternative is in brw_wm_emit.c, but the * conversion requires allocating a temporary variable which we @@ -532,7 +563,7 @@ static void precalc_tex( struct brw_wm_compile *c, inst->SaturateMode, inst->TexSrcUnit, inst->TexSrcTarget, - inst->SrcReg[0], + coord, src_undef(), src_undef()); } @@ -604,7 +635,12 @@ static void precalc_tex( struct brw_wm_compile *c, src_swizzle1(tmpsrc, Z), src_swizzle1(C1, W), src_swizzle1(src_reg_from_dst(dst), Y)); + + release_temp(c, tmp); } + + if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV) + release_temp(c, tmpcoord); } @@ -769,6 +805,27 @@ static void validate_src_regs( struct brw_wm_compile *c, +static void print_insns( const struct prog_instruction *insn, + GLuint nr ) +{ + GLuint i; + for (i = 0; i < nr; i++, insn++) { + _mesa_printf("%3d: ", i); + if (insn->Opcode < MAX_OPCODE) + _mesa_print_instruction(insn); + else if (insn->Opcode < MAX_WM_OPCODE) { + GLuint idx = insn->Opcode - MAX_OPCODE; + + _mesa_print_alu_instruction(insn, + wm_opcode_strings[idx], + 3); + } + else + _mesa_printf("UNKNOWN\n"); + + } +} + void brw_wm_pass_fp( struct brw_wm_compile *c ) { struct brw_fragment_program *fp = c->fp; @@ -867,7 +924,7 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) if (INTEL_DEBUG & DEBUG_WM) { _mesa_printf("\n\n\npass_fp:\n"); -/* _mesa_debug_fp_inst(c->nr_fp_insns, c->prog_instructions, wm_opcode_strings, wm_file_strings); */ + print_insns( c->prog_instructions, c->nr_fp_insns ); _mesa_printf("\n"); } } 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 6ccf56e41a2..5c7dc500cab 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -85,7 +85,8 @@ static GLuint translate_tex_format( GLuint mesa_format ) return BRW_SURFACEFORMAT_L8A8_UNORM; case MESA_FORMAT_RGB888: - return BRW_SURFACEFORMAT_R8G8B8_UNORM; + assert(0); /* not supported for sampling */ + return BRW_SURFACEFORMAT_R8G8B8_UNORM; case MESA_FORMAT_ARGB8888: return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; @@ -93,6 +94,15 @@ static GLuint translate_tex_format( GLuint mesa_format ) case MESA_FORMAT_RGBA8888_REV: return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; + case MESA_FORMAT_RGB565: + return BRW_SURFACEFORMAT_B5G6R5_UNORM; + + case MESA_FORMAT_ARGB1555: + return BRW_SURFACEFORMAT_B5G5R5A1_UNORM; + + case MESA_FORMAT_ARGB4444: + return BRW_SURFACEFORMAT_B4G4R4A4_UNORM; + case MESA_FORMAT_YCBCR_REV: return BRW_SURFACEFORMAT_YCRCB_NORMAL; diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h index 83a810cc6dd..6932522d3d3 100644 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -182,6 +182,8 @@ void bmUnmapBufferAUB( struct intel_context *, int bmValidateBuffers( struct intel_context * ); void bmReleaseBuffers( struct intel_context * ); +GLuint bmCtxId( struct intel_context *intel ); + GLboolean bmError( struct intel_context * ); void bmEvictAll( struct intel_context * ); diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c index 8f182f3d877..ed88ab3797a 100644 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -117,6 +117,7 @@ struct bufmgr { struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ /* then to pool->lru or free() */ + unsigned ctxId; unsigned last_fence; unsigned free_on_hardware; @@ -578,6 +579,12 @@ struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ) make_empty_list(&bm.referenced); make_empty_list(&bm.fenced); make_empty_list(&bm.on_hardware); + + /* The context id of any of the share group. This won't be used + * in communication with the kernel, so it doesn't matter if + * this context is eventually deleted. + */ + bm.ctxId = intel->hHWContext; } nr_attach++; @@ -1242,7 +1249,6 @@ void bmReleaseBuffers( struct intel_context *intel ) LOCK(bm); { struct block *block, *tmp; - assert(intel->locked); foreach_s (block, tmp, &bm->referenced) { @@ -1301,7 +1307,7 @@ unsigned bmSetFence( struct intel_context *intel ) GLuint dword[2]; dword[0] = intel->vtbl.flush_cmd(); dword[1] = 0; - intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword), GL_TRUE); + intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword)); intel->bm->last_fence = intelEmitIrqLocked( intel ); @@ -1432,3 +1438,9 @@ GLboolean bmError( struct intel_context *intel ) return retval; } + + +GLuint bmCtxId( struct intel_context *intel ) +{ + return intel->bm->ctxId; +} diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 598ce08735d..64885ed9b4b 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -128,7 +128,6 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) struct intel_context *intel = batch->intel; GLuint used = batch->ptr - (batch->map + batch->offset); GLuint offset; - GLboolean ignore_cliprects = (batch->flags & INTEL_BATCH_CLIPRECTS) ? GL_FALSE : GL_TRUE; GLint retval = GL_TRUE; assert(intel->locked); @@ -138,22 +137,6 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) return GL_TRUE; } - /* Throw away non-effective packets. - */ - if (intel->numClipRects == 0 && !ignore_cliprects) { - batch->ptr = batch->map + batch->offset; - bmReleaseBuffers( batch->intel ); - intel->vtbl.lost_hardware(intel); - batch->flags = 0; - - UNLOCK_HARDWARE(intel); - sched_yield(); - LOCK_HARDWARE(intel); - - return GL_TRUE; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. */ @@ -204,8 +187,7 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) */ intel_batch_ioctl(batch->intel, offset + batch->offset, - used, - ignore_cliprects); + used); if (intel->aub_file && intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index 7a9ead3e373..25e0a65e99f 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -46,7 +46,7 @@ struct intel_batchbuffer { struct buffer *buffer; GLuint flags; - GLuint offset; + unsigned long offset; GLubyte *map; GLubyte *ptr; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 2191dd585e1..0974f1f80ad 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -39,6 +39,7 @@ #include "intel_context.h" #include "intel_blit.h" #include "intel_regions.h" +#include "intel_structs.h" #include "bufmgr.h" @@ -74,9 +75,6 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, if (!rect) { - /* This is a really crappy way to do wait-for-vblank. I guess - * it sortof works in the single-application case. - */ UNLOCK_HARDWARE( intel ); driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target ); LOCK_HARDWARE( intel ); @@ -291,8 +289,12 @@ void intelEmitCopyBlit( struct intel_context *intel, /* Initial y values don't seem to work with negative pitches. If * we adjust the offsets manually (below), it seems to work fine. + * + * On the other hand, if we always adjust, the hardware doesn't + * know which blit directions to use, so overlapping copypixels get + * the wrong result. */ - if (0) { + if (dst_pitch > 0 && src_pitch > 0) { BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( dst_pitch | BR13 ); @@ -320,14 +322,14 @@ void intelEmitCopyBlit( struct intel_context *intel, -void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch) +void intelClearWithBlit(GLcontext *ctx, GLbitfield flags) { struct intel_context *intel = intel_context( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; - GLint cx, cy; + GLint cx, cy, cw, ch; GLint cpp = intelScreen->cpp; + GLboolean all; GLint i; struct intel_region *front = intel->front_region; struct intel_region *back = intel->back_region; @@ -374,21 +376,16 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); { - /* Refresh the cx/y/w/h values as they may have been invalidated - * by a new window position or size picked up when we did - * LOCK_HARDWARE above. The values passed by mesa are not - * reliable. - */ - { - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - } + /* get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height); /* flip top to bottom */ - cy = intel->driDrawable->h-cy1-ch; - cx = cx1 + intel->drawX; + cy = intel->driDrawable->h - cy - ch; + cx = cx + intel->drawX; cy += intel->drawY; /* adjust for page flipping */ @@ -492,3 +489,98 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, } + +#define BR13_565 0x1 +#define BR13_8888 0x3 + + +void +intelEmitImmediateColorExpandBlit(struct intel_context *intel, + GLuint cpp, + GLubyte *src_bits, GLuint src_size, + GLuint fg_color, + GLshort dst_pitch, + struct buffer *dst_buffer, + GLuint dst_offset, + GLboolean dst_tiled, + GLshort x, GLshort y, + GLshort w, GLshort h) +{ + struct xy_setup_blit setup; + struct xy_text_immediate_blit text; + int dwords = ((src_size + 7) & ~7) / 4; + + + if (w < 0 || h < 0) + return; + + dst_pitch *= cpp; + + if (dst_tiled) + dst_pitch /= 4; + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n", + __FUNCTION__, + dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords); + + memset(&setup, 0, sizeof(setup)); + + setup.br0.client = CLIENT_2D; + setup.br0.opcode = OPCODE_XY_SETUP_BLT; + setup.br0.write_alpha = (cpp == 4); + setup.br0.write_rgb = (cpp == 4); + setup.br0.dst_tiled = dst_tiled; + setup.br0.length = (sizeof(setup) / sizeof(int)) - 2; + + setup.br13.dest_pitch = dst_pitch; + setup.br13.rop = 0xcc; + setup.br13.color_depth = (cpp == 4) ? BR13_8888 : BR13_565; + setup.br13.clipping_enable = 0; + setup.br13.mono_source_transparency = 1; + + setup.dw2.clip_y1 = 0; + setup.dw2.clip_x1 = 0; + setup.dw3.clip_y2 = 100; + setup.dw3.clip_x2 = 100; + + setup.dest_base_addr = bmBufferOffset(intel, dst_buffer) + dst_offset; + setup.background_color = 0; + setup.foreground_color = fg_color; + setup.pattern_base_addr = 0; + + memset(&text, 0, sizeof(text)); + text.dw0.client = CLIENT_2D; + text.dw0.opcode = OPCODE_XY_TEXT_IMMEDIATE_BLT; + text.dw0.pad0 = 0; + text.dw0.byte_packed = 1; /* ?maybe? */ + text.dw0.pad1 = 0; + text.dw0.dst_tiled = dst_tiled; + text.dw0.pad2 = 0; + text.dw0.length = (sizeof(text)/sizeof(int)) - 2 + dwords; + text.dw1.dest_y1 = y; /* duplicates info in setup blit */ + text.dw1.dest_x1 = x; + text.dw2.dest_y2 = y + h; + text.dw2.dest_x2 = x + w; + + intel_batchbuffer_require_space( intel->batch, + sizeof(setup) + + sizeof(text) + + dwords, + INTEL_BATCH_NO_CLIPRECTS ); + + intel_batchbuffer_data( intel->batch, + &setup, + sizeof(setup), + INTEL_BATCH_NO_CLIPRECTS ); + + intel_batchbuffer_data( intel->batch, + &text, + sizeof(text), + INTEL_BATCH_NO_CLIPRECTS ); + + intel_batchbuffer_data( intel->batch, + src_bits, + dwords * 4, + INTEL_BATCH_NO_CLIPRECTS ); +} + diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index 357ceb4c512..b15fb1c2b7f 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -35,8 +35,7 @@ struct buffer; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); -extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch); +extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, @@ -62,5 +61,16 @@ extern void intelEmitFillBlit( struct intel_context *intel, GLshort w, GLshort h, GLuint color ); +void +intelEmitImmediateColorExpandBlit(struct intel_context *intel, + GLuint cpp, + GLubyte *src_bits, GLuint src_size, + GLuint fg_color, + GLshort dst_pitch, + struct buffer *dst_buffer, + GLuint dst_offset, + GLboolean dst_tiled, + GLshort dst_x, GLshort dst_y, + GLshort w, GLshort h); #endif diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index 853956671ce..d155c039d77 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -210,6 +210,12 @@ void intelWindowMoved( struct intel_context *intel ) intel->NewGLState |= _NEW_SCISSOR; } + + /* This works because the lock is always grabbed before emitting + * commands and commands are always flushed prior to releasing + * the lock. + */ + intel->NewGLState |= _NEW_WINDOW_POS; } @@ -218,12 +224,11 @@ void intelWindowMoved( struct intel_context *intel ) * machine independent. Maybe we'll get there one day. */ static void intelClearWithTris(struct intel_context *intel, - GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, - GLint cw, GLint ch) + GLbitfield mask) { + GLcontext *ctx = &intel->ctx; drm_clip_rect_t clear; + GLint cx, cy, cw, ch; if (INTEL_DEBUG & DEBUG_DRI) _mesa_printf("%s %x\n", __FUNCTION__, mask); @@ -232,18 +237,11 @@ static void intelClearWithTris(struct intel_context *intel, intel->vtbl.install_meta_state(intel); - /* Refresh the cx/y/w/h values as they may have been invalidated - * by a new window position or size picked up when we did - * LOCK_HARDWARE above. The values passed by mesa are not - * reliable. - */ - { - GLcontext *ctx = &intel->ctx; - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - } + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; clear.x1 = cx; clear.y1 = cy; @@ -321,11 +319,7 @@ static void intelClearWithTris(struct intel_context *intel, -static void intelClear(GLcontext *ctx, - GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, - GLint cw, GLint ch) +static void intelClear(GLcontext *ctx, GLbitfield mask) { struct intel_context *intel = intel_context( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); @@ -334,8 +328,7 @@ static void intelClear(GLcontext *ctx, GLbitfield swrast_mask = 0; if (INTEL_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %x all %d dims %d,%d %dx%d\n", __FUNCTION__, - mask, all, cx, cy, cw, ch); + fprintf(stderr, "%s %x\n", __FUNCTION__, mask); if (mask & BUFFER_BIT_FRONT_LEFT) { @@ -386,13 +379,13 @@ static void intelClear(GLcontext *ctx, intelFlush( ctx ); if (blit_mask) - intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); + intelClearWithBlit( ctx, blit_mask ); if (tri_mask) - intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch); + intelClearWithTris( intel, tri_mask ); if (swrast_mask) - _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, swrast_mask ); } @@ -549,7 +542,6 @@ void intelInitBufferFuncs( struct dd_function_table *functions ) { functions->Clear = intelClear; functions->GetBufferSize = intelBufferSize; - functions->ResizeBuffers = _mesa_resize_framebuffer; functions->DrawBuffer = intelDrawBuffer; functions->ReadBuffer = intelReadBuffer; } diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 59fc8073eee..36edd7db7f5 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -149,6 +149,10 @@ const struct dri_extension card_extensions[] = { "GL_ARB_texture_env_combine", NULL }, { "GL_ARB_texture_env_dot3", NULL }, { "GL_ARB_texture_mirrored_repeat", NULL }, + { "GL_ARB_texture_non_power_of_two", NULL }, + { "GL_ARB_texture_rectangle", NULL }, + { "GL_NV_texture_rectangle", NULL }, + { "GL_EXT_texture_rectangle", NULL }, { "GL_ARB_texture_rectangle", NULL }, { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, @@ -246,18 +250,14 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) functions->Finish = intelFinish; functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; - functions->CopyColorTable = _swrast_CopyColorTable; - functions->CopyColorSubTable = _swrast_CopyColorSubTable; - functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; - functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; - /* Pixel path fallbacks. + /* CopyPixels can be accelerated even with the current memory + * manager: */ - functions->Accum = _swrast_Accum; - functions->Bitmap = _swrast_Bitmap; - functions->CopyPixels = _swrast_CopyPixels; - functions->ReadPixels = _swrast_ReadPixels; - functions->DrawPixels = _swrast_DrawPixels; + if (!getenv("INTEL_NO_BLIT")) { + functions->CopyPixels = intelCopyPixels; + functions->Bitmap = intelBitmap; + } intelInitTextureFuncs( functions ); intelInitStateFuncs( functions ); @@ -370,8 +370,6 @@ GLboolean intelInitContext( struct intel_context *intel, exit(1); } - _math_matrix_ctr (&intel->ViewportMatrix); - driInitExtensions( ctx, card_extensions, GL_TRUE ); @@ -446,8 +444,6 @@ GLboolean intelInitContext( struct intel_context *intel, /* DRI_TEXMGR_DO_TEXTURE_RECT ); */ - intel->prim.primitive = ~0; - if (getenv("INTEL_NO_RAST")) { fprintf(stderr, "disabling 3D rasterization\n"); intel->no_rast = 1; @@ -537,18 +533,13 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, } -static void lost_hardware( struct intel_context *intel ) -{ - bm_fake_NotifyContendedLockTake( intel ); - intel->vtbl.lost_hardware( intel ); -} - static void intelContendedLock( struct intel_context *intel, GLuint flags ) { __DRIdrawablePrivate *dPriv = intel->driDrawable; __DRIscreenPrivate *sPriv = intel->driScreen; volatile drmI830Sarea * sarea = intel->sarea; int me = intel->hHWContext; + int my_bufmgr = bmCtxId(intel); drmGetLock(intel->driFd, intel->hHWContext, flags); @@ -562,12 +553,23 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags ) intel->locked = 1; + intel->need_flush = 1; /* Lost context? */ if (sarea->ctxOwner != me) { + DBG("Lost Context: sarea->ctxOwner %x me %x\n", sarea->ctxOwner, me); sarea->ctxOwner = me; - lost_hardware(intel); + intel->vtbl.lost_hardware( intel ); + } + + /* As above, but don't evict the texture data on transitions + * between contexts which all share a local buffer manager. + */ + if (sarea->texAge != my_bufmgr) { + DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr); + sarea->texAge = my_bufmgr; + bm_fake_NotifyContendedLockTake( intel ); } /* Drawable changed? @@ -575,12 +577,6 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags ) if (dPriv && intel->lastStamp != dPriv->lastStamp) { intelWindowMoved( intel ); intel->lastStamp = dPriv->lastStamp; - - /* This works because the lock is always grabbed before emitting - * commands and commands are always flushed prior to releasing - * the lock. - */ - intel->NewGLState |= _NEW_WINDOW_POS; } } diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 0328cb900a8..2df8faef28e 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -176,16 +176,6 @@ struct intel_context struct intel_batchbuffer *batch; - struct { - GLuint id; - GLuint primitive; - GLubyte *start_ptr; - void (*flush)( struct intel_context * ); - } prim; - - GLboolean locked; - GLboolean strict_conformance; - GLubyte clear_chan[4]; GLuint ClearColor; GLuint ClearDepth; @@ -201,6 +191,10 @@ struct intel_context GLboolean no_hw; GLboolean no_rast; GLboolean thrashing; + GLboolean locked; + GLboolean strict_conformance; + GLboolean need_flush; + /* AGP memory buffer manager: @@ -210,26 +204,14 @@ struct intel_context /* State for intelvb.c and inteltris.c. */ - GLuint RenderIndex; - GLmatrix ViewportMatrix; GLenum render_primitive; GLenum reduced_primitive; - GLuint vertex_size; - GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ - struct intel_region *front_region; struct intel_region *back_region; struct intel_region *draw_region; struct intel_region *depth_region; - - /* Fallback rasterization functions - */ - intel_point_func draw_point; - intel_line_func draw_line; - intel_tri_func draw_tri; - /* These refer to the current draw (front vs. back) buffer: */ int drawX; /* origin of drawable in draw buffer */ @@ -347,8 +329,8 @@ static inline void * __memcpy(void * to, const void * from, size_t n) */ static inline void *do_memcpy( void *dest, const void *src, size_t n ) { - if ( (((unsigned)src) & 63) || - (((unsigned)dest) & 63)) { + if ( (((unsigned long)src) & 63) || + (((unsigned long)dest) & 63)) { return __memcpy(dest, src, n); } else @@ -496,6 +478,21 @@ extern GLboolean intel_intersect_cliprects( drm_clip_rect_t *dest, const drm_clip_rect_t *b ); +/* ================================================================ + * intel_pixel_copy.c: + */ +void intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type); + +GLboolean intel_check_blit_fragment_ops(GLcontext * ctx); + +void intelBitmap(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * pixels); #define _NEW_WINDOW_POS 0x40000000 diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 9297543f82b..d1f2e3f27ca 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -105,8 +105,7 @@ void intelWaitIrq( struct intel_context *intel, int seq ) void intel_batch_ioctl( struct intel_context *intel, GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects) + GLuint used) { drmI830BatchBuffer batch; @@ -114,27 +113,24 @@ void intel_batch_ioctl( struct intel_context *intel, assert(used); if (0) - fprintf(stderr, "%s used %d offset %x..%x ignore_cliprects %d\n", + fprintf(stderr, "%s used %d offset %x..%x\n", __FUNCTION__, used, start_offset, - start_offset + used, - ignore_cliprects); + start_offset + used); batch.start = start_offset; batch.used = used; - batch.cliprects = intel->pClipRects; - batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.cliprects = NULL; + batch.num_cliprects = 0; batch.DR1 = 0; - batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) | - (((GLuint)intel->drawY) << 16)); + batch.DR4 = 0; if (INTEL_DEBUG & DEBUG_DMA) - fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + fprintf(stderr, "%s: 0x%x..0x%x\n", __FUNCTION__, batch.start, - batch.start + batch.used * 4, - batch.DR4, batch.num_cliprects); + batch.start + batch.used * 4); if (!intel->no_hw) { if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch, @@ -148,8 +144,7 @@ void intel_batch_ioctl( struct intel_context *intel, void intel_cmd_ioctl( struct intel_context *intel, char *buf, - GLuint used, - GLboolean ignore_cliprects) + GLuint used) { drmI830CmdBuffer cmd; @@ -159,17 +154,15 @@ void intel_cmd_ioctl( struct intel_context *intel, cmd.buf = buf; cmd.sz = used; cmd.cliprects = intel->pClipRects; - cmd.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + cmd.num_cliprects = 0; cmd.DR1 = 0; - cmd.DR4 = ((((GLuint)intel->drawX) & 0xffff) | - (((GLuint)intel->drawY) << 16)); + cmd.DR4 = 0; if (INTEL_DEBUG & DEBUG_DMA) - fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + fprintf(stderr, "%s: 0x%x..0x%x\n", __FUNCTION__, 0, - 0 + cmd.sz, - cmd.DR4, cmd.num_cliprects); + 0 + cmd.sz); if (!intel->no_hw) { if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd, diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.h b/src/mesa/drivers/dri/i965/intel_ioctl.h index dcebcb06d1d..df276593626 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.h +++ b/src/mesa/drivers/dri/i965/intel_ioctl.h @@ -35,12 +35,10 @@ int intelEmitIrqLocked( struct intel_context *intel ); void intel_batch_ioctl( struct intel_context *intel, GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects); + GLuint used); void intel_cmd_ioctl( struct intel_context *intel, char *buf, - GLuint used, - GLboolean ignore_cliprects); + GLuint used); #endif diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c new file mode 100644 index 00000000000..5841afaa3ef --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -0,0 +1,350 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portionsalloc + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "image.h" +#include "colormac.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" + + + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + + +/* Unlike the other intel_pixel_* functions, the expectation here is + * that the incoming data is not in a PBO. With the XY_TEXT blit + * method, there's no benefit haveing it in a PBO, but we could + * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit + * PBO bitmaps. I think they are probably pretty rare though - I + * wonder if Xgl uses them? + */ +static const GLubyte *map_pbo( GLcontext *ctx, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + GLubyte *buf; + + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + GL_COLOR_INDEX, GL_BITMAP, + (GLvoid *) bitmap)) { + _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)"); + return NULL; + } + + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); + return NULL; + } + + return ADD_POINTERS(buf, bitmap); +} + +static GLboolean test_bit( const GLubyte *src, + GLuint bit ) +{ + return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0; +} + +static void set_bit( GLubyte *dest, + GLuint bit ) +{ + dest[bit/8] |= 1 << (bit % 8); +} + +static int align(int x, int align) +{ + return (x + align - 1) & ~(align - 1); +} + +/* Extract a rectangle's worth of data from the bitmap. Called + * per-cliprect. + */ +static GLuint get_bitmap_rect(GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap, + GLuint x, GLuint y, + GLuint w, GLuint h, + GLubyte *dest, + GLuint row_align, + GLboolean invert) +{ + GLuint src_offset = (x + unpack->SkipPixels) & 0x7; + GLuint mask = unpack->LsbFirst ? 0 : 7; + GLuint bit = 0; + GLint row, col; + GLint first, last; + GLint incr; + GLuint count = 0; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n", + __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask); + + if (invert) { + first = h-1; + last = 0; + incr = -1; + } + else { + first = 0; + last = h-1; + incr = 1; + } + + /* Require that dest be pre-zero'd. + */ + for (row = first; row != (last+incr); row += incr) { + const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, + width, height, + GL_COLOR_INDEX, GL_BITMAP, + y + row, x); + + for (col = 0; col < w; col++, bit++) { + if (test_bit(rowsrc, (col + src_offset) ^ mask)) { + set_bit(dest, bit ^ 7); + count++; + } + } + + if (row_align) + bit = (bit + row_align - 1) & ~(row_align - 1); + } + + return count; +} + + + + +/* + * Render a bitmap. + */ +static GLboolean +do_blit_bitmap( GLcontext *ctx, + GLint dstx, GLint dsty, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + + union { + GLuint ui; + GLubyte ub[4]; + } color; + + + if (unpack->BufferObj->Name) { + bitmap = map_pbo(ctx, width, height, unpack, bitmap); + if (bitmap == NULL) + return GL_TRUE; /* even though this is an error, we're done */ + } + + UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]); + + /* Does zoom apply to bitmaps? + */ + if (!intel_check_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint srcx = 0, srcy = 0; + GLint orig_screen_x1, orig_screen_y2; + GLuint i; + + + orig_screen_x1 = dPriv->x + dstx; + orig_screen_y2 = dPriv->y + (dPriv->h - dsty); + + /* Do scissoring in GL coordinates: + */ + if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->y + (dPriv->h - dsty - height); + dstx = dPriv->x + dstx; + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + int box_w, box_h; + GLint px, py; + GLuint stipple[32]; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + /* Now go back to GL coordinates to figure out what subset of + * the bitmap we are uploading for this cliprect: + */ + box_w = rect.x2 - rect.x1; + box_h = rect.y2 - rect.y1; + srcx = rect.x1 - orig_screen_x1; + srcy = orig_screen_y2 - rect.y2; + + +#define DY 32 +#define DX 32 + + /* Then, finally, chop it all into chunks that can be + * digested by hardware: + */ + for (py = 0; py < box_h; py += DY) { + for (px = 0; px < box_w; px += DX) { + int h = MIN2(DY, box_h - py); + int w = MIN2(DX, box_w - px); + GLuint sz = align(align(w,8) * h, 64)/8; + + assert(sz <= sizeof(stipple)); + memset(stipple, 0, sz); + + /* May need to adjust this when padding has been introduced in + * sz above: + */ + if (get_bitmap_rect(width, height, unpack, + bitmap, + srcx + px, srcy + py, w, h, + (GLubyte *)stipple, + 8, + GL_TRUE) == 0) + continue; + + /* + */ + intelEmitImmediateColorExpandBlit( intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color.ui, + dst->pitch, + dst->buffer, + 0, + dst->tiled, + rect.x1 + px, + rect.y2 - (py + h), + w, h); + } + } + } + intel->need_flush = GL_TRUE; + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + + if (unpack->BufferObj->Name) { + /* done with PBO so unmap it now */ + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } + + return GL_TRUE; +} + + + + + +/* There are a large number of possible ways to implement bitmap on + * this hardware, most of them have some sort of drawback. Here are a + * few that spring to mind: + * + * Blit: + * - XY_MONO_SRC_BLT_CMD + * - use XY_SETUP_CLIP_BLT for cliprect clipping. + * - XY_TEXT_BLT + * - XY_TEXT_IMMEDIATE_BLT + * - blit per cliprect, subject to maximum immediate data size. + * - XY_COLOR_BLT + * - per pixel or run of pixels + * - XY_PIXEL_BLT + * - good for sparse bitmaps + * + * 3D engine: + * - Point per pixel + * - Translate bitmap to an alpha texture and render as a quad + * - Chop bitmap up into 32x32 squares and render w/polygon stipple. + */ +void +intelBitmap(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * pixels) +{ + if (do_blit_bitmap(ctx, x, y, width, height, + unpack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_Bitmap(ctx, x, y, width, height, unpack, pixels); +} diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c new file mode 100644 index 00000000000..d5d48994529 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c @@ -0,0 +1,240 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "image.h" +#include "mtypes.h" +#include "macros.h" +#include "state.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" + + +static struct intel_region * +copypix_src_region(struct intel_context *intel, GLenum type) +{ + switch (type) { + case GL_COLOR: + return intel_readbuf_region(intel); + case GL_DEPTH: + /* Don't think this is really possible execpt at 16bpp, when we have no stencil. + */ + if (intel->depth_region && intel->depth_region->cpp == 2) + return intel->depth_region; + case GL_STENCIL: + /* Don't think this is really possible. + */ + break; + case GL_DEPTH_STENCIL_EXT: + /* Does it matter whether it is stencil/depth or depth/stencil? + */ + return intel->depth_region; + default: + break; + } + + return NULL; +} + + + + +/** + * Check if any fragment operations are in effect which might effect + * glDraw/CopyPixels. + */ +GLboolean +intel_check_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Could do logicop with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->RenderMode != GL_RENDER || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || /* can do this! */ + ctx->Color.ColorLogicOpEnabled || /* can do this! */ + ctx->Texture._EnabledUnits || + ctx->FragmentProgram._Enabled); +} + + + +/** + * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. + */ +static GLboolean +do_blit_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + + /* Copypixels can be more than a straight copy. Ensure all the + * extra operations are disabled: + */ + if (!intel_check_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + if (!src || !dst) + return GL_FALSE; + + + + intelFlush(&intel->ctx); + +/* intel->vtbl.render_start(intel); */ +/* intel->vtbl.emit_state(intel); */ + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint delta_x = 0; + GLint delta_y = 0; + GLuint i; + + /* Do scissoring in GL coordinates: + */ + if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + GLint dx = dstx - srcx; + GLint dy = dsty - srcy; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + + srcx = dstx - dx; + srcy = dsty - dy; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->h - dsty - height; + srcy = dPriv->h - srcy - height; + dstx += dPriv->x; + dsty += dPriv->y; + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. Dst is clipped with cliprects below. + */ + { + delta_x = srcx - dstx; + delta_y = srcy - dsty; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx = srcx - delta_x; + dsty = srcy - delta_y; + } + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + +/* intel->vtbl.emit_flush(intel, 0); */ + + /* Could do slightly more clipping: Eg, take the intersection of + * the existing set of cliprects and those cliprects translated + * by delta_x, delta_y: + * + * This code will not overwrite other windows, but will + * introduce garbage when copying from obscured window regions. + */ + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + + intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, 0, src->tiled, + dst->pitch, dst->buffer, 0, dst->tiled, + rect.x1 + delta_x, + rect.y1 + delta_y, /* srcx, srcy */ + rect.x1, rect.y1, /* dstx, dsty */ + rect.x2 - rect.x1, rect.y2 - rect.y1); + } + + intel->need_flush = GL_TRUE; + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + return GL_TRUE; +} + +void +intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("fallback to _swrast_CopyPixels\n"); + + _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); +} diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 14b461b1ee7..56e6a792fa2 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -87,7 +87,7 @@ intelMapScreenRegions(__DRIscreenPrivate *sPriv) * the renderbuffer address to point to the beginning of the * renderbuffer. */ - intelScreen->front.map = sPriv->pFB; + intelScreen->front.map = (char *)sPriv->pFB; if (intelScreen->front.map == NULL) { fprintf(stderr, "Failed to find framebuffer mapping\n"); return GL_FALSE; @@ -272,7 +272,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) volatile drmI830Sarea *sarea; if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr,"\nERROR! sizeof(I830DRIRec) (%d) does not match passed size from device driver (%d)\n", sizeof(I830DRIRec), sPriv->devPrivSize); + fprintf(stderr,"\nERROR! sizeof(I830DRIRec) (%ld) does not match passed size from device driver (%d)\n", (unsigned long)sizeof(I830DRIRec), sPriv->devPrivSize); return GL_FALSE; } diff --git a/src/mesa/drivers/dri/i965/intel_span.c b/src/mesa/drivers/dri/i965/intel_span.c index c68def5a9f9..60fbeccdc54 100644 --- a/src/mesa/drivers/dri/i965/intel_span.c +++ b/src/mesa/drivers/dri/i965/intel_span.c @@ -35,6 +35,7 @@ #include "intel_span.h" #include "intel_ioctl.h" #include "intel_tex.h" +#include "intel_batchbuffer.h" #include "swrast/swrast.h" #undef DBG @@ -207,6 +208,16 @@ void intelSpanRenderStart( GLcontext *ctx ) { struct intel_context *intel = intel_context(ctx); + if (intel->need_flush) { + LOCK_HARDWARE(intel); + intel->vtbl.emit_flush(intel, 0); + intel_batchbuffer_flush(intel->batch); + intel->need_flush = 0; + UNLOCK_HARDWARE(intel); + intelFinish(&intel->ctx); + } + + LOCK_HARDWARE(intel); /* Just map the framebuffer and all textures. Bufmgr code will diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c index a471f67c510..ec6e0465d4a 100644 --- a/src/mesa/drivers/dri/i965/intel_state.c +++ b/src/mesa/drivers/dri/i965/intel_state.c @@ -182,39 +182,6 @@ static void intelClearColor(GLcontext *ctx, const GLfloat color[4]) } -static void intelCalcViewport( GLcontext *ctx ) -{ - struct intel_context *intel = intel_context(ctx); - const GLfloat *v = ctx->Viewport._WindowMap.m; - GLfloat *m = intel->ViewportMatrix.m; - GLint h = 0; - - if (intel->driDrawable) - h = intel->driDrawable->h + SUBPIXEL_Y; - - /* See also intel_translate_vertex. SUBPIXEL adjustments can be done - * via state vars, too. - */ - m[MAT_SX] = v[MAT_SX]; - m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; - m[MAT_SY] = - v[MAT_SY]; - m[MAT_TY] = - v[MAT_TY] + h; - m[MAT_SZ] = v[MAT_SZ] * intel->depth_scale; - m[MAT_TZ] = v[MAT_TZ] * intel->depth_scale; -} - -static void intelViewport( GLcontext *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height ) -{ - intelCalcViewport( ctx ); -} - -static void intelDepthRange( GLcontext *ctx, - GLclampd nearval, GLclampd farval ) -{ - intelCalcViewport( ctx ); -} /* Fallback to swrast for select and feedback. */ @@ -228,8 +195,6 @@ static void intelRenderMode( GLcontext *ctx, GLenum mode ) void intelInitStateFuncs( struct dd_function_table *functions ) { functions->RenderMode = intelRenderMode; - functions->Viewport = intelViewport; - functions->DepthRange = intelDepthRange; functions->ClearColor = intelClearColor; } diff --git a/src/mesa/drivers/dri/i965/intel_structs.h b/src/mesa/drivers/dri/i965/intel_structs.h new file mode 100644 index 00000000000..522e3bd92c2 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_structs.h @@ -0,0 +1,132 @@ +#ifndef INTEL_STRUCTS_H +#define INTEL_STRUCTS_H + +struct br0 { + GLuint length:8; + GLuint pad0:3; + GLuint dst_tiled:1; + GLuint pad1:8; + GLuint write_rgb:1; + GLuint write_alpha:1; + GLuint opcode:7; + GLuint client:3; +}; + + +struct br13 { + GLint dest_pitch:16; + GLuint rop:8; + GLuint color_depth:2; + GLuint pad1:3; + GLuint mono_source_transparency:1; + GLuint clipping_enable:1; + GLuint pad0:1; +}; + + + +/* This is an attempt to move some of the 2D interaction in this + * driver to using structs for packets rather than a bunch of #defines + * and dwords. + */ +struct xy_color_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint color; +}; + +struct xy_src_copy_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + + struct { + GLuint src_x1:16; + GLuint src_y1:16; + } dw5; + + struct { + GLint src_pitch:16; + GLuint pad:16; + } dw6; + + GLuint src_base_addr; +}; + +struct xy_setup_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint clip_x1:16; + GLuint clip_y1:16; + } dw2; + + struct { + GLuint clip_x2:16; + GLuint clip_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint background_color; + GLuint foreground_color; + GLuint pattern_base_addr; +}; + + +struct xy_text_immediate_blit { + struct { + GLuint length:8; + GLuint pad2:3; + GLuint dst_tiled:1; + GLuint pad1:4; + GLuint byte_packed:1; + GLuint pad0:5; + GLuint opcode:7; + GLuint client:3; + } dw0; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw1; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw2; + + /* Src bitmap data follows as inline dwords. + */ +}; + + +#define CLIENT_2D 0x2 +#define OPCODE_XY_SETUP_BLT 0x1 +#define OPCODE_XY_COLOR_BLT 0x50 +#define OPCODE_XY_TEXT_IMMEDIATE_BLT 0x31 + +#endif diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 5f65242458a..91ae0970a04 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -166,12 +166,15 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, * target, imageFormat, etc. */ if (intelObj->mt && - (intelObj->mt->first_level != intelObj->firstLevel || - intelObj->mt->last_level != intelObj->lastLevel || + (intelObj->mt->target != intelObj->base.Target || intelObj->mt->internal_format != firstImage->InternalFormat || + intelObj->mt->first_level != intelObj->firstLevel || + intelObj->mt->last_level != intelObj->lastLevel || intelObj->mt->width0 != firstImage->Width || intelObj->mt->height0 != firstImage->Height || - intelObj->mt->depth0 != firstImage->Depth)) + intelObj->mt->depth0 != firstImage->Depth || + intelObj->mt->cpp != firstImage->TexFormat->TexelBytes || + intelObj->mt->compressed != firstImage->IsCompressed)) { intel_miptree_destroy(intel, intelObj->mt); intelObj->mt = NULL; |