From cfc21190af1038f204d38ab4764a9c731b0323a5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:28:01 -0700 Subject: Convert i915tex to the new interface and make it compile. --- src/mesa/drivers/dri/i965/intel_context.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 10eb9a2e28..422eb96097 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -656,7 +656,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; if (intel->aub_wrap) { - bm_fake_NotifyContendedLockTake( intel ); + bm_fake_NotifyContendedLockTake( intel ); intel->vtbl.lost_hardware( intel ); intel->vtbl.aub_wrap(intel); intel->aub_wrap = 0; @@ -667,7 +667,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->vtbl.lost_hardware( intel ); } - /* Make sure nothing has been emitted prior to getting the lock: + /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -700,8 +700,6 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) intel->vtbl.note_unlock( intel ); intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); _glthread_UNLOCK_MUTEX(lockMutex); } -- cgit v1.2.3 From 60179434d15989b81e2d4757f34033009184a678 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Mon, 30 Jul 2007 10:18:11 +0800 Subject: ARB sprite point support on i965 --- src/mesa/drivers/dri/i965/brw_sf.c | 15 ++++-- src/mesa/drivers/dri/i965/brw_sf.h | 9 +++- src/mesa/drivers/dri/i965/brw_sf_emit.c | 80 +++++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_context.c | 5 ++ 4 files changed, 105 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index d5175399d6..73232b3c7c 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -74,6 +74,11 @@ static void compile_sf_prog( struct brw_context *brw, if (c.key.attrs & (1<= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) { + c.point_attrs[i].CoordReplace = + brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0]; + } else + c.point_attrs[i].CoordReplace = GL_FALSE; idx++; } @@ -90,7 +95,10 @@ static void compile_sf_prog( struct brw_context *brw, break; case SF_POINTS: c.nr_verts = 1; - brw_emit_point_setup( &c ); + if (key->do_point_sprite) + brw_emit_point_sprite_setup( &c ); + else + brw_emit_point_setup( &c ); break; case SF_UNFILLED_TRIS: c.nr_verts = 3; @@ -162,7 +170,8 @@ static void upload_sf_prog( struct brw_context *brw ) break; } - + key.do_point_sprite = brw->attribs.Point->PointSprite; + key.SpriteOrigin = brw->attribs.Point->SpriteOrigin; /* _NEW_LIGHT */ key.do_flat_shading = (brw->attribs.Light->ShadeModel == GL_FLAT); key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide); @@ -179,7 +188,7 @@ static void upload_sf_prog( struct brw_context *brw ) const struct brw_tracked_state brw_sf_prog = { .dirty = { - .mesa = (_NEW_LIGHT|_NEW_POLYGON), + .mesa = (_NEW_LIGHT|_NEW_POLYGON|_NEW_POINT), .brw = (BRW_NEW_REDUCED_PRIMITIVE), .cache = CACHE_NEW_VS_PROG }, diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index fb72b84ba8..e374e372bb 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -50,9 +50,14 @@ struct brw_sf_prog_key { GLuint do_flat_shading:1; GLuint attrs:16; GLuint frontface_ccw:1; - GLuint pad:11; + GLuint do_point_sprite:1; + GLuint pad:10; + GLenum SpriteOrigin; }; +struct brw_sf_point_tex { + GLboolean CoordReplace; +}; struct brw_sf_compile { struct brw_compile func; @@ -94,12 +99,14 @@ struct brw_sf_compile { GLubyte attr_to_idx[VERT_RESULT_MAX]; GLubyte idx_to_attr[VERT_RESULT_MAX]; + struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX]; }; void brw_emit_tri_setup( struct brw_sf_compile *c ); void brw_emit_line_setup( struct brw_sf_compile *c ); void brw_emit_point_setup( struct brw_sf_compile *c ); +void brw_emit_point_sprite_setup( struct brw_sf_compile *c ); void brw_emit_anyprim_setup( struct brw_sf_compile *c ); #endif diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index cbaf018c44..7ecf9bb560 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -497,6 +497,86 @@ void brw_emit_line_setup( struct brw_sf_compile *c ) } } +void brw_emit_point_sprite_setup( struct brw_sf_compile *c ) +{ + struct brw_compile *p = &c->func; + GLuint i; + + c->nr_verts = 1; + alloc_regs(c); + copy_z_inv_w(c); + for (i = 0; i < c->nr_setup_regs; i++) + { + struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]]; + struct brw_reg a0 = offset(c->vert[0], i); + GLushort pc, pc_persp, pc_linear; + GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); + + if (pc_persp) + { + if (!tex->CoordReplace) { + brw_set_predicate_control_flag_value(p, pc_persp); + brw_MUL(p, a0, a0, c->inv_w[0]); + } + } + + if (tex->CoordReplace) { + /* Caculate 1.0/PointWidth */ + brw_math(&c->func, + c->tmp, + BRW_MATH_FUNCTION_INV, + BRW_MATH_SATURATE_NONE, + 0, + c->dx0, + BRW_MATH_DATA_SCALAR, + BRW_MATH_PRECISION_FULL); + + if (c->key.SpriteOrigin == GL_UPPER_LEFT) { + brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); + brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); + brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0])); + brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); + } else { + brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); + brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); + brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]); + brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); + } + } else { + brw_MOV(p, c->m1Cx, brw_imm_ud(0)); + brw_MOV(p, c->m2Cy, brw_imm_ud(0)); + } + + { + brw_set_predicate_control_flag_value(p, pc); + if (tex->CoordReplace) { + if (c->key.SpriteOrigin == GL_UPPER_LEFT) { + brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0)); + brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0)); + } + else + brw_MOV(p, c->m3C0, brw_imm_f(0.0)); + } else { + brw_MOV(p, c->m3C0, a0); /* constant value */ + } + + /* Copy m0..m3 to URB. + */ + brw_urb_WRITE(p, + brw_null_reg(), + 0, + brw_vec8_grf(0, 0), + 0, /* allocate */ + 1, /* used */ + 4, /* msg len */ + 0, /* response len */ + last, /* eot */ + last, /* writes complete */ + i*4, /* urb destination offset */ + BRW_URB_SWIZZLE_TRANSPOSE); + } + } +} /* Points setup - several simplifications as all attributes are * constant across the face of the point (point sprites excluded!) diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 4f51fefe0f..a8204ee4b8 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -66,6 +66,7 @@ int INTEL_DEBUG = (0); #endif +#define need_GL_NV_point_sprite #define need_GL_ARB_multisample #define need_GL_ARB_point_parameters #define need_GL_ARB_texture_compression @@ -81,6 +82,7 @@ int INTEL_DEBUG = (0); #define need_GL_EXT_fog_coord #define need_GL_EXT_multi_draw_arrays #define need_GL_EXT_secondary_color +#define need_GL_EXT_point_parameters #include "extension_helper.h" #ifndef VERBOSE @@ -146,6 +148,7 @@ const struct dri_extension card_extensions[] = { "GL_ARB_multisample", GL_ARB_multisample_functions }, { "GL_ARB_multitexture", NULL }, { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, + { "GL_NV_point_sprite", GL_NV_point_sprite_functions }, { "GL_ARB_texture_border_clamp", NULL }, { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, { "GL_ARB_texture_cube_map", NULL }, @@ -158,6 +161,8 @@ const struct dri_extension card_extensions[] = { "GL_NV_texture_rectangle", NULL }, { "GL_EXT_texture_rectangle", NULL }, { "GL_ARB_texture_rectangle", NULL }, + { "GL_ARB_point_sprite", NULL}, + { "GL_ARB_point_parameters", NULL }, { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, -- cgit v1.2.3 From 69337ed098bdf0def6820ccdb121b08c0e139085 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 31 Jul 2007 09:10:31 +0800 Subject: i965: Use I16_UNORM instead of L16_UNORM (bug 11742) --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') 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 d24c618a66..d54623175b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -114,7 +114,7 @@ static GLuint translate_tex_format( GLuint mesa_format ) return BRW_SURFACEFORMAT_FXT1; case MESA_FORMAT_Z16: - return BRW_SURFACEFORMAT_L16_UNORM; + return BRW_SURFACEFORMAT_I16_UNORM; case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGB_DXT1: -- cgit v1.2.3 From e66757c8babe6968ea2e506d1214c8063cbd0760 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 31 Jul 2007 22:40:42 +0800 Subject: i965: fix bad casts in do_blit_bitmap to support WindowPos correctly --- src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index 421fcc5e51..f3f062e651 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -226,10 +226,10 @@ do_blit_bitmap( GLcontext *ctx, 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; + dest_rect.x1 = dstx < 0 ? 0 : dstx; + dest_rect.y1 = dsty < 0 ? 0 : dsty; + dest_rect.x2 = dstx + width < 0 ? 0 : dstx + width; + dest_rect.y2 = dsty + height < 0 ? 0 : dsty + height; for (i = 0; i < nbox; i++) { drm_clip_rect_t rect; -- cgit v1.2.3 From a6dad044e24358af9fe5764ca7b342f4ed4804db Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 1 Aug 2007 11:08:05 +0800 Subject: fix fd.o bug #11788, max point size --- src/mesa/drivers/dri/i965/brw_sf_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 9a6e5f5f19..307fb63785 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -185,7 +185,7 @@ static void upload_sf_unit( struct brw_context *brw ) /* _NEW_POINT */ sf.sf6.point_rast_rule = 1; /* opengl conventions */ /* XXX clamp max depends on AA vs. non-AA */ - sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 3.0) * (1<<3); + sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 255.0) * (1<<3); sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated; /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons: -- cgit v1.2.3 From 6bf81a5edfa287a396f30188b107ff1761039f3f Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 2 Aug 2007 14:26:12 +0800 Subject: EXT_texture_sRGB support on i965 --- src/mesa/drivers/dri/i965/brw_tex.c | 19 +++++++++++++++++ src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 5 +++++ src/mesa/drivers/dri/i965/intel_context.c | 1 + src/mesa/main/texcompress_s3tc.c | 26 ++++++++++++++++++++++++ src/mesa/main/texformat.h | 2 ++ 5 files changed, 53 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index 9d4b9867d2..f8d0c3fb6f 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -168,6 +168,25 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_DEPTH_COMPONENT32: return &_mesa_texformat_z16; + case GL_SRGB_EXT: + case GL_SRGB8_EXT: + case GL_SRGB_ALPHA_EXT: + case GL_SRGB8_ALPHA8_EXT: + case GL_SLUMINANCE_EXT: + case GL_SLUMINANCE8_EXT: + case GL_SLUMINANCE_ALPHA_EXT: + case GL_SLUMINANCE8_ALPHA8_EXT: + case GL_COMPRESSED_SRGB_EXT: + case GL_COMPRESSED_SRGB_ALPHA_EXT: + case GL_COMPRESSED_SLUMINANCE_EXT: + case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: + return &_mesa_texformat_srgb_dxt1; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return &_mesa_texformat_srgb_dxt1; + default: fprintf(stderr, "unexpected texture format %s in %s\n", _mesa_lookup_enum_by_nr(internalFormat), 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 d54623175b..acf5771e77 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -120,6 +120,11 @@ static GLuint translate_tex_format( GLuint mesa_format ) case MESA_FORMAT_RGB_DXT1: return BRW_SURFACEFORMAT_DXT1_RGB; + case MESA_FORMAT_SRGBA8: + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB; + case MESA_FORMAT_SRGB_DXT1: + return BRW_SURFACEFORMAT_BC1_UNORM_SRGB; + default: assert(0); return 0; diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index a8204ee4b8..eafe809d3a 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -182,6 +182,7 @@ const struct dri_extension card_extensions[] = { "GL_EXT_texture_env_dot3", NULL }, { "GL_EXT_texture_filter_anisotropic", NULL }, { "GL_EXT_texture_lod_bias", NULL }, + { "GL_EXT_texture_sRGB", NULL }, { "GL_3DFX_texture_compression_FXT1", NULL }, { "GL_APPLE_client_storage", NULL }, { "GL_MESA_pack_invert", NULL }, diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index c48063d919..4f329cdf59 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -577,6 +577,32 @@ const struct gl_texture_format _mesa_texformat_rgb_dxt1 = { NULL /* StoreTexel */ }; +#if FEATURE_EXT_texture_sRGB +const struct gl_texture_format _mesa_texformat_srgb_dxt1 = { + MESA_FORMAT_SRGB_DXT1, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 4, /*approx*/ /* RedBits */ + 4, /*approx*/ /* GreenBits */ + 4, /*approx*/ /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 0, /* StencilBits */ + 0, /* TexelBytes */ + texstore_rgb_dxt1, /* StoreTexImageFunc */ + NULL, /*impossible*/ /* FetchTexel1D */ + fetch_texel_2d_rgb_dxt1, /* FetchTexel2D */ + NULL, /*impossible*/ /* FetchTexel3D */ + NULL, /*impossible*/ /* FetchTexel1Df */ + fetch_texel_2d_f_rgb_dxt1, /* FetchTexel2Df */ + NULL, /*impossible*/ /* FetchTexel3Df */ + NULL /* StoreTexel */ +}; +#endif + const struct gl_texture_format _mesa_texformat_rgba_dxt1 = { MESA_FORMAT_RGBA_DXT1, /* MesaFormat */ GL_RGBA, /* BaseFormat */ diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 55851db701..82023b946d 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -97,6 +97,7 @@ enum _format { MESA_FORMAT_SRGBA8, MESA_FORMAT_SL8, MESA_FORMAT_SLA8, + MESA_FORMAT_SRGB_DXT1, /*@}*/ #endif @@ -168,6 +169,7 @@ extern const struct gl_texture_format _mesa_texformat_srgb8; extern const struct gl_texture_format _mesa_texformat_srgba8; extern const struct gl_texture_format _mesa_texformat_sl8; extern const struct gl_texture_format _mesa_texformat_sla8; +extern const struct gl_texture_format _mesa_texformat_srgb_dxt1; /*@}*/ #endif -- cgit v1.2.3 From 246d1d2522858a1bcf525d64ad165f9af11a2b4d Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 2 Aug 2007 14:35:59 +0800 Subject: Fix previous commit --- src/mesa/drivers/dri/i965/brw_tex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index f8d0c3fb6f..a62395a432 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -180,7 +180,7 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_COMPRESSED_SRGB_ALPHA_EXT: case GL_COMPRESSED_SLUMINANCE_EXT: case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - return &_mesa_texformat_srgb_dxt1; + return &_mesa_texformat_srgba8; case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: -- cgit v1.2.3 From 505453a04e8ba5e394c34401bd9ec320ffce2423 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 2 Aug 2007 15:27:13 +0800 Subject: fix fd.o bug #11804 glPolygonMode with point sprite on i965 --- src/mesa/drivers/dri/i965/brw_defines.h | 2 ++ src/mesa/drivers/dri/i965/brw_sf_emit.c | 9 +++++++++ src/mesa/drivers/dri/i965/brw_sf_state.c | 2 ++ 3 files changed, 13 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index e8f878a701..9bb7d2f703 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -240,6 +240,8 @@ #define BRW_FRONTWINDING_CW 0 #define BRW_FRONTWINDING_CCW 1 +#define BRW_SPRITE_POINT_ENABLE 16 + #define BRW_INDEX_BYTE 0 #define BRW_INDEX_WORD 1 #define BRW_INDEX_DWORD 2 diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index 7ecf9bb560..22911a4649 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -641,6 +641,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) struct brw_compile *p = &c->func; struct brw_reg ip = brw_ip_reg(); struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0); + struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0); struct brw_reg primmask; struct brw_instruction *jmp; struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); @@ -681,6 +682,14 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) } brw_land_fwd_jump(p, jmp); + brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); + brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<attribs.Point->PointSprite; sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 255.0) * (1<<3); sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated; -- cgit v1.2.3 From 46ac4531966e0edf802919def935c4125342e8bf Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Aug 2007 11:37:57 +0100 Subject: Fix typo in logic for unalias2() --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 6eb11b19ad..d00f0c71a8 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -201,7 +201,7 @@ static void unalias2( struct brw_vs_compile *c, struct brw_reg, struct brw_reg )) { - if ((dst.file == arg0.file && dst.nr == arg0.nr) && + if ((dst.file == arg0.file && dst.nr == arg0.nr) || (dst.file == arg1.file && dst.nr == arg1.nr)) { struct brw_compile *p = &c->func; struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask); -- cgit v1.2.3 From 2cafd749b8e4fa44863c176389f7201c7f74eca9 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 10 Aug 2007 15:14:12 +0800 Subject: i965: set mt->cpp differently with compressed texture --- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/i965/intel_tex_validate.c | 36 +++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 8486086b27..d7b1946ce3 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -75,7 +75,7 @@ struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel, mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; - mt->cpp = compressed ? 2 : cpp; + mt->cpp = cpp; mt->compressed = compressed; switch (intel->intelScreen->deviceID) { diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 44ee94614d..8c05e7cdab 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -122,6 +122,29 @@ static void intel_texture_invalidate_cb( struct intel_context *intel, intel_texture_invalidate( (struct intel_texture_object *) ptr ); } +#include "texformat.h" +static GLuint intel_compressed_num_bytes(GLenum mesaFormat) +{ + GLuint bytes = 0; + + switch (mesaFormat) { + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + bytes = 2; + break; + + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + bytes = 4; + + default: + break; + } + + return bytes; +} /* */ @@ -132,7 +155,8 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint face, i; GLuint nr_faces = 0; struct gl_texture_image *firstImage; - + GLuint cpp = 0; + if( tObj == intel->frame_buffer_texobj ) return GL_FALSE; @@ -165,6 +189,12 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, + if (firstImage->IsCompressed) { + cpp = intel_compressed_num_bytes(firstImage->TexFormat->MesaFormat); + } else { + cpp = firstImage->TexFormat->TexelBytes; + } + /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. */ @@ -176,7 +206,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, intelObj->mt->width0 != firstImage->Width || intelObj->mt->height0 != firstImage->Height || intelObj->mt->depth0 != firstImage->Depth || - intelObj->mt->cpp != firstImage->TexFormat->TexelBytes || + intelObj->mt->cpp != cpp || intelObj->mt->compressed != firstImage->IsCompressed)) { intel_miptree_destroy(intel, intelObj->mt); @@ -199,7 +229,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, firstImage->Width, firstImage->Height, firstImage->Depth, - firstImage->TexFormat->TexelBytes, + cpp, firstImage->IsCompressed); /* Tell the buffer manager that we will manage the backing -- cgit v1.2.3 From 8ea66fa2ec9eeb6a7e869ff08d713f5e77d795e0 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 10 Aug 2007 16:23:14 +0800 Subject: i965/i915tex: applying right alignment to compressed texture, which make small textures(4x4,2x2,1x1) work well. --- src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 9 ++++-- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 16 ++++++++-- src/mesa/drivers/dri/intel/intel_tex_layout.c | 38 +++++++++++++++++++++--- src/mesa/drivers/dri/intel/intel_tex_layout.h | 1 + 4 files changed, 55 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c index 843a78eb82..fc38a28290 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -325,6 +325,7 @@ intel_miptree_image_data(struct intel_context *intel, } } +extern GLuint intel_compressed_alignment(GLenum); /* Copy mipmap image between trees */ void @@ -342,8 +343,12 @@ intel_miptree_image_copy(struct intel_context *intel, const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); GLuint i; - if (dst->compressed) - height /= 4; + if (dst->compressed) { + GLuint alignment = intel_compressed_alignment(dst->internal_format); + height = (height + 3) / 4; + width = ((width + alignment - 1) & ~(alignment - 1)); + } + for (i = 0; i < depth; i++) { intel_region_copy(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index d7b1946ce3..f24f234682 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -211,7 +211,7 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, - +extern GLuint intel_compressed_alignment(GLenum); /* Upload data for a particular image. */ GLboolean intel_miptree_image_data(struct intel_context *intel, @@ -226,6 +226,16 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, GLuint dst_offset = intel_miptree_image_offset(dst, face, level); const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); GLuint i; + GLuint width, height, alignment; + + width = dst->level[level].width; + height = dst->level[level].height; + + if (dst->compressed) { + alignment = intel_compressed_alignment(dst->internal_format); + width = ((width + alignment - 1) & ~(alignment - 1)); + height = (height + 3) / 4; + } DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { @@ -237,8 +247,8 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, src, src_row_pitch, 0, 0, /* source x,y */ - dst->level[level].width, - dst->level[level].height)) + width, + height)) return GL_FALSE; src += src_image_pitch; } diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index fcb5cc3906..fdecd3e186 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -40,6 +40,23 @@ static int align(int value, int alignment) return (value + alignment - 1) & ~(alignment - 1); } +GLuint intel_compressed_alignment(GLenum internalFormat) +{ + GLuint alignment = 4; + + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + alignment = 8; + break; + + default: + break; + } + + return alignment; +} + void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) { GLint align_h = 2, align_w = 4; @@ -51,17 +68,30 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) mt->pitch = mt->width0; + if (mt->compressed) { + align_w = intel_compressed_alignment(mt->internal_format); + mt->pitch = align(mt->width0, align_w); + } + /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ if (mt->first_level != mt->last_level) { - GLuint mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); + GLuint mip1_width; + + if (mt->compressed) { + mip1_width = align(minify(mt->width0), align_w) + + align(minify(minify(mt->width0)), align_w); + } else { + mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + } - if (mip1_width > mt->width0) - mt->pitch = mip1_width; + if (mip1_width > mt->pitch) { + mt->pitch = mip1_width; + } } /* Pitch must be a whole number of dwords, even though we diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 1e37f8f525..99d41c3629 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -39,3 +39,4 @@ static GLuint minify( GLuint d ) } extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ); +extern GLuint intel_compressed_alignment(GLenum); -- cgit v1.2.3 From db928291dcbda2a820dbb1668c43d2fb4266be7c Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 10 Aug 2007 16:37:30 +0800 Subject: i965: roland's DXTn format texture patch(bug10347) --- src/mesa/drivers/dri/i965/brw_tex.c | 12 +++++++++--- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 12 ++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index a62395a432..ad29316a42 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -154,13 +154,19 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_RGB_S3TC: case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + case GL_RGBA_S3TC: case GL_RGBA4_S3TC: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return &_mesa_texformat_rgb_dxt1; /* there is no rgba support? */ + return &_mesa_texformat_rgba_dxt5; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: 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 acf5771e77..0a45164a0f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -116,9 +116,17 @@ static GLuint translate_tex_format( GLuint mesa_format ) case MESA_FORMAT_Z16: return BRW_SURFACEFORMAT_I16_UNORM; - case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGB_DXT1: - return BRW_SURFACEFORMAT_DXT1_RGB; + return BRW_SURFACEFORMAT_DXT1_RGB; + + case MESA_FORMAT_RGBA_DXT1: + return BRW_SURFACEFORMAT_BC1_UNORM; + + case MESA_FORMAT_RGBA_DXT3: + return BRW_SURFACEFORMAT_BC2_UNORM; + + case MESA_FORMAT_RGBA_DXT5: + return BRW_SURFACEFORMAT_BC3_UNORM; case MESA_FORMAT_SRGBA8: return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB; -- cgit v1.2.3 From 88451b04e9cd39db9cc9315aaf69e074614f22f9 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 13 Aug 2007 17:16:27 +0800 Subject: i965: fix projtex_mask projtex_mask is only an 8bit field, and wm.input_size_masks includes other attributes' information, therefore right shift is needed. --- src/mesa/drivers/dri/i965/brw_wm.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_fp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 1497dc7968..904c00bef8 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -285,7 +285,7 @@ static void brw_wm_populate_key( struct brw_context *brw, /* BRW_NEW_WM_INPUT_DIMENSIONS */ - key->projtex_mask = brw->wm.input_size_masks[4-1]; + key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS); /* _NEW_LIGHT */ key->flat_shade = (brw->attribs.Light->ShadeModel == GL_FLAT); diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index ff97d87dc4..62bb081206 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -660,7 +660,7 @@ static GLboolean projtex( struct brw_wm_compile *c, return 0; /* ut2004 gun rendering !?! */ else if (src.File == PROGRAM_INPUT && GET_SWZ(src.Swizzle, W) == W && - (c->key.projtex_mask & (1<key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0) return 0; else return 1; -- cgit v1.2.3 From ab999608582534bb5187a786b2ea437167f2d8a4 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 15 Aug 2007 13:28:00 +0800 Subject: i965: use BRW_TEXCOORDMODE_CLAMP instead of BRW_TEXCOORDMODE_CLAMP_BORDER to implement GL_CLAMP --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 93d4cfc3a5..83a4b02e48 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -54,7 +54,7 @@ static GLuint translate_wrap_mode( GLenum wrap ) case GL_REPEAT: return BRW_TEXCOORDMODE_WRAP; case GL_CLAMP: - return BRW_TEXCOORDMODE_CLAMP_BORDER; /* conform likes it this way */ + return BRW_TEXCOORDMODE_CLAMP; case GL_CLAMP_TO_EDGE: return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */ case GL_CLAMP_TO_BORDER: -- cgit v1.2.3 From 00b86ecf6f2f936bad6d628622ea5546c780ab8d Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 17 Aug 2007 12:42:52 -0400 Subject: i965: align width/height for volume texture --- src/mesa/drivers/dri/i965/brw_tex_layout.c | 46 +++++++++++++++++++-------- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 1 + 2 files changed, 34 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index af1ad0f1ef..2094a1c8ad 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -37,6 +37,7 @@ #include "intel_tex_layout.h" #include "macros.h" +#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1)) GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) { @@ -53,11 +54,20 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) GLuint pack_x_pitch, pack_x_nr; GLuint pack_y_pitch; GLuint level; + GLuint align_h = 2; + GLuint align_w = 4; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; mt->total_height = 0; + + if (mt->compressed) { + align_w = intel_compressed_alignment(mt->internal_format); + mt->pitch = ALIGN(width, align_w); + pack_y_pitch = (height + 3) / 4; + } else { + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + pack_y_pitch = ALIGN(mt->height0, align_h); + } - pack_y_pitch = MAX2(mt->height0, 2); pack_x_pitch = mt->pitch; pack_x_nr = 1; @@ -83,20 +93,30 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) mt->total_height += y; - - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - } - width = minify(width); height = minify(height); depth = minify(depth); + + if (mt->compressed) { + pack_y_pitch = (height + 3) / 4; + + if (pack_x_pitch > ALIGN(width, align_w)) { + pack_x_pitch = ALIGN(width, align_w); + pack_x_nr <<= 1; + } + } else { + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + pack_y_pitch = ALIGN(pack_y_pitch, align_h); + } + } + } break; } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index f24f234682..0fb33e27f4 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -233,6 +233,7 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, if (dst->compressed) { alignment = intel_compressed_alignment(dst->internal_format); + src_row_pitch = ((src_row_pitch + alignment - 1) & ~(alignment - 1)); width = ((width + alignment - 1) & ~(alignment - 1)); height = (height + 3) / 4; } -- cgit v1.2.3 From c235cc71a296e63f65cafcc95839119cf3cf2a63 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 28 Aug 2007 11:35:52 -0400 Subject: i965: flush batch buffer when getting the maximum. This makes some 3D programs such as pymol work well. --- src/mesa/drivers/dri/i965/brw_draw.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 0c64d7e756..5ca9b2f549 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -331,6 +331,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, else { /* Otherwise, explicitly do the cliprects at this point: */ + GLuint nprims = 0; for (j = 0; j < brw->intel.numClipRects; j++) { brw_emit_cliprect(brw, &brw->intel.pClipRects[j]); @@ -338,6 +339,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, */ for (i = 0; i < nr_prims; i++) { brw_emit_prim(brw, &prim[i]); + + if (++nprims == VBO_MAX_PRIM) { + intel_batchbuffer_flush(brw->intel.batch); + nprims = 0; + } } } } -- cgit v1.2.3 From 410d8f7cdb40889e66f5c6794878ad9a5f572ee7 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 29 Aug 2007 10:13:10 -0400 Subject: i965: samplers group in fours in WM_STATE. fix bug#9415 --- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index ff5cb31bdd..5b4f2abd0e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -117,7 +117,7 @@ static void upload_wm_unit(struct brw_context *brw ) wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; /* CACHE_NEW_SAMPLER */ - wm.wm4.sampler_count = brw->wm.sampler_count; + wm.wm4.sampler_count = (brw->wm.sampler_count + 1) / 4; wm.wm4.sampler_state_pointer = brw->wm.sampler_gs_offset >> 5; /* BRW_NEW_FRAGMENT_PROGRAM */ -- cgit v1.2.3 From f6a89e1884535a6136900febc163ee930c1d2179 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 29 Aug 2007 13:03:34 -0400 Subject: i965: check NULL pointer. fix bug#12193 --- src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index f3f062e651..23f381fe91 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -174,6 +174,8 @@ do_blit_bitmap( GLcontext *ctx, GLubyte ub[4]; } color; + if (!dst) + return GL_FALSE; if (unpack->BufferObj->Name) { bitmap = map_pbo(ctx, width, height, unpack, bitmap); -- cgit v1.2.3 From bad6e175cf59cce630c37d73f6e71f3a4de50ae6 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 29 Aug 2007 15:11:10 -0400 Subject: i965: store read drawable info in intel_context. Some OpenGL operations are based on read drawable. fix bug#10136. --- src/mesa/drivers/dri/i965/intel_context.c | 4 ++++ src/mesa/drivers/dri/i965/intel_context.h | 1 + src/mesa/drivers/dri/i965/intel_pixel_copy.c | 5 +++-- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index eafe809d3a..1fbf571184 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -576,6 +576,10 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; + if (intel->driReadDrawable != driReadPriv) { + intel->driReadDrawable = driReadPriv; + } + if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 406f8483dc..ae25592908 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -234,6 +234,7 @@ struct intel_context int driFd; __DRIdrawablePrivate *driDrawable; + __DRIdrawablePrivate *driReadDrawable; __DRIscreenPrivate *driScreen; intelScreenPrivate *intelScreen; volatile drmI830Sarea *sarea; diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c index 58dc49505f..3bdf2fb479 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c @@ -231,6 +231,7 @@ do_blit_copypixels(GLcontext * ctx, if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIdrawablePrivate *dReadPriv = intel->driReadDrawable; drm_clip_rect_t *box = dPriv->pClipRects; drm_clip_rect_t dest_rect; GLint nbox = dPriv->numClipRects; @@ -262,8 +263,8 @@ do_blit_copypixels(GLcontext * ctx, srcy = dPriv->h - srcy - height; dstx += dPriv->x; dsty += dPriv->y; - srcx += dPriv->x; - srcy += dPriv->y; + srcx += dReadPriv->x; + srcy += dReadPriv->y; /* Clip against the source region. This is the only source * clipping we do. Dst is clipped with cliprects below. -- cgit v1.2.3 From 1dd94a63ace0c6133f80191ba3b3e5f56f86c8fe Mon Sep 17 00:00:00 2001 From: David Moore Date: Thu, 30 Aug 2007 14:43:30 -0700 Subject: Bug #10571: Fix 965 line clipping when neither vertex needs clipping. --- src/mesa/drivers/dri/i965/brw_clip_line.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 83182270ea..0103be4345 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -130,6 +130,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) struct brw_instruction *plane_loop; struct brw_instruction *plane_active; struct brw_instruction *is_negative; + struct brw_instruction *is_neg2; struct brw_instruction *not_culled; struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); @@ -183,13 +184,20 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) /* Coming back in. We know that both cannot be negative * because the line would have been culled in that case. */ - brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); - brw_math_invert(p, c->reg.t, c->reg.t); - brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); - brw_MOV(p, c->reg.t0, c->reg.t); - brw_set_predicate_control(p, BRW_PREDICATE_NONE); + /* If both are positive, do nothing */ + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); + is_neg2 = brw_IF(p, BRW_EXECUTE_1); + { + brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); + brw_math_invert(p, c->reg.t, c->reg.t); + brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); + + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); + brw_MOV(p, c->reg.t0, c->reg.t); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + brw_ENDIF(p, is_neg2); } brw_ENDIF(p, is_negative); } -- cgit v1.2.3 From 22bc3cdd49eb81d48ad4b8f06be0b9a9de624c91 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 31 Aug 2007 12:51:36 +0800 Subject: i965: Take the upper limitation on LOD into account. --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 83a4b02e48..81fc9ef2f0 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -192,8 +192,8 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, */ sampler->ss0.base_level = U_FIXED(0, 1); - sampler->ss1.max_lod = U_FIXED(MAX2(texObj->MaxLod, 0), 6); - sampler->ss1.min_lod = U_FIXED(MAX2(texObj->MinLod, 0), 6); + sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(texObj->MaxLod, 0), 13), 6); + sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(texObj->MinLod, 0), 13), 6); sampler->ss2.default_color_pointer = sdc_gs_offset >> 5; } -- cgit v1.2.3 From b47c9f8c915ae4ca8c7fa5ee3b6b64f17c38b569 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 31 Aug 2007 13:42:20 +0800 Subject: optimize 965 clip 1. increase clip thread number to 2 2. do cliptest for -rhw --- src/mesa/drivers/dri/i965/brw_clip_line.c | 7 ++ src/mesa/drivers/dri/i965/brw_clip_state.c | 2 +- src/mesa/drivers/dri/i965/brw_clip_tri.c | 107 +++++++++++++++++++++++++++-- src/mesa/drivers/dri/i965/brw_clip_util.c | 12 +--- 4 files changed, 113 insertions(+), 15 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 0103be4345..9ad00676d4 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -147,6 +147,13 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_clip_init_planes(c); brw_clip_init_clipmask(c); + /* -ve rhw workaround */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), + brw_imm_ud(1<<20)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + plane_loop = brw_DO(p, BRW_EXECUTE_1); { /* if (planemask & 1) diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index 1e6d6fa176..ae46d7a86e 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -55,7 +55,7 @@ static void upload_clip_unit( struct brw_context *brw ) /* BRW_NEW_URB_FENCE */ clip.thread4.nr_urb_entries = brw->urb.nr_clip_entries; clip.thread4.urb_entry_allocation_size = brw->urb.vsize - 1; - clip.thread4.max_threads = 0; /* Hmm, maybe the max is 1 or 2 threads */ + clip.thread4.max_threads = 1; /* 2 threads */ if (INTEL_DEBUG & DEBUG_STATS) clip.thread4.stats_enable = 1; diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index f62b02cedf..506ab3712d 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -42,6 +42,20 @@ #include "brw_util.h" #include "brw_clip.h" +static struct brw_reg get_tmp( struct brw_clip_compile *c ) +{ + struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0); + + if (++c->last_tmp > c->prog_data.total_grf) + c->prog_data.total_grf = c->last_tmp; + + return tmp; +} + +static void release_tmps( struct brw_clip_compile *c ) +{ + c->last_tmp = c->first_tmp; +} void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, @@ -435,15 +449,103 @@ static void maybe_do_clip_tri( struct brw_clip_compile *c ) brw_ENDIF(p, do_clip); } - +static void brw_clip_test( struct brw_clip_compile *c ) +{ + struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + + struct brw_reg v0 = get_tmp(c); + struct brw_reg v1 = get_tmp(c); + struct brw_reg v2 = get_tmp(c); + + struct brw_indirect vt0 = brw_indirect(0, 0); + struct brw_indirect vt1 = brw_indirect(1, 0); + struct brw_indirect vt2 = brw_indirect(2, 0); + + struct brw_compile *p = &c->func; + + brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0])); + brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1])); + brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2])); + brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS])); + brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS])); + brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS])); + brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f)); + + /* test nearz, xmin, ymin plane */ + brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_XOR(p, t, t1, t2); + brw_XOR(p, t1, t2, t3); + brw_OR(p, t, t, t1); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 0), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 1), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 2), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + /* test farz, xmax, ymax plane */ + brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_XOR(p, t, t1, t2); + brw_XOR(p, t1, t2, t3); + brw_OR(p, t, t, t1); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 0), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 1), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 2), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + release_tmps(c); +} void brw_emit_tri_clip( struct brw_clip_compile *c ) { + struct brw_instruction *neg_rhw; + struct brw_compile *p = &c->func; brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); brw_clip_tri_init_vertices(c); brw_clip_init_clipmask(c); + /* if -ve rhw workaround bit is set, + do cliptest */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), + brw_imm_ud(1<<20)); + neg_rhw = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_test(c); + } + brw_ENDIF(p, neg_rhw); + /* Can't push into do_clip_tri because with polygon (or quad) * flatshading, need to apply the flatshade here because we don't * respect the PV when converting to trifan for emit: @@ -462,6 +564,3 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) */ brw_clip_kill_thread(c); } - - - diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index 19bef19801..c37bfeb1ce 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -272,6 +272,7 @@ void brw_clip_kill_thread(struct brw_clip_compile *c) + struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c ) { return brw_address(c->reg.fixed_planes); @@ -327,8 +328,7 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c ) /* Shift so that lowest outcode bit is rightmost: */ - brw_MOV(p, c->reg.planemask, incoming); - brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(26)); + brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26)); if (c->key.nr_userclip) { struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD); @@ -342,13 +342,5 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c ) release_tmp(c, tmp); } - - /* Test for -ve rhw workaround - */ - brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); - brw_AND(p, vec1(brw_null_reg()), incoming, brw_imm_ud(1<<20)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); - brw_set_predicate_control(p, BRW_PREDICATE_NONE); - } -- cgit v1.2.3 From 214347fdb4c30dc8bac5d4b9a823458709bc53ea Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 31 Aug 2007 16:50:48 +0800 Subject: i965: Calculate the positional light in homogeneous coordinates. fix bug#11009 --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 5 +++++ src/mesa/tnl/t_vp_build.c | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index b69be350a9..339a330448 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1003,6 +1003,11 @@ static void build_lighting( struct tnl_program *p ) VPpli = get_temp(p); half = get_temp(p); + + /* In homogeneous object coordinates + */ + emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); + emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); /* Calulate VPpli vector */ diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index ee1a2498b3..336f3c7a2a 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -960,6 +960,11 @@ static void build_lighting( struct tnl_program *p ) VPpli = get_temp(p); half = get_temp(p); + /* In homogeneous object coordinates + */ + emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); + emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); + /* Calulate VPpli vector */ emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); -- cgit v1.2.3 From cb7da3f09655f9c66eabb6a38f581c9176980cd2 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Sat, 1 Sep 2007 15:43:15 +0800 Subject: i965: Correct build_lighting in i965 driver according to commit 6dd98e9853a6984150aa47467112e016c40a4ab4. --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 339a330448..2ed80dc36e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1000,6 +1000,7 @@ static void build_lighting( struct tnl_program *p ) STATE_POSITION); struct ureg V = get_eye_position(p); struct ureg dist = get_temp(p); + struct ureg tmpPpli = get_temp(p); VPpli = get_temp(p); half = get_temp(p); @@ -1007,11 +1008,11 @@ static void build_lighting( struct tnl_program *p ) /* In homogeneous object coordinates */ emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); - emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); + emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist); /* Calulate VPpli vector */ - emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); + emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); /* Normalize VPpli. The dist value also used in * attenuation below. @@ -1043,6 +1044,7 @@ static void build_lighting( struct tnl_program *p ) emit_normalize_vec3(p, half, half); release_temp(p, dist); + release_temp(p, tmpPpli); } /* Calculate dot products: -- cgit v1.2.3 From 1a15b2169ba6cb100627eb525a20a00537cfb6f0 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 5 Sep 2007 13:31:01 +0800 Subject: i965: only take non-varying attribute into account when compiling sf_prog. fix bug#11378 (which is introduced by commit d619cceea47dc3070ebb7f7ea4f8b6b31a672d38) --- src/mesa/drivers/dri/i965/brw_sf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index 73232b3c7c..a655b010fd 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -43,7 +43,7 @@ #include "brw_sf.h" #include "brw_state.h" -#define DO_SETUP_BITS ((1< Date: Tue, 11 Sep 2007 16:49:02 +0800 Subject: i965: limit on LOD Bias, fix#11987 --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 81fc9ef2f0..8afefdd435 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -178,7 +178,7 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, /* Set LOD bias: */ - sampler->ss0.lod_bias = S_FIXED(texUnit->LodBias + texObj->LodBias, 6); + sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias + texObj->LodBias, -16, 15), 6); sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ -- cgit v1.2.3 From 0aedb9a2042bef9c13358500f93acaf8459a74cb Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 11 Sep 2007 16:57:07 +0800 Subject: i965: take the secondary color into account when drawing bitmap. fix#10688 --- src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index 23f381fe91..79c1fee9c0 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -168,7 +168,8 @@ do_blit_bitmap( GLcontext *ctx, { struct intel_context *intel = intel_context(ctx); struct intel_region *dst = intel_drawbuf_region(intel); - + GLfloat tmpColor[4]; + union { GLuint ui; GLubyte ub[4]; @@ -183,10 +184,16 @@ do_blit_bitmap( GLcontext *ctx, 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]); + COPY_4V(tmpColor, ctx->Current.RasterColor); + + if (NEED_SECONDARY_COLOR(ctx)) { + ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor); + } + + UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], tmpColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], tmpColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], tmpColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], tmpColor[3]); /* Does zoom apply to bitmaps? */ -- cgit v1.2.3 From acfeb3b6ea93bcb5b18e6f51a0727e39da608d76 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Sep 2007 10:57:37 -0600 Subject: Fix-up #includes to remove some -I options. eg: #include "shader/program.h" and remove -I$(TOP)/src/mesa/program --- src/mesa/drivers/dri/Makefile.template | 5 ----- src/mesa/drivers/dri/i915/i915_fragprog.c | 11 ++++++----- src/mesa/drivers/dri/i915tex/i915_fragprog.c | 11 ++++++----- src/mesa/drivers/dri/i965/brw_program.c | 10 +++++----- src/mesa/drivers/dri/i965/brw_sf.h | 2 +- src/mesa/drivers/dri/i965/brw_vs.h | 2 +- src/mesa/drivers/dri/i965/brw_vs_emit.c | 4 ++-- src/mesa/drivers/dri/i965/brw_wm.h | 2 +- src/mesa/drivers/dri/r200/r200_fragshader.c | 10 +++++----- src/mesa/drivers/dri/r200/r200_vertprog.c | 8 ++++---- src/mesa/drivers/dri/r300/r300_shader.c | 7 +++---- src/mesa/drivers/dri/r300/r300_swtcl.c | 1 + src/mesa/drivers/dri/r300/r300_vertprog.c | 8 ++++---- src/mesa/drivers/dri/radeon/radeon_context.c | 17 +++++++++-------- 14 files changed, 48 insertions(+), 50 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 6f2314ee8c..adf30ef41e 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -49,11 +49,6 @@ SHARED_INCLUDES = \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/math \ - -I$(TOP)/src/mesa/transform \ - -I$(TOP)/src/mesa/shader \ - -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/egl/drivers/dri \ $(LIBDRM_CFLAGS) diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index abca0bbffe..c839bbdea5 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -29,19 +29,20 @@ #include "macros.h" #include "enums.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/program.h" +#include "shader/programopt.h" + #include "tnl/tnl.h" #include "tnl/t_context.h" + #include "intel_batchbuffer.h" #include "i915_reg.h" #include "i915_context.h" #include "i915_program.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "program.h" -#include "programopt.h" - /* 1, -1/3!, 1/5!, -1/7! */ diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c index 95ec50490a..4c3f2236e5 100644 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -29,19 +29,20 @@ #include "macros.h" #include "enums.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/program.h" +#include "shader/programopt.h" + #include "tnl/tnl.h" #include "tnl/t_context.h" + #include "intel_batchbuffer.h" #include "i915_reg.h" #include "i915_context.h" #include "i915_program.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "program.h" -#include "programopt.h" - /* 1, -1/3!, 1/5!, -1/7! */ diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 752fe49bcb..f7b1d31810 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -29,15 +29,15 @@ * Keith Whitwell */ +#include "main/imports.h" +#include "main/enums.h" #include "shader/prog_parameter.h" +#include "shader/program.h" +#include "tnl/tnl.h" + #include "brw_context.h" #include "brw_aub.h" #include "brw_util.h" -#include "program.h" -#include "imports.h" -#include "enums.h" -#include "tnl/tnl.h" - static void brwBindProgram( GLcontext *ctx, GLenum target, diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index e374e372bb..e8946511dd 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -34,9 +34,9 @@ #define BRW_SF_H +#include "shader/program.h" #include "brw_context.h" #include "brw_eu.h" -#include "program.h" #define SF_POINTS 0 diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index fdb5785d67..8843f816f9 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -36,7 +36,7 @@ #include "brw_context.h" #include "brw_eu.h" -#include "program.h" +#include "shader/program.h" struct brw_vs_prog_key { diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index d00f0c71a8..8733b470c2 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -30,8 +30,8 @@ */ -#include "program.h" -#include "macros.h" +#include "main/macros.h" +#include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "brw_context.h" diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index f5fddfdb68..6dcf4732a9 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -34,9 +34,9 @@ #define BRW_WM_H +#include "shader/prog_instruction.h" #include "brw_context.h" #include "brw_eu.h" -#include "prog_instruction.h" /* A big lookup table is used to figure out which and how many * additional regs will inserted before the main payload in the WM diff --git a/src/mesa/drivers/dri/r200/r200_fragshader.c b/src/mesa/drivers/dri/r200/r200_fragshader.c index 5dd3adaef6..d514b28219 100644 --- a/src/mesa/drivers/dri/r200/r200_fragshader.c +++ b/src/mesa/drivers/dri/r200/r200_fragshader.c @@ -24,13 +24,13 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ -#include "glheader.h" -#include "macros.h" -#include "enums.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" #include "tnl/t_context.h" -#include "atifragshader.h" -#include "program.h" +#include "shader/atifragshader.h" +#include "shader/program.h" #include "r200_context.h" #include "r200_ioctl.h" #include "r200_tex.h" diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 6089d617c6..604b9c6cae 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -30,10 +30,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Aapo Tahkola * Roland Scheidegger */ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" +#include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 5f5ac7c4c7..77abf86a8e 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -1,8 +1,7 @@ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" +#include "main/glheader.h" + +#include "shader/program.h" #include "tnl/tnl.h" #include "r300_context.h" #include "r300_fragprog.h" diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index c949f33bf3..a732bdb559 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -40,6 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "image.h" #include "imports.h" +#include "light.h" #include "macros.h" #include "swrast/s_context.h" diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 7d4e8c9511..4dd3fd6a67 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -35,10 +35,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * For a description of the vertex program instruction set see r300_reg.h. */ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" +#include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 9451ec4aa5..b302275c71 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -35,14 +35,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Keith Whitwell */ -#include "glheader.h" -#include "api_arrayelt.h" -#include "context.h" -#include "simple_list.h" -#include "imports.h" -#include "matrix.h" -#include "extensions.h" -#include "framebuffer.h" +#include "main/glheader.h" +#include "main/api_arrayelt.h" +#include "main/context.h" +#include "main/simple_list.h" +#include "main/imports.h" +#include "main/matrix.h" +#include "main/extensions.h" +#include "main/framebuffer.h" +#include "main/state.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -- cgit v1.2.3 From ae078e1a0abae58e325ed3ebcb1884867847826b Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 12 Sep 2007 15:13:06 +0800 Subject: i965: revert commit 1a15b2169ba6cb100627eb525a20a00537cfb6f0, and keep the instruction state unchanged after calling brw_emit_tri_setup/brw_emit_line_setup when building setup thread for SF_UNFILLED_TRIS. --- src/mesa/drivers/dri/i965/brw_sf.c | 2 +- src/mesa/drivers/dri/i965/brw_sf_emit.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index a655b010fd..738ceb0552 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -43,7 +43,7 @@ #include "brw_sf.h" #include "brw_state.h" -#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX - MAX_VARYING))-1) +#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX)) - 1) static void compile_sf_prog( struct brw_context *brw, struct brw_sf_prog_key *key ) diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index 22911a4649..5e86e428fa 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -663,7 +663,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) (1<<_3DPRIM_TRIFAN_NOSTIPPLE))); jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { + brw_push_insn_state(p); brw_emit_tri_setup( c ); + brw_pop_insn_state(p); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); @@ -677,7 +679,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) (1<<_3DPRIM_LINESTRIP_CONT_BF))); jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { + brw_push_insn_state(p); brw_emit_line_setup( c ); + brw_pop_insn_state(p); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); @@ -686,7 +690,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1< Date: Wed, 12 Sep 2007 16:51:45 +0800 Subject: i965: translate shadow compare function into correct internal function to match the EXT_shadow_funs spec. fix bug#11925 --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- src/mesa/drivers/dri/i965/intel_context.h | 2 +- src/mesa/drivers/dri/i965/intel_state.c | 25 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 8afefdd435..3c0952acf0 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -173,7 +173,7 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, * message (sample_c). So need to recompile WM program when * shadow comparison is enabled on each/any texture unit. */ - sampler->ss0.shadow_function = intel_translate_compare_func(texObj->CompareFunc); + sampler->ss0.shadow_function = intel_translate_shadow_compare_func(texObj->CompareFunc); } /* Set LOD bias: diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index ae25592908..053d93a82b 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -464,7 +464,7 @@ extern void intelInitStateFuncs( struct dd_function_table *functions ); #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f - +extern int intel_translate_shadow_compare_func( GLenum func ); extern int intel_translate_compare_func( GLenum func ); extern int intel_translate_stencil_op( GLenum op ); extern int intel_translate_blend_factor( GLenum factor ); diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c index 2e442db619..2f5467a4e4 100644 --- a/src/mesa/drivers/dri/i965/intel_state.c +++ b/src/mesa/drivers/dri/i965/intel_state.c @@ -38,6 +38,31 @@ #include "intel_regions.h" #include "swrast/swrast.h" +int intel_translate_shadow_compare_func( GLenum func ) +{ + switch(func) { + case GL_NEVER: + return COMPAREFUNC_ALWAYS; + case GL_LESS: + return COMPAREFUNC_LEQUAL; + case GL_LEQUAL: + return COMPAREFUNC_LESS; + case GL_GREATER: + return COMPAREFUNC_GEQUAL; + case GL_GEQUAL: + return COMPAREFUNC_GREATER; + case GL_NOTEQUAL: + return COMPAREFUNC_EQUAL; + case GL_EQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_ALWAYS: + return COMPAREFUNC_NEVER; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_NEVER; +} + int intel_translate_compare_func( GLenum func ) { switch(func) { -- cgit v1.2.3 From ea07a0df9a2f689b8f5acaf92c40bbbd602cab3c Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 14 Sep 2007 11:10:23 +0800 Subject: i965: align the address of the first element within the index buffer. (fix#11910) --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 6150cac4aa..dc289ca9ae 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -593,6 +593,28 @@ void brw_upload_indices( struct brw_context *brw, ib_size, index_buffer->ptr, bufferobj); + } else { + if (((1 << get_index_type(index_buffer->type)) - 1) & offset) { + struct gl_buffer_object *vbo; + GLuint voffset; + GLubyte *map = ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + GL_DYNAMIC_DRAW_ARB, + bufferobj); + map += offset; + get_space(brw, ib_size, &vbo, &voffset); + + ctx->Driver.BufferSubData(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + voffset, + ib_size, + map, + vbo); + ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj); + + bufferobj = vbo; + offset = voffset; + } } /* Emit the indexbuffer packet: -- cgit v1.2.3 From 2c88bfeaa47bf464b02275e10e6c348e5172a0a1 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 20 Sep 2007 17:42:13 +0800 Subject: i965: fix an error in brw_vs_tnl.c if the state of TEXMAT is changed, the VS isn't updated. --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 2ed80dc36e..27210d1a37 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1628,7 +1628,8 @@ const struct brw_tracked_state brw_tnl_vertprog = { _NEW_FOG | _NEW_HINT | _NEW_POINT | - _NEW_TEXTURE), + _NEW_TEXTURE | + _NEW_TEXTURE_MATRIX), .brw = (BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_INPUT_VARYING), .cache = 0 -- cgit v1.2.3 From 439fa7957874d564b30a92345e74ee57b388ebec Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Mon, 24 Sep 2007 16:48:55 +0800 Subject: fix fd.o bug #12217, recalcuate urb when clip plane size change --- src/mesa/drivers/dri/i965/brw_curbe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 3f0aaa1f86..5bf0ed536b 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -90,7 +90,7 @@ static void calculate_curbe_offsets( struct brw_context *brw ) */ if (nr_fp_regs > brw->curbe.wm_size || nr_vp_regs > brw->curbe.vs_size || - nr_clip_regs > brw->curbe.clip_size || + nr_clip_regs != brw->curbe.clip_size || (total_regs < brw->curbe.total_size / 4 && brw->curbe.total_size > 16)) { -- cgit v1.2.3 From 919709af6ba19eb30d293a161d89a0b8fccb9ec7 Mon Sep 17 00:00:00 2001 From: Roland Bär Date: Mon, 24 Sep 2007 13:47:26 -0700 Subject: [i965] Bug #11812: Fix fwrite return value checks in AUB file code. --- src/mesa/drivers/dri/i965/brw_aub.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_aub.c b/src/mesa/drivers/dri/i965/brw_aub.c index f851a5b795..c549f7a4f6 100644 --- a/src/mesa/drivers/dri/i965/brw_aub.c +++ b/src/mesa/drivers/dri/i965/brw_aub.c @@ -80,7 +80,7 @@ static void init_aubfile( FILE *aub_file ) fh.hour = (nr>>16) & 0xff; fh.comment_length = 0x0; - if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) + if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1) FAIL; /* Setup the GTT starting at main memory address zero (!): @@ -96,12 +96,12 @@ static void init_aubfile( FILE *aub_file ) bh.address = PGETBL_CTL; bh.length = 0x4; - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) FAIL; data = 0x0 | PGETBL_ENABLED; - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + if (fwrite(&data, sizeof(data), 1, aub_file) < 1) FAIL; } @@ -128,7 +128,7 @@ static void init_aub_gtt( struct brw_context *brw, bh.address = start_offset / 4096 * 4; bh.length = size / 4096 * 4; - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) FAIL; for (i = 0; i < size / 4096; i++) { @@ -136,7 +136,7 @@ static void init_aub_gtt( struct brw_context *brw, brw->next_free_page += 4096; - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + if (fwrite(&data, sizeof(data), 1, aub_file) < 1) FAIL; } @@ -149,10 +149,10 @@ static void write_block_header( FILE *aub_file, { sz = (sz + 3) & ~3; - if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) + if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1) FAIL; - if (fwrite(data, sz, 1, aub_file) < 0) + if (fwrite(data, sz, 1, aub_file) < 1) FAIL; fflush(aub_file); @@ -162,7 +162,7 @@ static void write_block_header( FILE *aub_file, static void write_dump_bmp( FILE *aub_file, struct aub_dump_bmp *db ) { - if (fwrite(db, sizeof(*db), 1, aub_file) < 0) + if (fwrite(db, sizeof(*db), 1, aub_file) < 1) FAIL; fflush(aub_file); -- cgit v1.2.3 From 395b3bf6f95b35a84a74d4baf7e04bc67cf3771c Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 26 Sep 2007 10:00:41 +0800 Subject: fix a bug in 965 ARB_occlusion_query, fd.o bug #12132 --- src/mesa/drivers/dri/i965/intel_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 4a95087d78..f3ec2b2eee 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -271,7 +271,7 @@ intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) }; intel->stats_wm++; intelFinish(&intel->ctx); - drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); } static void @@ -285,7 +285,7 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) .data = &tmp }; intelFinish(&intel->ctx); - drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); q->Result = tmp - q->Result; q->Ready = GL_TRUE; intel->stats_wm--; -- cgit v1.2.3 From 175db68db59c6b917306adff98442d590df9af06 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 26 Sep 2007 16:42:50 +0800 Subject: i965: The cube map texture coordinates must be devided by the component with the largest absolute value before they are delivered. fix bug #12421 --- src/mesa/drivers/dri/i965/brw_wm_fp.c | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 62bb081206..67154c1b13 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -525,7 +525,57 @@ static void precalc_tex( struct brw_wm_compile *c, struct prog_src_register coord; struct prog_dst_register tmpcoord; - if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { + if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) { + struct prog_instruction *out; + struct prog_dst_register tmp0 = get_temp(c); + struct prog_src_register tmp0src = src_reg_from_dst(tmp0); + struct prog_dst_register tmp1 = get_temp(c); + struct prog_src_register tmp1src = src_reg_from_dst(tmp1); + struct prog_src_register src0 = inst->SrcReg[0]; + + tmpcoord = get_temp(c); + coord = src_reg_from_dst(tmpcoord); + + out = emit_op(c, OPCODE_MOV, + tmpcoord, + 0, 0, 0, + src0, + src_undef(), + src_undef()); + out->SrcReg[0].NegateBase = 0; + out->SrcReg[0].Abs = 1; + + emit_op(c, OPCODE_MAX, + tmp0, + 0, 0, 0, + src_swizzle1(coord, X), + src_swizzle1(coord, Y), + src_undef()); + + emit_op(c, OPCODE_MAX, + tmp1, + 0, 0, 0, + tmp0src, + src_swizzle1(coord, Z), + src_undef()); + + emit_op(c, OPCODE_RCP, + tmp0, + 0, 0, 0, + tmp1src, + src_undef(), + src_undef()); + + emit_op(c, OPCODE_MUL, + tmpcoord, + 0, 0, 0, + src0, + tmp0src, + src_undef()); + + release_temp(c, tmp0); + release_temp(c, tmp1); + } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { struct prog_src_register scale = search_or_add_param5( c, STATE_INTERNAL, -- cgit v1.2.3 From 67f6449743d006084df85693085eca79a966ad17 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 27 Sep 2007 11:15:42 +1000 Subject: i915/i965 merge serer directories along lines for radeon/r200 --- src/mesa/drivers/dri/i915/server/i830_common.h | 20 + src/mesa/drivers/dri/i965/Makefile | 14 +- src/mesa/drivers/dri/i965/server/i830_common.h | 222 ---- src/mesa/drivers/dri/i965/server/i830_dri.h | 63 -- src/mesa/drivers/dri/i965/server/intel.h | 328 ------ src/mesa/drivers/dri/i965/server/intel_dri.c | 1282 ------------------------ 6 files changed, 33 insertions(+), 1896 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/server/i830_common.h delete mode 100644 src/mesa/drivers/dri/i965/server/i830_dri.h delete mode 100644 src/mesa/drivers/dri/i965/server/intel.h delete mode 100644 src/mesa/drivers/dri/i965/server/intel_dri.c (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h index a877f3c2f4..f1fd3939ab 100644 --- a/src/mesa/drivers/dri/i915/server/i830_common.h +++ b/src/mesa/drivers/dri/i915/server/i830_common.h @@ -54,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_DESTROY_HEAP 0x0c #define DRM_I830_SET_VBLANK_PIPE 0x0d #define DRM_I830_GET_VBLANK_PIPE 0x0e +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -233,4 +234,23 @@ typedef struct { int pipe; } drmI830VBlankPipe; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; + #endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 9e4ff112dc..15a6752e0f 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -77,6 +77,12 @@ DRIVER_SOURCES = \ brw_wm_state.c \ brw_wm_surface_state.c +SYMLINKS = \ + server/i830_dri.h \ + server/i830_common.h \ + server/intel_dri.c \ + server/intel.h + C_SOURCES = \ $(COMMON_SOURCES) \ $(MINIGLX_SOURCES) \ @@ -90,4 +96,10 @@ include ../Makefile.template intel_tex_layout.o: ../intel/intel_tex_layout.c -symlinks: +server: + mkdir -p server + +$(SYMLINKS): server + @[ -e $@ ] || ln -sf ../../i915/$@ server/ + +symlinks: $(SYMLINKS) diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h deleted file mode 100644 index f320378c2a..0000000000 --- a/src/mesa/drivers/dri/i965/server/i830_common.h +++ /dev/null @@ -1,222 +0,0 @@ -/************************************************************************** - -Copyright 2001 VA Linux Systems Inc., Fremont, California. -Copyright 2002 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 -on 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 -ATI, VA LINUX SYSTEMS AND/OR THEIR 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. - -**************************************************************************/ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ - -#ifndef _I830_COMMON_H_ -#define _I830_COMMON_H_ - - -#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ -#define I830_LOG_MIN_TEX_REGION_SIZE 14 - - -/* Driver specific DRM command indices - * NOTE: these are not OS specific, but they are driver specific - */ -#define DRM_I830_INIT 0x00 -#define DRM_I830_FLUSH 0x01 -#define DRM_I830_FLIP 0x02 -#define DRM_I830_BATCHBUFFER 0x03 -#define DRM_I830_IRQ_EMIT 0x04 -#define DRM_I830_IRQ_WAIT 0x05 -#define DRM_I830_GETPARAM 0x06 -#define DRM_I830_SETPARAM 0x07 -#define DRM_I830_ALLOC 0x08 -#define DRM_I830_FREE 0x09 -#define DRM_I830_INIT_HEAP 0x0a -#define DRM_I830_CMDBUFFER 0x0b -#define DRM_I830_DESTROY_HEAP 0x0c -#define DRM_I830_MMIO 0x10 - -typedef struct { - enum { - I830_INIT_DMA = 0x01, - I830_CLEANUP_DMA = 0x02, - I830_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drmI830Init; - -typedef struct { - drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - volatile int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; -} drmI830Sarea; - -/* Flags for perf_boxes - */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - - -typedef struct { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830BatchBuffer; - -typedef struct { - char *buf; /* agp offset */ - int sz; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830CmdBuffer; - -typedef struct { - int *irq_seq; -} drmI830IrqEmit; - -typedef struct { - int irq_seq; -} drmI830IrqWait; - -typedef struct { - int param; - int *value; -} drmI830GetParam; - -#define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 - -typedef struct { - int param; - int value; -} drmI830SetParam; - -#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 - - -/* A memory manager for regions of shared memory: - */ -#define I830_MEM_REGION_AGP 1 - -typedef struct { - int region; - int alignment; - int size; - int *region_offset; /* offset from start of fb or agp */ -} drmI830MemAlloc; - -typedef struct { - int region; - int region_offset; -} drmI830MemFree; - -typedef struct { - int region; - int size; - int start; -} drmI830MemInitHeap; - -typedef struct { - int region; -} drmI830MemDestroyHeap; - -#define MMIO_READ 0 -#define MMIO_WRITE 1 - -#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 -#define MMIO_REGS_IA_VERTICES_COUNT 1 -#define MMIO_REGS_VS_INVOCATION_COUNT 2 -#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 -#define MMIO_REGS_GS_INVOCATION_COUNT 4 -#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 -#define MMIO_REGS_CL_INVOCATION_COUNT 6 -#define MMIO_REGS_PS_INVOCATION_COUNT 7 -#define MMIO_REGS_PS_DEPTH_COUNT 8 - -typedef struct { - unsigned int read_write:1; - unsigned int reg:31; - void __user *data; -} drmI830MMIO; - -#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i965/server/i830_dri.h b/src/mesa/drivers/dri/i965/server/i830_dri.h deleted file mode 100644 index 22951812ad..0000000000 --- a/src/mesa/drivers/dri/i965/server/i830_dri.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" -#include "i830_common.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 3 -#define I830_PATCHLEVEL 0 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize unused1; /* backbufferSize */ - drm_handle_t unused2; /* backbuffer */ - - drmSize unused3; /* depthbufferSize */ - drm_handle_t unused4; /* depthbuffer */ - - drmSize unused5; /* rotatedSize /*/ - drm_handle_t unused6; /* rotatedbuffer */ - - drm_handle_t unused7; /* textures */ - int unused8; /* textureSize */ - - drm_handle_t unused9; /* agp_buffers */ - drmSize unused10; /* agp_buf_size */ - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - - int unused12; /* logTextureGranularity */ - int unused13; /* textureOffset */ - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/mesa/drivers/dri/i965/server/intel.h b/src/mesa/drivers/dri/i965/server/intel.h deleted file mode 100644 index d7858a20c8..0000000000 --- a/src/mesa/drivers/dri/i965/server/intel.h +++ /dev/null @@ -1,328 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/mesa/drivers/dri/i965/server/intel_dri.c b/src/mesa/drivers/dri/i965/server/intel_dri.c deleted file mode 100644 index 169fdbece3..0000000000 --- a/src/mesa/drivers/dri/i965/server/intel_dri.c +++ /dev/null @@ -1,1282 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - 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 THE COPYRIGHT HOLDERS AND/OR THEIR 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 -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - - memset(&host_bridge, 0, sizeof(host_bridge)); - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags) -{ - int ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) - return AllocFromAGP(ctx, pI830, size, alignment, result); - else - { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - - if (ret==0) - return AllocFromAGP(ctx, pI830, size, alignment, result); - return ret; - } -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; - - return TRUE; -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); - - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static void -I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* Start up the simple memory manager for agp space */ - drmI830MemInitHeap drmHeap; - drmHeap.region = I830_MEM_REGION_AGP; - drmHeap.start = 0; - drmHeap.size = sarea->tex_size; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - fprintf(stderr, - "[drm] Failed to initialized agp heap manager\n"); - } else { - fprintf(stderr, - "[drm] Initialized kernel agp heap manager, %d\n", - sarea->tex_size); - - I830SetParam(ctx, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, - sarea->log_tex_granularity); - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - I830InitTextureHeap(ctx, pI830, sarea); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - pI830DRI->backOffset = pI830->BackBuffer.Start; - pI830DRI->backPitch = pI830->BackBuffer.Pitch; - - pI830DRI->depthOffset = pI830->DepthBuffer.Start; - pI830DRI->depthPitch = pI830->DepthBuffer.Pitch; - - pI830DRI->fbOffset = pI830->FrontBuffer.Start; - pI830DRI->fbStride = pI830->FrontBuffer.Pitch; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; -- cgit v1.2.3 From aa88d11e7d881f0dd4c02fcefceb4085bdb3cf8a Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 27 Sep 2007 13:49:35 +0800 Subject: fix ppracer and bzflag issue with clip optimization --- src/mesa/drivers/dri/i965/brw_clip_tri.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index 506ab3712d..b7d30bb0c4 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -472,7 +472,6 @@ static void brw_clip_test( struct brw_clip_compile *c ) brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS])); brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS])); brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS])); - brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f)); /* test nearz, xmin, ymin plane */ brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3)); -- cgit v1.2.3 From 3ee6a77e97f7d2996f8fffdbb4787a9589189b39 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 27 Sep 2007 16:14:57 +0800 Subject: i965: handle all unfilled mode in clip stage. fix bug #12453 --- src/mesa/drivers/dri/i965/brw_clip.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 3bec153075..8287fd9edf 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -212,6 +212,10 @@ static void upload_clip_prog( struct brw_context *brw ) } } + if (brw->attribs.Polygon->BackMode != GL_FILL || + brw->attribs.Polygon->FrontMode != GL_FILL) + key.do_unfilled = 1; + /* Most cases the fixed function units will handle. Cases where * one or more polygon faces are unfilled will require help: */ -- cgit v1.2.3 From 38c30a81844214b030c9c637f9cf97bd2bf19cde Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 26 Sep 2007 13:57:08 -0700 Subject: [965] Remove AUB file support. This code existed to dump logs of hardware access to be replayed in simulation. Since we have real hardware now, it's not really needed. --- src/mesa/drivers/dri/i965/Makefile | 2 - src/mesa/drivers/dri/i965/brw_aub.c | 353 ------------------ src/mesa/drivers/dri/i965/brw_aub.h | 172 --------- src/mesa/drivers/dri/i965/brw_aub_playback.c | 443 ----------------------- src/mesa/drivers/dri/i965/brw_context.c | 11 - src/mesa/drivers/dri/i965/brw_context.h | 3 - src/mesa/drivers/dri/i965/brw_curbe.c | 13 +- src/mesa/drivers/dri/i965/brw_draw.c | 6 - src/mesa/drivers/dri/i965/brw_draw_upload.c | 1 - src/mesa/drivers/dri/i965/brw_program.c | 1 - src/mesa/drivers/dri/i965/brw_state_batch.c | 1 - src/mesa/drivers/dri/i965/brw_state_cache.c | 78 ++-- src/mesa/drivers/dri/i965/brw_state_pool.c | 5 +- src/mesa/drivers/dri/i965/brw_vtbl.c | 3 - src/mesa/drivers/dri/i965/bufmgr.h | 24 -- src/mesa/drivers/dri/i965/bufmgr_fake.c | 100 ----- src/mesa/drivers/dri/i965/intel_batchbuffer.c | 19 - src/mesa/drivers/dri/i965/intel_buffer_objects.c | 7 +- src/mesa/drivers/dri/i965/intel_buffers.c | 6 - src/mesa/drivers/dri/i965/intel_context.c | 7 - src/mesa/drivers/dri/i965/intel_context.h | 17 - src/mesa/drivers/dri/i965/intel_ioctl.c | 4 - src/mesa/drivers/dri/i965/intel_regions.c | 10 +- 23 files changed, 42 insertions(+), 1244 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/brw_aub.c delete mode 100644 src/mesa/drivers/dri/i965/brw_aub.h delete mode 100644 src/mesa/drivers/dri/i965/brw_aub_playback.c (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 15a6752e0f..5748d7ff05 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -22,8 +22,6 @@ DRIVER_SOURCES = \ intel_tex.c \ intel_tex_layout.c \ intel_tex_validate.c \ - brw_aub.c \ - brw_aub_playback.c \ brw_cc.c \ brw_clip.c \ brw_clip_line.c \ diff --git a/src/mesa/drivers/dri/i965/brw_aub.c b/src/mesa/drivers/dri/i965/brw_aub.c deleted file mode 100644 index c549f7a4f6..0000000000 --- a/src/mesa/drivers/dri/i965/brw_aub.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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, sublicense, 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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_context.h" -#include "brw_aub.h" -#include "intel_regions.h" -#include - -extern char *__progname; - - -/* Registers to control page table - */ -#define PGETBL_CTL 0x2020 -#define PGETBL_ENABLED 0x1 - -#define NR_GTT_ENTRIES 65536 /* 256 mb */ - -#define FAIL \ -do { \ - fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ - exit(1); \ -} while (0) - - -/* Emit the headers at the top of each aubfile. Initialize the GTT. - */ -static void init_aubfile( FILE *aub_file ) -{ - struct aub_file_header fh; - struct aub_block_header bh; - unsigned int data; - - static int nr; - - nr++; - - /* Emit the aub header: - */ - memset(&fh, 0, sizeof(fh)); - - fh.instruction_type = AUB_FILE_HEADER; - fh.minor = 0x0; - fh.major = 0x7; - memcpy(fh.application, __progname, sizeof(fh.application)); - fh.day = (nr>>24) & 0xff; - fh.month = 0x0; - fh.year = 0x0; - fh.timezone = 0x0; - fh.second = nr & 0xff; - fh.minute = (nr>>8) & 0xff; - fh.hour = (nr>>16) & 0xff; - fh.comment_length = 0x0; - - if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1) - FAIL; - - /* Setup the GTT starting at main memory address zero (!): - */ - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_MMI0_WRITE32; - bh.type = 0x0; - bh.address_space = ADDR_GTT; /* ??? */ - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = PGETBL_CTL; - bh.length = 0x4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) - FAIL; - - data = 0x0 | PGETBL_ENABLED; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 1) - FAIL; -} - - -static void init_aub_gtt( struct brw_context *brw, - GLuint start_offset, - GLuint size ) -{ - FILE *aub_file = brw->intel.aub_file; - struct aub_block_header bh; - unsigned int i; - - assert(start_offset + size < NR_GTT_ENTRIES * 4096); - - - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = 0x0; - bh.address_space = ADDR_MAIN; - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = start_offset / 4096 * 4; - bh.length = size / 4096 * 4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) - FAIL; - - for (i = 0; i < size / 4096; i++) { - GLuint data = brw->next_free_page | 1; - - brw->next_free_page += 4096; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 1) - FAIL; - } - -} - -static void write_block_header( FILE *aub_file, - struct aub_block_header *bh, - const GLuint *data, - GLuint sz ) -{ - sz = (sz + 3) & ~3; - - if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1) - FAIL; - - if (fwrite(data, sz, 1, aub_file) < 1) - FAIL; - - fflush(aub_file); -} - - -static void write_dump_bmp( FILE *aub_file, - struct aub_dump_bmp *db ) -{ - if (fwrite(db, sizeof(*db), 1, aub_file) < 1) - FAIL; - - fflush(aub_file); -} - - - -static void brw_aub_gtt_data( struct intel_context *intel, - GLuint offset, - const void *data, - GLuint sz, - GLuint type, - GLuint state_type ) -{ - struct aub_block_header bh; - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - - if (type == DW_GENERAL_STATE) { - bh.general_state_type = state_type; - bh.surface_state_type = 0; - } - else { - bh.general_state_type = 0; - bh.surface_state_type = state_type; - } - - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(intel->aub_file, &bh, data, sz); -} - - - -static void brw_aub_gtt_cmds( struct intel_context *intel, - GLuint offset, - const void *data, - GLuint sz ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - struct aub_block_header bh; - GLuint type = CW_PRIMARY_RING_A; - - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_COMMAND_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - bh.general_state_type = 0; - bh.surface_state_type = 0; - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(brw->intel.aub_file, &bh, data, sz); -} - -static void brw_aub_dump_bmp( struct intel_context *intel, - GLuint buffer ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - intelScreenPrivate *intelScreen = brw->intel.intelScreen; - struct aub_dump_bmp db; - GLuint format; - - if (intelScreen->cpp == 4) - format = 0x7; - else - format = 0x3; - - - if (buffer == 0) { - db.instruction_type = AUB_DUMP_BMP; - db.xmin = 0; - db.ymin = 0; - db.format = format; - db.bpp = intelScreen->cpp * 8; - db.pitch = intelScreen->front.pitch / intelScreen->cpp; - db.xsize = intelScreen->width; - db.ysize = intelScreen->height; - db.addr = intelScreen->front.offset; - db.unknown = 0x0; /* 4: xmajor tiled, 0: not tiled */ - - write_dump_bmp(brw->intel.aub_file, &db); - } - else { - db.instruction_type = AUB_DUMP_BMP; - db.xmin = 0; - db.ymin = 0; - db.format = format; - db.bpp = intel->back_region->cpp * 8; - db.pitch = intel->back_region->pitch; - db.xsize = intel->back_region->pitch; - db.ysize = intel->back_region->height; - db.addr = intelScreen->back.offset; - db.unknown = intel->back_region->tiled ? 0x4 : 0x0; - - write_dump_bmp(brw->intel.aub_file, &db); - } -} - -/* Attempt to prevent monster aubfiles by closing and reopening when - * the state pools wrap. - */ -static void brw_aub_wrap( struct intel_context *intel ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - if (intel->aub_file) { - brw_aub_destroy(brw); - brw_aub_init(brw); - } - brw->wrap = 1; /* ??? */ -} - - -int brw_aub_init( struct brw_context *brw ) -{ - struct intel_context *intel = &brw->intel; - intelScreenPrivate *intelScreen = intel->intelScreen; - char filename[80]; - int val; - static int i = 0; - - i++; - - if (_mesa_getenv("INTEL_REPLAY")) - return 0; - - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); - brw->intel.aub_file = fopen(filename, "w"); - } - else if (_mesa_getenv("INTEL_AUB")) { - val = snprintf(filename, sizeof(filename), "%s.aub", __progname); - if (val < 0 || val > sizeof(filename)) - strcpy(filename, "default.aub"); - - _mesa_printf("--> Aub file: %s\n", filename); - brw->intel.aub_file = fopen(filename, "w"); - } - else { - return 0; - } - - if (!brw->intel.aub_file) { - _mesa_printf("couldn't open aubfile\n"); - exit(1); - } - - brw->intel.vtbl.aub_commands = brw_aub_gtt_cmds; - brw->intel.vtbl.aub_dump_bmp = brw_aub_dump_bmp; - brw->intel.vtbl.aub_gtt_data = brw_aub_gtt_data; - brw->intel.vtbl.aub_wrap = brw_aub_wrap; - - init_aubfile(brw->intel.aub_file); - - /* The GTT is located starting address zero in main memory. Pages - * to populate the gtt start after this point. - */ - brw->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; - - /* More or less correspond with all the agp regions mapped by the - * driver: - */ - init_aub_gtt(brw, 0, 4096*4); /* so new fulsim doesn't crash */ - init_aub_gtt(brw, intelScreen->front.offset, intelScreen->back.size); - init_aub_gtt(brw, intelScreen->back.offset, intelScreen->back.size); - init_aub_gtt(brw, intelScreen->depth.offset, intelScreen->back.size); - init_aub_gtt(brw, intelScreen->tex.offset, intelScreen->tex.size); - - return 0; -} - -void brw_aub_destroy( struct brw_context *brw ) -{ - if (brw->intel.aub_file) { - fclose(brw->intel.aub_file); - brw->intel.aub_file = NULL; - } -} diff --git a/src/mesa/drivers/dri/i965/brw_aub.h b/src/mesa/drivers/dri/i965/brw_aub.h deleted file mode 100644 index 198e36dc3c..0000000000 --- a/src/mesa/drivers/dri/i965/brw_aub.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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, sublicense, 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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#ifndef BRW_AUB_H -#define BRW_AUB_H - -struct aub_file_header { - unsigned int instruction_type; - unsigned int pad0:16; - unsigned int minor:8; - unsigned int major:8; - unsigned char application[8*4]; - unsigned int day:8; - unsigned int month:8; - unsigned int year:16; - unsigned int timezone:8; - unsigned int second:8; - unsigned int minute:8; - unsigned int hour:8; - unsigned int comment_length:16; - unsigned int pad1:16; -}; - -struct aub_block_header { - unsigned int instruction_type; - unsigned int operation:8; - unsigned int type:8; - unsigned int address_space:8; - unsigned int pad0:8; - unsigned int general_state_type:8; - unsigned int surface_state_type:8; - unsigned int pad1:16; - unsigned int address; - unsigned int length; -}; - -struct aub_dump_bmp { - unsigned int instruction_type; - unsigned int xmin:16; - unsigned int ymin:16; - unsigned int pitch:16; - unsigned int bpp:8; - unsigned int format:8; - unsigned int xsize:16; - unsigned int ysize:16; - unsigned int addr; - unsigned int unknown; -}; - -enum bh_operation { - BH_COMMENT, - BH_DATA_WRITE, - BH_COMMAND_WRITE, - BH_MMI0_WRITE32, - BH_END_SCENE, - BH_CONFIG_MEMORY_MAP, - BH_MAX_OPERATION -}; - -enum command_write_type { - CW_HWB_RING = 1, - CW_PRIMARY_RING_A, - CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ - CW_PRIMARY_RING_C, - CW_MAX_TYPE -}; - -enum data_write_type { - DW_NOTYPE, - DW_BATCH_BUFFER, - DW_BIN_BUFFER, - DW_BIN_POINTER_LIST, - DW_SLOW_STATE_BUFFER, - DW_VERTEX_BUFFER, - DW_2D_MAP, - DW_CUBE_MAP, - DW_INDIRECT_STATE_BUFFER, - DW_VOLUME_MAP, - DW_1D_MAP, - DW_CONSTANT_BUFFER, - DW_CONSTANT_URB_ENTRY, - DW_INDEX_BUFFER, - DW_GENERAL_STATE, - DW_SURFACE_STATE, - DW_MEDIA_OBJECT_INDIRECT_DATA, - DW_MAX_TYPE -}; - -enum data_write_general_state_type { - DWGS_NOTYPE, - DWGS_VERTEX_SHADER_STATE, - DWGS_GEOMETRY_SHADER_STATE , - DWGS_CLIPPER_STATE, - DWGS_STRIPS_FANS_STATE, - DWGS_WINDOWER_IZ_STATE, - DWGS_COLOR_CALC_STATE, - DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ - DWGS_STRIPS_FANS_VIEWPORT_STATE, - DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ - DWGS_SAMPLER_STATE, - DWGS_KERNEL_INSTRUCTIONS, - DWGS_SCRATCH_SPACE, - DWGS_SAMPLER_DEFAULT_COLOR, - DWGS_INTERFACE_DESCRIPTOR, - DWGS_VLD_STATE, - DWGS_VFE_STATE, - DWGS_MAX_TYPE -}; - -enum data_write_surface_state_type { - DWSS_NOTYPE, - DWSS_BINDING_TABLE_STATE, - DWSS_SURFACE_STATE, - DWSS_MAX_TYPE -}; - -enum memory_map_type { - MM_DEFAULT, - MM_DYNAMIC, - MM_MAX_TYPE -}; - -enum address_space { - ADDR_GTT, - ADDR_LOCAL, - ADDR_MAIN, - ADDR_MAX -}; - - -#define AUB_FILE_HEADER 0xe085000b -#define AUB_BLOCK_HEADER 0xe0c10003 -#define AUB_DUMP_BMP 0xe09e0004 - -struct brw_context; -struct intel_context; - -int brw_aub_init( struct brw_context *brw ); -void brw_aub_destroy( struct brw_context *brw ); - -int brw_playback_aubfile(struct brw_context *brw, - const char *filename); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_aub_playback.c b/src/mesa/drivers/dri/i965/brw_aub_playback.c deleted file mode 100644 index 2433d50c11..0000000000 --- a/src/mesa/drivers/dri/i965/brw_aub_playback.c +++ /dev/null @@ -1,443 +0,0 @@ - -#include -#include -#include -#include -#include -#include - -#include "brw_aub.h" -#include "brw_defines.h" -#include "brw_context.h" -#include "intel_ioctl.h" -#include "bufmgr.h" - -struct aub_state { - struct intel_context *intel; - const char *map; - unsigned int csr; - unsigned int sz; -}; - - -static int gobble( struct aub_state *s, int size ) -{ - if (s->csr + size > s->sz) { - _mesa_printf("EOF in %s\n", __FUNCTION__); - return 1; - } - - s->csr += size; - return 0; -} - -static void flush_and_fence( struct aub_state *s ) -{ - struct intel_context *intel = s->intel; - GLuint buf[2]; - - buf[0] = intel->vtbl.flush_cmd(); - buf[1] = 0; - - intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf)); - - intelWaitIrq( intel, intelEmitIrqLocked( intel )); -} - -static void flush_cmds( struct aub_state *s, - const void *data, - int len ) -{ - DBG("%s %d\n", __FUNCTION__, len); - - if (len & 0x4) { - unsigned int *tmp = malloc(len + 4); - DBG("padding to octword\n"); - memcpy(tmp, data, len); - tmp[len/4] = MI_NOOP; - flush_cmds(s, tmp, len+4); - free(tmp); - return; - } - - /* For ring data, just send off immediately via an ioctl. - * 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); - - if (1) - flush_and_fence(s); -} - -static const char *pstrings[] = { - "none", - "POINTLIST", - "LINELIST", - "LINESTRIP", - "TRILIST", - "TRISTRIP", - "TRIFAN", - "QUADLIST", - "QUADSTRIP", - "LINELIST_ADJ", - "LINESTRIP_ADJ", - "TRILIST_ADJ", - "TRISTRIP_ADJ", - "TRISTRIP_REVERSE", - "POLYGON", - "RECTLIST", - "LINELOOP", - "POINTLIST_BF", - "LINESTRIP_CONT", - "LINESTRIP_BF", - "LINESTRIP_CONT_BF", - "TRIFAN_NOSTIPPLE", -}; - -static void do_3d_prim( struct aub_state *s, - const void *data, - int len ) -{ - struct brw_3d_primitive prim; - const struct brw_3d_primitive *orig = data; - int i; - - assert(len == sizeof(prim)); - memcpy(&prim, data, sizeof(prim)); - -#define START 0 -#define BLOCK (12*28) - - if (orig->verts_per_instance < BLOCK) - flush_cmds(s, &prim, sizeof(prim)); - else { - for (i = START; i + BLOCK < orig->verts_per_instance; i += BLOCK/2) { - prim.start_vert_location = i; - prim.verts_per_instance = BLOCK; - _mesa_printf("%sprim %d/%s verts %d..%d (of %d)\n", - prim.header.indexed ? "INDEXED " : "", - prim.header.topology, pstrings[prim.header.topology%16], - prim.start_vert_location, - prim.start_vert_location + prim.verts_per_instance, - orig->verts_per_instance); - flush_cmds(s, &prim, sizeof(prim)); - } - } -} - - - -static struct { - int cmd; - const char *name; - int has_length; -} cmd_info[] = { - { 0, "NOOP", 0 }, - { 0x5410, "XY_COLOR_BLT_RGB", 1 }, - { 0x5430, "XY_COLOR_BLT_RGBA", 1 }, - { 0x54d0, "XY_SRC_COPY_BLT_RGB", 1 }, - { 0x54f0, "XY_SRC_COPY_BLT_RGBA", 1 }, - { CMD_URB_FENCE, "URB_FENCE", 1 }, - { CMD_CONST_BUFFER_STATE, "CONST_BUFFER_STATE", 1 }, - { CMD_CONST_BUFFER, "CONST_BUFFER", 1 }, - { CMD_STATE_BASE_ADDRESS, "STATE_BASE_ADDRESS", 1 }, - { CMD_STATE_INSN_POINTER, "STATE_INSN_POINTER", 1 }, - { CMD_PIPELINE_SELECT, "PIPELINE_SELECT", 0, }, - { CMD_PIPELINED_STATE_POINTERS, "PIPELINED_STATE_POINTERS", 1 }, - { CMD_BINDING_TABLE_PTRS, "BINDING_TABLE_PTRS", 1 }, - { CMD_VERTEX_BUFFER, "VERTEX_BUFFER", 1 }, - { CMD_VERTEX_ELEMENT, "VERTEX_ELEMENT", 1 }, - { CMD_INDEX_BUFFER, "INDEX_BUFFER", 1 }, - { CMD_VF_STATISTICS, "VF_STATISTICS", 0 }, - { CMD_DRAW_RECT, "DRAW_RECT", 1 }, - { CMD_BLEND_CONSTANT_COLOR, "BLEND_CONSTANT_COLOR", 1 }, - { CMD_CHROMA_KEY, "CHROMA_KEY", 1 }, - { CMD_DEPTH_BUFFER, "DEPTH_BUFFER", 1 }, - { CMD_POLY_STIPPLE_OFFSET, "POLY_STIPPLE_OFFSET", 1 }, - { CMD_POLY_STIPPLE_PATTERN, "POLY_STIPPLE_PATTERN", 1 }, - { CMD_LINE_STIPPLE_PATTERN, "LINE_STIPPLE_PATTERN", 1 }, - { CMD_GLOBAL_DEPTH_OFFSET_CLAMP, "GLOBAL_DEPTH_OFFSET_CLAMP", 1 }, - { CMD_PIPE_CONTROL, "PIPE_CONTROL", 1 }, - { CMD_MI_FLUSH, "MI_FLUSH", 0 }, - { CMD_3D_PRIM, "3D_PRIM", 1 }, -}; - -#define NR_CMDS (sizeof(cmd_info)/sizeof(cmd_info[0])) - - -static int find_command( unsigned int cmd ) -{ - int i; - - for (i = 0; i < NR_CMDS; i++) - if (cmd == cmd_info[i].cmd) - return i; - - return -1; -} - - - -static int parse_commands( struct aub_state *s, - const unsigned int *data, - int len ) -{ - while (len) { - int cmd = data[0] >> 16; - int dwords; - int i; - - i = find_command(cmd); - - if (i < 0) { - _mesa_printf("couldn't find info for cmd %x\n", cmd); - return 1; - } - - if (cmd_info[i].has_length) - dwords = (data[0] & 0xff) + 2; - else - dwords = 1; - - _mesa_printf("%s (%d dwords) 0x%x\n", cmd_info[i].name, dwords, data[0]); - - if (len < dwords * 4) { - _mesa_printf("EOF in %s (%d bytes)\n", __FUNCTION__, len); - return 1; - } - - - if (0 && cmd == CMD_3D_PRIM) - do_3d_prim(s, data, dwords * 4); - else - flush_cmds(s, data, dwords * 4); - - data += dwords; - len -= dwords * 4; - } - - return 0; -} - - - -static void parse_data_write( struct aub_state *s, - const struct aub_block_header *bh, - void *dest, - const unsigned int *data, - int len ) -{ - switch (bh->type) { - case DW_GENERAL_STATE: - switch (bh->general_state_type) { - case DWGS_VERTEX_SHADER_STATE: { - struct brw_vs_unit_state vs; - assert(len == sizeof(vs)); - - _mesa_printf("DWGS_VERTEX_SHADER_STATE\n"); - memcpy(&vs, data, sizeof(vs)); - -/* vs.vs6.vert_cache_disable = 1; */ -/* vs.thread4.max_threads = 4; */ - - memcpy(dest, &vs, sizeof(vs)); - return; - } - case DWGS_CLIPPER_STATE: { - struct brw_clip_unit_state clip; - assert(len == sizeof(clip)); - - _mesa_printf("DWGS_CLIPPER_STATE\n"); - memcpy(&clip, data, sizeof(clip)); - -/* clip.thread4.max_threads = 0; */ -/* clip.clip5.clip_mode = BRW_CLIPMODE_REJECT_ALL; */ - - memcpy(dest, &clip, sizeof(clip)); - return; - } - - case DWGS_NOTYPE: - case DWGS_GEOMETRY_SHADER_STATE: - case DWGS_STRIPS_FANS_STATE: - break; - - case DWGS_WINDOWER_IZ_STATE: { - struct brw_wm_unit_state wm; - assert(len == sizeof(wm)); - - _mesa_printf("DWGS_WINDOWER_IZ_STATE\n"); - memcpy(&wm, data, sizeof(wm)); - -/* wm.wm5.max_threads = 10; */ - - memcpy(dest, &wm, sizeof(wm)); - return; - } - - case DWGS_COLOR_CALC_STATE: - case DWGS_CLIPPER_VIEWPORT_STATE: - case DWGS_STRIPS_FANS_VIEWPORT_STATE: - case DWGS_COLOR_CALC_VIEWPORT_STATE: - case DWGS_SAMPLER_STATE: - case DWGS_KERNEL_INSTRUCTIONS: - case DWGS_SCRATCH_SPACE: - case DWGS_SAMPLER_DEFAULT_COLOR: - case DWGS_INTERFACE_DESCRIPTOR: - case DWGS_VLD_STATE: - case DWGS_VFE_STATE: - default: - break; - } - break; - case DW_SURFACE_STATE: - break; - case DW_1D_MAP: - case DW_2D_MAP: - case DW_CUBE_MAP: - case DW_VOLUME_MAP: - case DW_CONSTANT_BUFFER: - case DW_CONSTANT_URB_ENTRY: - case DW_VERTEX_BUFFER: - case DW_INDEX_BUFFER: - default: - break; - } - - memcpy(dest, data, len); -} - - -/* In order to work, the memory layout has to be the same as the X - * server which created the aubfile. - */ -static int parse_block_header( struct aub_state *s ) -{ - struct aub_block_header *bh = (struct aub_block_header *)(s->map + s->csr); - void *data = (void *)(bh + 1); - unsigned int len = (bh->length + 3) & ~3; - - _mesa_printf("block header at 0x%x\n", s->csr); - - if (s->csr + len + sizeof(*bh) > s->sz) { - _mesa_printf("EOF in data in %s\n", __FUNCTION__); - return 1; - } - - if (bh->address_space == ADDR_GTT) { - - switch (bh->operation) - { - case BH_DATA_WRITE: { - void *dest = bmFindVirtual( s->intel, bh->address, len ); - if (dest == NULL) { - _mesa_printf("Couldn't find virtual address for offset %x\n", bh->address); - return 1; - } - -#if 1 - parse_data_write(s, bh, dest, data, len); -#else - memcpy(dest, data, len); -#endif - break; - } - case BH_COMMAND_WRITE: -#if 0 - intel_cmd_ioctl(s->intel, (void *)data, len); -#else - if (parse_commands(s, data, len) != 0) - _mesa_printf("parse_commands failed\n"); -#endif - break; - default: - break; - } - } - - s->csr += sizeof(*bh) + len; - return 0; -} - - -#define AUB_FILE_HEADER 0xe085000b -#define AUB_BLOCK_HEADER 0xe0c10003 -#define AUB_DUMP_BMP 0xe09e0004 - -int brw_playback_aubfile(struct brw_context *brw, - const char *filename) -{ - struct intel_context *intel = &brw->intel; - struct aub_state state; - struct stat sb; - int fd; - int retval = 0; - - state.intel = intel; - - fd = open(filename, O_RDONLY, 0); - if (fd < 0) { - _mesa_printf("couldn't open aubfile: %s\n", filename); - return 1; - } - - if (fstat(fd, &sb) != 0) { - _mesa_printf("couldn't open %s\n", filename); - return 1; - } - - state.csr = 0; - state.sz = sb.st_size; - state.map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - - if (state.map == NULL) { - _mesa_printf("couldn't mmap %s\n", filename); - return 1; - } - - LOCK_HARDWARE(intel); - { - /* Make sure we don't confuse anything that might happen to be - * going on with the hardware: - */ -/* bmEvictAll(intel); */ -/* intel->vtbl.lost_hardware(intel); */ - - - /* Replay the aubfile item by item: - */ - while (retval == 0 && - state.csr != state.sz) { - unsigned int insn = *(unsigned int *)(state.map + state.csr); - - switch (insn) { - case AUB_FILE_HEADER: - retval = gobble(&state, sizeof(struct aub_file_header)); - break; - - case AUB_BLOCK_HEADER: - retval = parse_block_header(&state); - break; - - case AUB_DUMP_BMP: - retval = gobble(&state, sizeof(struct aub_dump_bmp)); - break; - - default: - _mesa_printf("unknown instruction %x\n", insn); - retval = 1; - break; - } - } - } - UNLOCK_HARDWARE(intel); - return retval; -} - - - - - - - diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 397a9bd3f5..0ccdd8a661 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -31,7 +31,6 @@ #include "brw_context.h" -#include "brw_aub.h" #include "brw_defines.h" #include "brw_draw.h" #include "brw_vs.h" @@ -135,8 +134,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, driInitExtensions( ctx, brw_extensions, GL_FALSE ); - brw_aub_init( brw ); - brw_init_attribs( brw ); brw_init_metaops( brw ); brw_init_state( brw ); @@ -156,14 +153,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, brw_FrameBufferTexInit( brw ); - { - const char *filename = getenv("INTEL_REPLAY"); - if (filename) { - brw_playback_aubfile(brw, filename); - exit(0); - } - } - return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 08fdc54520..aa797b72ce 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -277,9 +277,6 @@ struct brw_cache { GLuint key_size; /* for fixed-size keys */ GLuint aux_size; - GLuint aub_type; - GLuint aub_sub_type; - GLuint last_addr; /* offset of active item */ }; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 5bf0ed536b..d3c88c1dca 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -42,7 +42,6 @@ #include "brw_defines.h" #include "brw_state.h" #include "brw_util.h" -#include "brw_aub.h" /* Partition the CURBE between the various users of constant values: @@ -315,13 +314,11 @@ static void upload_constant_buffer(struct brw_context *brw) /* Copy data to the buffer: */ - bmBufferSubDataAUB(&brw->intel, - pool->buffer, - brw->curbe.gs_offset, - bufsz, - buf, - DW_CONSTANT_BUFFER, - 0); + bmBufferSubData(&brw->intel, + pool->buffer, + brw->curbe.gs_offset, + bufsz, + buf); } /* TODO: only emit the constant_buffer packet when necessary, ie: diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 5ca9b2f549..b23b357988 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -36,7 +36,6 @@ #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" -#include "brw_aub.h" #include "brw_state.h" #include "brw_fallback.h" @@ -468,11 +467,6 @@ void brw_draw_prims( GLcontext *ctx, _swsetup_Wakeup(ctx); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); } - - 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 dc289ca9ae..fc2e3035af 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -36,7 +36,6 @@ #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" -#include "brw_aub.h" #include "brw_state.h" #include "brw_fallback.h" diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index f7b1d31810..8e8fea48e9 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -36,7 +36,6 @@ #include "tnl/tnl.h" #include "brw_context.h" -#include "brw_aub.h" #include "brw_util.h" static void brwBindProgram( GLcontext *ctx, diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c index 909b0acd12..b78b51328a 100644 --- a/src/mesa/drivers/dri/i965/brw_state_batch.c +++ b/src/mesa/drivers/dri/i965/brw_state_batch.c @@ -32,7 +32,6 @@ #include "brw_state.h" -#include "brw_aub.h" #include "intel_batchbuffer.h" #include "imports.h" diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 71c6938f9a..98d765ac0e 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -31,7 +31,6 @@ #include "brw_state.h" -#include "brw_aub.h" #include "intel_batchbuffer.h" #include "imports.h" @@ -188,13 +187,11 @@ GLuint brw_upload_cache( struct brw_cache *cache, /* Copy data to the buffer: */ - bmBufferSubDataAUB(&cache->brw->intel, - cache->pool->buffer, - offset, - data_size, - data, - cache->aub_type, - cache->aub_sub_type); + bmBufferSubData(&cache->brw->intel, + cache->pool->buffer, + offset, + data_size, + data); cache->brw->state.dirty.cache |= 1<id; @@ -227,17 +224,17 @@ GLuint brw_cache_data(struct brw_cache *cache, return brw_cache_data_sz(cache, data, cache->key_size); } - - - +enum pool_type { + DW_SURFACE_STATE, + DW_GENERAL_STATE +}; static void brw_init_cache( struct brw_context *brw, const char *name, GLuint id, GLuint key_size, GLuint aux_size, - GLuint aub_type, - GLuint aub_sub_type ) + enum pool_type pool_type) { struct brw_cache *cache = &brw->cache[id]; cache->brw = brw; @@ -254,9 +251,7 @@ static void brw_init_cache( struct brw_context *brw, cache->key_size = key_size; cache->aux_size = aux_size; - cache->aub_type = aub_type; - cache->aub_sub_type = aub_sub_type; - switch (aub_type) { + switch (pool_type) { case DW_GENERAL_STATE: cache->pool = &brw->pool[BRW_GS_POOL]; break; case DW_SURFACE_STATE: cache->pool = &brw->pool[BRW_SS_POOL]; break; default: assert(0); break; @@ -271,136 +266,119 @@ void brw_init_caches( struct brw_context *brw ) BRW_CC_VP, sizeof(struct brw_cc_viewport), 0, - DW_GENERAL_STATE, - DWGS_COLOR_CALC_VIEWPORT_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "CC_UNIT", BRW_CC_UNIT, sizeof(struct brw_cc_unit_state), 0, - DW_GENERAL_STATE, - DWGS_COLOR_CALC_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "WM_PROG", BRW_WM_PROG, sizeof(struct brw_wm_prog_key), sizeof(struct brw_wm_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "SAMPLER_DEFAULT_COLOR", BRW_SAMPLER_DEFAULT_COLOR, sizeof(struct brw_sampler_default_color), 0, - DW_GENERAL_STATE, - DWGS_SAMPLER_DEFAULT_COLOR); + DW_GENERAL_STATE); brw_init_cache(brw, "SAMPLER", BRW_SAMPLER, 0, /* variable key/data size */ 0, - DW_GENERAL_STATE, - DWGS_SAMPLER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "WM_UNIT", BRW_WM_UNIT, sizeof(struct brw_wm_unit_state), 0, - DW_GENERAL_STATE, - DWGS_WINDOWER_IZ_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "SF_PROG", BRW_SF_PROG, sizeof(struct brw_sf_prog_key), sizeof(struct brw_sf_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "SF_VP", BRW_SF_VP, sizeof(struct brw_sf_viewport), 0, - DW_GENERAL_STATE, - DWGS_STRIPS_FANS_VIEWPORT_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "SF_UNIT", BRW_SF_UNIT, sizeof(struct brw_sf_unit_state), 0, - DW_GENERAL_STATE, - DWGS_STRIPS_FANS_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "VS_UNIT", BRW_VS_UNIT, sizeof(struct brw_vs_unit_state), 0, - DW_GENERAL_STATE, - DWGS_VERTEX_SHADER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "VS_PROG", BRW_VS_PROG, sizeof(struct brw_vs_prog_key), sizeof(struct brw_vs_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "CLIP_UNIT", BRW_CLIP_UNIT, sizeof(struct brw_clip_unit_state), 0, - DW_GENERAL_STATE, - DWGS_CLIPPER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "CLIP_PROG", BRW_CLIP_PROG, sizeof(struct brw_clip_prog_key), sizeof(struct brw_clip_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "GS_UNIT", BRW_GS_UNIT, sizeof(struct brw_gs_unit_state), 0, - DW_GENERAL_STATE, - DWGS_GEOMETRY_SHADER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "GS_PROG", BRW_GS_PROG, sizeof(struct brw_gs_prog_key), sizeof(struct brw_gs_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "SS_SURFACE", BRW_SS_SURFACE, sizeof(struct brw_surface_state), 0, - DW_SURFACE_STATE, - DWSS_SURFACE_STATE); + DW_SURFACE_STATE); brw_init_cache(brw, "SS_SURF_BIND", BRW_SS_SURF_BIND, sizeof(struct brw_surface_binding_table), 0, - DW_SURFACE_STATE, - DWSS_BINDING_TABLE_STATE); + DW_SURFACE_STATE); } diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c index b9926f2a5d..708ae857ab 100644 --- a/src/mesa/drivers/dri/i965/brw_state_pool.c +++ b/src/mesa/drivers/dri/i965/brw_state_pool.c @@ -126,10 +126,7 @@ void brw_pool_check_wrap( struct brw_context *brw, struct brw_mem_pool *pool ) { if (pool->offset > (pool->size * 3) / 4) { - if (brw->intel.aub_file) - brw->intel.aub_wrap = 1; - else - brw->state.dirty.brw |= BRW_NEW_CONTEXT; + brw->state.dirty.brw |= BRW_NEW_CONTEXT; } } diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 786f30e641..d8cb168802 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -47,7 +47,6 @@ #include "brw_draw.h" #include "brw_state.h" -#include "brw_aub.h" #include "brw_fallback.h" #include "brw_vs.h" @@ -60,8 +59,6 @@ static void brw_destroy_context( struct intel_context *intel ) GLcontext *ctx = &intel->ctx; struct brw_context *brw = brw_context(&intel->ctx); - brw_aub_destroy(brw); - brw_destroy_metaops(brw); brw_destroy_state(brw); brw_draw_destroy( brw ); diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h index e748c0d6d0..b31c2e6d9b 100644 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -130,24 +130,6 @@ int bmBufferSubData(struct intel_context *, unsigned size, const void *data ); - -int bmBufferDataAUB(struct intel_context *, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags, - unsigned aubtype, - unsigned aubsubtype ); - -int bmBufferSubDataAUB(struct intel_context *, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data, - unsigned aubtype, - unsigned aubsubtype ); - - /* In this version, taking the offset will provoke an upload on * buffers not already resident in AGP: */ @@ -170,12 +152,6 @@ void *bmMapBuffer( struct intel_context *, void bmUnmapBuffer( struct intel_context *, struct buffer *buf ); -void bmUnmapBufferAUB( struct intel_context *, - struct buffer *buf, - unsigned aubtype, - unsigned aubsubtype ); - - /* Pertains to all buffers who's offset has been taken since the last * fence or release. */ diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c index 24ee11edd8..a85121122f 100644 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -85,7 +85,6 @@ struct buffer { unsigned mapped:1; unsigned dirty:1; - unsigned aub_dirty:1; unsigned alignment:13; unsigned flags:16; @@ -906,86 +905,6 @@ int bmBufferSubData(struct intel_context *intel, return retval; } - - -int bmBufferDataAUB(struct intel_context *intel, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags, - unsigned aubtype, - unsigned aubsubtype ) -{ - int retval = bmBufferData(intel, buf, size, data, flags); - - - /* This only works because in this version of the buffer manager we - * allocate all buffers statically in agp space and so can emit the - * uploads to the aub file with the correct offsets as they happen. - */ - if (retval == 0 && data && intel->aub_file) { - - if (buf->block && !buf->dirty) { - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs, - buf->block->virtual, - size, - aubtype, - aubsubtype); - buf->aub_dirty = 0; - } - } - - return retval; -} - - -int bmBufferSubDataAUB(struct intel_context *intel, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data, - unsigned aubtype, - unsigned aubsubtype ) -{ - int retval = bmBufferSubData(intel, buf, offset, size, data); - - - /* This only works because in this version of the buffer manager we - * allocate all buffers statically in agp space and so can emit the - * uploads to the aub file with the correct offsets as they happen. - */ - if (intel->aub_file) { - if (retval == 0 && buf->block && !buf->dirty) - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs + offset, - ((const char *)buf->block->virtual) + offset, - size, - aubtype, - aubsubtype); - } - - return retval; -} - -void bmUnmapBufferAUB( struct intel_context *intel, - struct buffer *buf, - unsigned aubtype, - unsigned aubsubtype ) -{ - bmUnmapBuffer(intel, buf); - - if (intel->aub_file) { - /* Hack - exclude the framebuffer mappings. If you removed - * this, you'd get very big aubfiles, but you *would* be able to - * see fallback rendering. - */ - if (buf->block && !buf->dirty && buf->block->pool == &intel->bm->pool[0]) { - buf->aub_dirty = 1; - } - } -} - unsigned bmBufferOffset(struct intel_context *intel, struct buffer *buf) { @@ -1197,26 +1116,7 @@ int bmValidateBuffers( struct intel_context *intel ) buf->backing_store, buf->size); - if (intel->aub_file) { - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs, - buf->backing_store, - buf->size, - 0, - 0); - } - buf->dirty = 0; - buf->aub_dirty = 0; - } - else if (buf->aub_dirty) { - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs, - buf->block->virtual, - buf->size, - 0, - 0); - buf->aub_dirty = 0; } block->referenced = 0; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 64885ed9b4..2aaa10e1c2 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -168,31 +168,12 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) goto out; } - - if (intel->aub_file) { - /* Send buffered commands to aubfile as a single packet. - */ - intel_batchbuffer_map(batch); - ((int *)batch->ptr)[-1] = intel->vtbl.flush_cmd(); - intel->vtbl.aub_commands(intel, - offset, /* Fulsim wierdness - don't adjust */ - batch->map + batch->offset, - used); - ((int *)batch->ptr)[-1] = MI_BATCH_BUFFER_END; - intel_batchbuffer_unmap(batch); - } - - /* Fire the batch buffer, which was uploaded above: */ intel_batch_ioctl(batch->intel, offset + batch->offset, used); - if (intel->aub_file && - intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) - intel->vtbl.aub_dump_bmp( intel, 0 ); - /* Reset the buffer: */ out: diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c index 015e433fd7..3349284f5d 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c @@ -103,8 +103,7 @@ static void intel_bufferobj_data( GLcontext *ctx, obj->Size = size; obj->Usage = usage; - bmBufferDataAUB(intel, intel_obj->buffer, size, data, 0, - 0, 0); + bmBufferData(intel, intel_obj->buffer, size, data, 0); } @@ -125,7 +124,7 @@ static void intel_bufferobj_subdata( GLcontext *ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - bmBufferSubDataAUB(intel, intel_obj->buffer, offset, size, data, 0, 0); + bmBufferSubData(intel, intel_obj->buffer, offset, size, data); } @@ -181,7 +180,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, assert(intel_obj); assert(intel_obj->buffer); assert(obj->Pointer); - bmUnmapBufferAUB(intel, intel_obj->buffer, 0, 0); + bmUnmapBuffer(intel, intel_obj->buffer); obj->Pointer = NULL; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index d155c039d7..6c8b073502 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -450,12 +450,6 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv ) } else { intelCopyBuffer( dPriv, NULL ); } - if (intel->aub_file) { - intelFlush(ctx); - intel->vtbl.aub_dump_bmp( intel, 1 ); - - intel->aub_wrap = 1; - } } } else { /* XXX this shouldn't be an error but we can't handle it for now */ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index f3ec2b2eee..022819d582 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -668,13 +668,6 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; - if (intel->aub_wrap) { - bm_fake_NotifyContendedLockTake( intel ); - intel->vtbl.lost_hardware( intel ); - intel->vtbl.aub_wrap(intel); - intel->aub_wrap = 0; - } - if (bmError(intel)) { bmEvictAll(intel); intel->vtbl.lost_hardware( intel ); diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 053d93a82b..06cfc6946d 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -109,20 +109,6 @@ struct intel_context void (*emit_flush)( struct intel_context *intel, GLuint unused ); - void (*aub_commands)( struct intel_context *intel, - GLuint offset, - const void *buf, - GLuint sz ); - void (*aub_dump_bmp)( struct intel_context *intel, GLuint buffer ); - void (*aub_wrap)( struct intel_context *intel ); - void (*aub_gtt_data)( struct intel_context *intel, - GLuint offset, - const void *src, - GLuint size, - GLuint aubtype, - GLuint aubsubtype); - - void (*reduced_primitive_state)( struct intel_context *intel, GLenum rprim ); GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected ); @@ -176,7 +162,6 @@ struct intel_context GLuint last_swap_fence; GLuint second_last_swap_fence; - GLboolean aub_wrap; GLuint stats_wm; struct intel_batchbuffer *batch; @@ -238,8 +223,6 @@ struct intel_context __DRIscreenPrivate *driScreen; intelScreenPrivate *intelScreen; volatile drmI830Sarea *sarea; - - FILE *aub_file; GLuint lastStamp; diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 0a8e976f70..e7e736079f 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -115,10 +115,6 @@ void intelWaitIrq( struct intel_context *intel, int seq ) if ( ret ) { fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); - if (intel->aub_file) { - intel->vtbl.aub_dump_bmp( intel, intel->ctx.Visual.doubleBufferMode ? 1 : 0 ); - } - exit(1); } } diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 835ecdd725..b78eba898f 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel, { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - bmUnmapBufferAUB(intel, region->buffer, 0, 0); + bmUnmapBuffer(intel, region->buffer); region->map = NULL; } } @@ -217,10 +217,10 @@ GLboolean intel_region_data(struct intel_context *intel, srcx == 0 && srcy == 0) { - return (bmBufferDataAUB(intel, - dst->buffer, - dst->cpp * width * dst->height, - src, 0, 0, 0) == 0); + return (bmBufferData(intel, + dst->buffer, + dst->cpp * width * dst->height, + src, 0) == 0); } else { GLubyte *map = intel_region_map(intel, dst); -- cgit v1.2.3 From b2f1aa2389473ed09170713301b042661d70a48e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Sep 2007 10:16:04 -0700 Subject: WIP 965 conversion to dri_bufmgr. --- src/mesa/drivers/dri/i915/Makefile | 1 + src/mesa/drivers/dri/i915/intel_batchbuffer.c | 331 ------ src/mesa/drivers/dri/i915/intel_batchbuffer.h | 122 -- src/mesa/drivers/dri/i965/Makefile | 2 +- src/mesa/drivers/dri/i965/brw_context.h | 4 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 6 +- src/mesa/drivers/dri/i965/brw_state_pool.c | 2 +- src/mesa/drivers/dri/i965/brw_state_upload.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/bufmgr.h | 191 --- src/mesa/drivers/dri/i965/bufmgr_fake.c | 1360 ---------------------- src/mesa/drivers/dri/i965/intel_batchbuffer.c | 13 +- src/mesa/drivers/dri/i965/intel_batchbuffer.h | 4 +- src/mesa/drivers/dri/i965/intel_blit.c | 16 +- src/mesa/drivers/dri/i965/intel_blit.h | 10 +- src/mesa/drivers/dri/i965/intel_buffer_objects.c | 4 +- src/mesa/drivers/dri/i965/intel_buffer_objects.h | 4 +- src/mesa/drivers/dri/i965/intel_context.c | 25 +- src/mesa/drivers/dri/i965/intel_ioctl.c | 2 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/i965/intel_regions.c | 12 +- src/mesa/drivers/dri/i965/intel_regions.h | 4 +- src/mesa/drivers/dri/i965/intel_screen.c | 59 +- src/mesa/drivers/dri/i965/intel_screen.h | 7 + src/mesa/drivers/dri/i965/intel_tex_layout.c | 103 +- src/mesa/drivers/dri/i965/intel_tex_validate.c | 2 +- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 331 ++++++ src/mesa/drivers/dri/intel/intel_batchbuffer.h | 122 ++ 28 files changed, 673 insertions(+), 2070 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.c delete mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.h delete mode 100644 src/mesa/drivers/dri/i965/bufmgr.h delete mode 100644 src/mesa/drivers/dri/i965/bufmgr_fake.c mode change 120000 => 100644 src/mesa/drivers/dri/i965/intel_tex_layout.c create mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.h (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index d3d0bd570c..0e2cdcb240 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -66,6 +66,7 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ include ../Makefile.template +intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c symlinks: diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c deleted file mode 100644 index 8ee48b5a68..0000000000 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - * - * 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 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 "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_decode.h" -#include "i915_debug.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->size = intel->intelScreen->maxBatchSize; - batch->ptr = batch->map; -} - -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->last_fence = NULL; - intel_batchbuffer_reset(batch); - - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - dri_fence_wait(batch->last_fence); - dri_fence_unreference(batch->last_fence); - batch->last_fence = NULL; - } - if (batch->map) { - dri_bo_unmap(batch->buf); - batch->map = NULL; - } - dri_bo_unreference(batch->buf); - batch->buf = NULL; - free(batch); -} - -static int -relocation_sort(const void *a_in, const void *b_in) { - const struct buffer_reloc *a = a_in, *b = b_in; - - return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; -} - - -/* TODO: Push this whole function into bufmgr. - */ -static void -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - GLuint *ptr; - GLuint i; - struct intel_context *intel = batch->intel; - dri_fence *fo; - GLboolean performed_rendering = GL_FALSE; - - assert(batch->buf->virtual != NULL); - ptr = batch->buf->virtual; - - /* Sort our relocation list in terms of referenced buffer pointer. - * This lets us uniquely validate the buffers with the sum of all the flags, - * while avoiding O(n^2) on number of relocations. - */ - qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), - relocation_sort); - - /* Perform the necessary validations of buffers, and enter the relocations - * in the batchbuffer. - */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - - if (r->validate_flags & DRM_BO_FLAG_WRITE) - performed_rendering = GL_TRUE; - - /* If this is the first time we've seen this buffer in the relocation - * list, figure out our flags and validate it. - */ - if (i == 0 || batch->reloc[i - 1].buf != r->buf) { - uint32_t validate_flags; - int j, ret; - - /* Accumulate the flags we need for validating this buffer. */ - validate_flags = r->validate_flags; - for (j = i + 1; j < batch->nr_relocs; j++) { - if (batch->reloc[j].buf != r->buf) - break; - validate_flags |= batch->reloc[j].validate_flags; - } - - /* Validate. If we fail, fence to clear the unfenced list and bail - * out. - */ - ret = dri_bo_validate(r->buf, validate_flags); - if (ret != 0) { - dri_bo_unmap(batch->buf); - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "batchbuffer failure fence", GL_TRUE); - dri_fence_unreference(fo); - goto done; - } - } - ptr[r->offset / 4] = r->buf->offset + r->delta; - dri_bo_unreference(r->buf); - } - - dri_bo_unmap(batch->buf); - batch->map = NULL; - batch->ptr = NULL; - - dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { - intel_batch_ioctl(batch->intel, - batch->buf->offset, - used, ignore_cliprects, allow_unlock); - } - - /* Associate a fence with the validated buffers, and note that we included - * a flush at the end. - */ - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "Batch fence", GL_TRUE); - - if (performed_rendering) { - dri_fence_unreference(batch->last_fence); - batch->last_fence = fo; - } else { - /* If we didn't validate any buffers for writing by the card, we don't - * need to track the fence for glFinish(). - */ - dri_fence_unreference(fo); - } - - if (intel->numClipRects == 0 && !ignore_cliprects) { - if (allow_unlock) { - /* If we are not doing any actual user-visible rendering, - * do a sched_yield to keep the app from pegging the cpu while - * achieving nothing. - */ - UNLOCK_HARDWARE(intel); - sched_yield(); - LOCK_HARDWARE(intel); - } - intel->vtbl.lost_hardware(intel); - } - -done: - if (INTEL_DEBUG & DEBUG_BATCH) { - dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); - dri_bo_unmap(batch->buf); - } -} - - -void -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - GLboolean was_locked = intel->locked; - - if (used == 0) - return; - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - intel_batchbuffer_flush(batch); - if (batch->last_fence != NULL) - dri_fence_wait(batch->last_fence); -} - - -/* This is the only way buffers get added to the validate list. - */ -GLboolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint delta) -{ - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - - assert(batch->nr_relocs <= MAX_RELOCS); - - dri_bo_reference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - r->validate_flags = flags; - - batch->ptr += 4; - return GL_TRUE; -} - - - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - __memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h deleted file mode 100644 index 850a91e1c9..0000000000 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "mtypes.h" -#include "dri_bufmgr.h" - -struct intel_context; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define MAX_RELOCS 4096 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct buffer_reloc -{ - dri_bo *buf; - GLuint offset; - GLuint delta; /* not needed? */ - GLuint validate_flags; -}; - -struct intel_batchbuffer -{ - struct intel_context *intel; - - dri_bo *buf; - dri_fence *last_fence; - GLuint flags; - - drmBOList list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - struct buffer_reloc reloc[MAX_RELOCS]; - GLuint nr_relocs; - GLuint size; -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -void intel_batchbuffer_flush(struct intel_batchbuffer *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint offset); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf, flags, delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ -} while (0) - -#define ADVANCE_BATCH() do { } while(0) - - -#endif diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 5748d7ff05..07256ce1e5 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -5,7 +5,6 @@ include $(TOP)/configs/current LIBNAME = i965_dri.so DRIVER_SOURCES = \ - bufmgr_fake.c \ intel_batchbuffer.c \ intel_blit.c \ intel_buffer_objects.c \ @@ -92,6 +91,7 @@ DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c server: diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index aa797b72ce..279baf8c83 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -242,7 +242,7 @@ struct brw_surface_binding_table { struct brw_cache; struct brw_mem_pool { - struct buffer *buffer; + dri_bo *buffer; GLuint size; GLuint offset; /* offset of first free byte */ @@ -605,7 +605,7 @@ struct brw_context GLuint nr_surfaces; GLuint max_threads; - struct buffer *scratch_buffer; + dri_bo *scratch_buffer; GLuint scratch_buffer_size; GLuint sampler_count; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index fc2e3035af..5f6f0ef5a6 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -58,7 +58,7 @@ struct brw_array_state { GLuint dword; } vb0; - struct buffer *buffer; + dri_bo *buffer; GLuint offset; GLuint max_index; @@ -68,7 +68,7 @@ struct brw_array_state { }; -static struct buffer *array_buffer( const struct gl_client_array *array ) +static dri_bo *array_buffer( const struct gl_client_array *array ) { return intel_bufferobj_buffer(intel_buffer_object(array->BufferObj)); } @@ -620,7 +620,7 @@ void brw_upload_indices( struct brw_context *brw, */ { struct brw_indexbuffer ib; - struct buffer *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); + dri_bo *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); memset(&ib, 0, sizeof(ib)); diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c index 708ae857ab..9677c73583 100644 --- a/src/mesa/drivers/dri/i965/brw_state_pool.c +++ b/src/mesa/drivers/dri/i965/brw_state_pool.c @@ -34,7 +34,7 @@ #include "imports.h" #include "intel_ioctl.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" GLboolean brw_pool_alloc( struct brw_mem_pool *pool, GLuint size, diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 92c07c2962..d5e575ef66 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -33,7 +33,7 @@ #include "brw_context.h" #include "brw_state.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "intel_batchbuffer.h" /* This is used to initialize brw->state.atoms[]. We could use this diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 5b4f2abd0e..b1de66d988 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -34,7 +34,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" /*********************************************************************** * WM unit - fragment programs and rasterization diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h deleted file mode 100644 index b31c2e6d9b..0000000000 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ /dev/null @@ -1,191 +0,0 @@ -/************************************************************************** - * - * 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 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. - * - **************************************************************************/ - -#ifndef BUFMGR_H -#define BUFMGR_H - -#include "intel_context.h" - - -/* The buffer manager context. Opaque. - */ -struct bufmgr; -struct buffer; - - -struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); - -/* Flags for validate and other calls. If both NO_UPLOAD and NO_EVICT - * are specified, ValidateBuffers is essentially a query. - */ -#define BM_MEM_LOCAL 0x1 -#define BM_MEM_AGP 0x2 -#define BM_MEM_VRAM 0x4 /* not yet used */ -#define BM_WRITE 0x8 /* not yet used */ -#define BM_READ 0x10 /* not yet used */ -#define BM_NO_UPLOAD 0x20 -#define BM_NO_EVICT 0x40 -#define BM_NO_MOVE 0x80 /* not yet used */ -#define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */ -#define BM_CLIENT 0x200 /* for map - pointer will be accessed - * without dri lock */ - -#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM) - - - - -/* Create a pool of a given memory type, from a certain offset and a - * certain size. - * - * Also passed in is a virtual pointer to the start of the pool. This - * is useful in the faked-out version in i915 so that MapBuffer can - * return a pointer to a buffer residing in AGP space. - * - * Flags passed into a pool are inherited by all buffers allocated in - * that pool. So pools representing the static front,back,depth - * buffer allocations should have MEM_AGP|NO_UPLOAD|NO_EVICT|NO_MOVE to match - * the behaviour of the legacy allocations. - * - * Returns -1 for failure, pool number for success. - */ -int bmInitPool( struct intel_context *, - unsigned long low_offset, - void *low_virtual, - unsigned long size, - unsigned flags); - - -/* Stick closely to ARB_vbo semantics - they're well defined and - * understood, and drivers can just pass the calls through without too - * much thunking. - */ -void bmGenBuffers(struct intel_context *, const char *, unsigned n, struct buffer **buffers, - int align ); -void bmDeleteBuffers(struct intel_context *, unsigned n, struct buffer **buffers); - - -/* Hook to inform faked buffer manager about fixed-position - * front,depth,back buffers. These may move to a fully memory-managed - * scheme, or they may continue to be managed as is. - */ -struct buffer *bmGenBufferStatic(struct intel_context *, - unsigned pool); - -/* On evict, buffer manager will call invalidate_cb() to note that the - * buffer needs to be reloaded. - * - * Buffer is uploaded by calling bmMapBuffer() and copying data into - * the returned pointer. - * - * This is basically a big hack to get some more performance by - * turning off backing store for buffers where we either have it - * already (textures) or don't need it (batch buffers, temporary - * vbo's). - */ -void bmBufferSetInvalidateCB(struct intel_context *, - struct buffer *buf, - void (*invalidate_cb)( struct intel_context *, void *ptr ), - void *ptr, - GLboolean dont_fence_subdata); - - -/* The driver has more intimate knowledge of the hardare than a GL - * client would, so flags here is more proscriptive than the usage - * values in the ARB_vbo interface: - */ -int bmBufferData(struct intel_context *, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags ); - -int bmBufferSubData(struct intel_context *, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data ); - -/* In this version, taking the offset will provoke an upload on - * buffers not already resident in AGP: - */ -unsigned bmBufferOffset(struct intel_context *, - struct buffer *buf); - - -/* Extract data from the buffer: - */ -void bmBufferGetSubData(struct intel_context *, - struct buffer *buf, - unsigned offset, - unsigned size, - void *data ); - -void *bmMapBuffer( struct intel_context *, - struct buffer *buf, - unsigned access ); - -void bmUnmapBuffer( struct intel_context *, - struct buffer *buf ); - -/* Pertains to all buffers who's offset has been taken since the last - * fence or release. - */ -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 * ); - -void *bmFindVirtual( struct intel_context *intel, - unsigned int offset, - size_t sz ); - -/* This functionality is used by the buffer manager, not really sure - * if we need to be exposing it in this way, probably libdrm will - * offer equivalent calls. - * - * For now they can stay, but will likely change/move before final: - */ -unsigned bmSetFence( struct intel_context * ); -unsigned bmSetFenceLock( struct intel_context * ); -unsigned bmLockAndFence( struct intel_context *intel ); -int bmTestFence( struct intel_context *, unsigned fence ); -void bmFinishFence( struct intel_context *, unsigned fence ); -void bmFinishFenceLock( struct intel_context *, unsigned fence ); - -void bm_fake_NotifyContendedLockTake( struct intel_context * ); - -extern int INTEL_DEBUG; -#define DEBUG_BUFMGR 0x10000000 - -#define DBG(...) do { if (INTEL_DEBUG & DEBUG_BUFMGR) _mesa_printf(__VA_ARGS__); } while(0) - -#endif diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c deleted file mode 100644 index a85121122f..0000000000 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ /dev/null @@ -1,1360 +0,0 @@ -/************************************************************************** - * - * 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 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. - * - **************************************************************************/ - -/* Originally a fake version of the buffer manager so that we can - * prototype the changes in a driver fairly quickly, has been fleshed - * out to a fully functional interim solution. - * - * Basically wraps the old style memory management in the new - * programming interface, but is more expressive and avoids many of - * the bugs in the old texture manager. - */ -#include "bufmgr.h" - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" - -#include "simple_list.h" -#include "mm.h" -#include "imports.h" - -#define BM_POOL_MAX 8 - -/* Internal flags: - */ -#define BM_NO_BACKING_STORE 0x2000 -#define BM_NO_FENCE_SUBDATA 0x4000 - - -static int check_fenced( struct intel_context *intel ); - -static int nr_attach = 0; - -/* Wrapper around mm.c's mem_block, which understands that you must - * wait for fences to expire before memory can be freed. This is - * specific to our use of memcpy for uploads - an upload that was - * processed through the command queue wouldn't need to care about - * fences. - */ -struct block { - struct block *next, *prev; - struct pool *pool; /* BM_MEM_AGP */ - struct mem_block *mem; /* BM_MEM_AGP */ - - unsigned referenced:1; - unsigned on_hardware:1; - unsigned fenced:1; - - - unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */ - - struct buffer *buf; - void *virtual; -}; - - -struct buffer { - unsigned id; /* debug only */ - const char *name; - unsigned size; - - unsigned mapped:1; - unsigned dirty:1; - unsigned alignment:13; - unsigned flags:16; - - struct block *block; - void *backing_store; - void (*invalidate_cb)( struct intel_context *, void * ); - void *invalidate_ptr; -}; - -struct pool { - unsigned size; - unsigned low_offset; - struct buffer *static_buffer; - unsigned flags; - struct mem_block *heap; - void *virtual; - struct block lru; /* only allocated, non-fence-pending blocks here */ -}; - -struct bufmgr { - _glthread_Mutex mutex; /**< for thread safety */ - struct pool pool[BM_POOL_MAX]; - unsigned nr_pools; - - unsigned buf_nr; /* for generating ids */ - - struct block referenced; /* after bmBufferOffset */ - struct block on_hardware; /* after bmValidateBuffers */ - 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; - - unsigned fail:1; - unsigned need_fence:1; -}; - -#define MAXFENCE 0x7fffffff - -static GLboolean FENCE_LTE( unsigned a, unsigned b ) -{ - if (a == b) - return GL_TRUE; - - if (a < b && b - a < (1<<24)) - return GL_TRUE; - - if (a > b && MAXFENCE - a + b < (1<<24)) - return GL_TRUE; - - return GL_FALSE; -} - -int bmTestFence( struct intel_context *intel, unsigned fence ) -{ - /* Slight problem with wrap-around: - */ - return fence == 0 || FENCE_LTE(fence, intel->sarea->last_dispatch); -} - -#define LOCK(bm) \ - int dolock = nr_attach > 1; \ - if (dolock) _glthread_LOCK_MUTEX(bm->mutex) - -#define UNLOCK(bm) \ - if (dolock) _glthread_UNLOCK_MUTEX(bm->mutex) - - - -static GLboolean alloc_from_pool( struct intel_context *intel, - unsigned pool_nr, - struct buffer *buf ) -{ - struct bufmgr *bm = intel->bm; - struct pool *pool = &bm->pool[pool_nr]; - struct block *block = (struct block *)calloc(sizeof *block, 1); - GLuint sz, align = (1<alignment); - - if (!block) - return GL_FALSE; - - sz = (buf->size + align-1) & ~(align-1); - - block->mem = mmAllocMem(pool->heap, - sz, - buf->alignment, 0); - if (!block->mem) { - free(block); - return GL_FALSE; - } - - make_empty_list(block); - - /* Insert at head or at tail??? - */ - insert_at_tail(&pool->lru, block); - - block->pool = pool; - block->virtual = pool->virtual + block->mem->ofs; - block->buf = buf; - - buf->block = block; - - return GL_TRUE; -} - - - - - - - - -/* Release the card storage associated with buf: - */ -static void free_block( struct intel_context *intel, struct block *block ) -{ - DBG("free block %p\n", block); - - if (!block) - return; - - check_fenced(intel); - - if (block->referenced) { - _mesa_printf("tried to free block on referenced list\n"); - assert(0); - } - else if (block->on_hardware) { - block->buf = NULL; - intel->bm->free_on_hardware += block->mem->size; - } - else if (block->fenced) { - block->buf = NULL; - } - else { - DBG(" - free immediately\n"); - remove_from_list(block); - - mmFreeMem(block->mem); - free(block); - } -} - - -static void alloc_backing_store( struct intel_context *intel, struct buffer *buf ) -{ - assert(!buf->backing_store); - assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); - - buf->backing_store = ALIGN_MALLOC(buf->size, 64); -} - -static void free_backing_store( struct intel_context *intel, struct buffer *buf ) -{ - assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); - - if (buf->backing_store) { - ALIGN_FREE(buf->backing_store); - buf->backing_store = NULL; - } -} - - - - - - -static void set_dirty( struct intel_context *intel, - struct buffer *buf ) -{ - if (buf->flags & BM_NO_BACKING_STORE) - buf->invalidate_cb(intel, buf->invalidate_ptr); - - assert(!(buf->flags & BM_NO_EVICT)); - - DBG("set_dirty - buf %d\n", buf->id); - buf->dirty = 1; -} - - -static int evict_lru( struct intel_context *intel, GLuint max_fence, GLuint *pool ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - int i; - - DBG("%s\n", __FUNCTION__); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s(block, tmp, &bm->pool[i].lru) { - - if (block->buf && - (block->buf->flags & BM_NO_FENCE_SUBDATA)) - continue; - - if (block->fence && max_fence && - !FENCE_LTE(block->fence, max_fence)) - return 0; - - set_dirty(intel, block->buf); - block->buf->block = NULL; - - free_block(intel, block); - *pool = i; - return 1; - } - } - } - - - return 0; -} - - -#define foreach_s_rev(ptr, t, list) \ - for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev) - -static int evict_mru( struct intel_context *intel, GLuint *pool ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - int i; - - DBG("%s\n", __FUNCTION__); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s_rev(block, tmp, &bm->pool[i].lru) { - - if (block->buf && - (block->buf->flags & BM_NO_FENCE_SUBDATA)) - continue; - - set_dirty(intel, block->buf); - block->buf->block = NULL; - - free_block(intel, block); - *pool = i; - return 1; - } - } - } - - - return 0; -} - - -static int check_fenced( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - int ret = 0; - - foreach_s(block, tmp, &bm->fenced ) { - assert(block->fenced); - - if (bmTestFence(intel, block->fence)) { - - block->fenced = 0; - - if (!block->buf) { - DBG("delayed free: offset %x sz %x\n", block->mem->ofs, block->mem->size); - remove_from_list(block); - mmFreeMem(block->mem); - free(block); - } - else { - DBG("return to lru: offset %x sz %x\n", block->mem->ofs, block->mem->size); - move_to_tail(&block->pool->lru, block); - } - - ret = 1; - } - else { - /* Blocks are ordered by fence, so if one fails, all from - * here will fail also: - */ - break; - } - } - - /* Also check the referenced list: - */ - foreach_s(block, tmp, &bm->referenced ) { - if (block->fenced && - bmTestFence(intel, block->fence)) { - block->fenced = 0; - } - } - - - DBG("%s: %d\n", __FUNCTION__, ret); - return ret; -} - - - -static void fence_blocks( struct intel_context *intel, - unsigned fence ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - - foreach_s (block, tmp, &bm->on_hardware) { - DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, - block->mem->size, block->buf, fence); - block->fence = fence; - - block->on_hardware = 0; - block->fenced = 1; - - /* Move to tail of pending list here - */ - move_to_tail(&bm->fenced, block); - } - - /* Also check the referenced list: - */ - foreach_s (block, tmp, &bm->referenced) { - if (block->on_hardware) { - DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, - block->mem->size, block->buf, fence); - - block->fence = fence; - block->on_hardware = 0; - block->fenced = 1; - } - } - - - bm->last_fence = fence; - assert(is_empty_list(&bm->on_hardware)); -} - - - - -static GLboolean alloc_block( struct intel_context *intel, - struct buffer *buf ) -{ - struct bufmgr *bm = intel->bm; - int i; - - assert(intel->locked); - - DBG("%s 0x%x bytes (%s)\n", __FUNCTION__, buf->size, buf->name); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_ALLOC) && - alloc_from_pool(intel, i, buf)) { - - DBG("%s --> 0x%x (sz %x)\n", __FUNCTION__, - buf->block->mem->ofs, buf->block->mem->size); - - return GL_TRUE; - } - } - - DBG("%s --> fail\n", __FUNCTION__); - return GL_FALSE; -} - - -static GLboolean evict_and_alloc_block( struct intel_context *intel, - struct buffer *buf ) -{ - GLuint pool; - struct bufmgr *bm = intel->bm; - - assert(buf->block == NULL); - - /* Put a cap on the amount of free memory we'll allow to accumulate - * before emitting a fence. - */ - if (bm->free_on_hardware > 1 * 1024 * 1024) { - DBG("fence for free space: %x\n", bm->free_on_hardware); - bmSetFence(intel); - } - - /* Search for already free memory: - */ - if (alloc_block(intel, buf)) - return GL_TRUE; - - /* Look for memory that may have become free: - */ - if (check_fenced(intel) && - alloc_block(intel, buf)) - return GL_TRUE; - - /* Look for memory blocks not used for >1 frame: - */ - while (evict_lru(intel, intel->second_last_swap_fence, &pool)) - if (alloc_from_pool(intel, pool, buf)) - return GL_TRUE; - - /* If we're not thrashing, allow lru eviction to dig deeper into - * recently used textures. We'll probably be thrashing soon: - */ - if (!intel->thrashing) { - while (evict_lru(intel, 0, &pool)) - if (alloc_from_pool(intel, pool, buf)) - return GL_TRUE; - } - - /* Keep thrashing counter alive? - */ - if (intel->thrashing) - intel->thrashing = 20; - - /* Wait on any already pending fences - here we are waiting for any - * freed memory that has been submitted to hardware and fenced to - * become available: - */ - while (!is_empty_list(&bm->fenced)) { - GLuint fence = bm->fenced.next->fence; - bmFinishFence(intel, fence); - - if (alloc_block(intel, buf)) - return GL_TRUE; - } - - - /* - */ - if (!is_empty_list(&bm->on_hardware)) { - bmSetFence(intel); - - while (!is_empty_list(&bm->fenced)) { - GLuint fence = bm->fenced.next->fence; - bmFinishFence(intel, fence); - } - - if (!intel->thrashing) { - DBG("thrashing\n"); - } - intel->thrashing = 20; - - if (alloc_block(intel, buf)) - return GL_TRUE; - } - - while (evict_mru(intel, &pool)) - if (alloc_from_pool(intel, pool, buf)) - return GL_TRUE; - - DBG("%s 0x%x bytes failed\n", __FUNCTION__, buf->size); - - assert(is_empty_list(&bm->on_hardware)); - assert(is_empty_list(&bm->fenced)); - - return GL_FALSE; -} - - - - - - - - - - -/*********************************************************************** - * Public functions - */ - - -/* The initialization functions are skewed in the fake implementation. - * This call would be to attach to an existing manager, rather than to - * create a local one. - */ -struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ) -{ - _glthread_DECLARE_STATIC_MUTEX(initMutex); - static struct bufmgr bm; - - /* This function needs a mutex of its own... - */ - _glthread_LOCK_MUTEX(initMutex); - - if (nr_attach == 0) { - _glthread_INIT_MUTEX(bm.mutex); - - 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++; - - _glthread_UNLOCK_MUTEX(initMutex); - - return &bm; -} - - - -/* The virtual pointer would go away in a true implementation. - */ -int bmInitPool( struct intel_context *intel, - unsigned long low_offset, - void *low_virtual, - unsigned long size, - unsigned flags) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - LOCK(bm); - { - GLuint i; - - for (i = 0; i < bm->nr_pools; i++) { - if (bm->pool[i].low_offset == low_offset && - bm->pool[i].size == size) { - retval = i; - goto out; - } - } - - - if (bm->nr_pools >= BM_POOL_MAX) - retval = -1; - else { - i = bm->nr_pools++; - - DBG("bmInitPool %d low_offset %x sz %x\n", - i, low_offset, size); - - bm->pool[i].low_offset = low_offset; - bm->pool[i].size = size; - bm->pool[i].heap = mmInit( low_offset, size ); - bm->pool[i].virtual = low_virtual - low_offset; - bm->pool[i].flags = flags; - - make_empty_list(&bm->pool[i].lru); - - retval = i; - } - } - out: - UNLOCK(bm); - return retval; -} - -static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name, int align) -{ - struct bufmgr *bm = intel->bm; - struct buffer *buf = calloc(sizeof(*buf), 1); - - buf->id = ++bm->buf_nr; - buf->name = name; - buf->alignment = align; - buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL; - - return buf; -} - - -void *bmFindVirtual( struct intel_context *intel, - unsigned int offset, - size_t sz ) -{ - struct bufmgr *bm = intel->bm; - int i; - - for (i = 0; i < bm->nr_pools; i++) - if (offset >= bm->pool[i].low_offset && - offset + sz <= bm->pool[i].low_offset + bm->pool[i].size) - return bm->pool[i].virtual + offset; - - return NULL; -} - - -void bmGenBuffers(struct intel_context *intel, - const char *name, unsigned n, - struct buffer **buffers, - int align ) -{ - struct bufmgr *bm = intel->bm; - LOCK(bm); - { - int i; - - for (i = 0; i < n; i++) - buffers[i] = do_GenBuffer(intel, name, align); - } - UNLOCK(bm); -} - - -void bmDeleteBuffers(struct intel_context *intel, unsigned n, struct buffer **buffers) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - unsigned i; - - for (i = 0; i < n; i++) { - struct buffer *buf = buffers[i]; - - if (buf && buf->block) - free_block(intel, buf->block); - - if (buf) - free(buf); - } - } - UNLOCK(bm); -} - - - - -/* Hook to inform faked buffer manager about fixed-position - * front,depth,back buffers. These may move to a fully memory-managed - * scheme, or they may continue to be managed as is. It will probably - * be useful to pass a fixed offset here one day. - */ -struct buffer *bmGenBufferStatic(struct intel_context *intel, - unsigned pool ) -{ - struct bufmgr *bm = intel->bm; - struct buffer *buf; - LOCK(bm); - { - assert(bm->pool[pool].flags & BM_NO_EVICT); - assert(bm->pool[pool].flags & BM_NO_MOVE); - - if (bm->pool[pool].static_buffer) - buf = bm->pool[pool].static_buffer; - else { - buf = do_GenBuffer(intel, "static", 12); - - bm->pool[pool].static_buffer = buf; - assert(!buf->block); - - buf->size = bm->pool[pool].size; - buf->flags = bm->pool[pool].flags; - buf->alignment = 12; - - if (!alloc_from_pool(intel, pool, buf)) - assert(0); - } - } - UNLOCK(bm); - return buf; -} - - -static void wait_quiescent(struct intel_context *intel, - struct block *block) -{ - if (block->on_hardware) { - assert(intel->bm->need_fence); - bmSetFence(intel); - assert(!block->on_hardware); - } - - - if (block->fenced) { - bmFinishFence(intel, block->fence); - } - - assert(!block->on_hardware); - assert(!block->fenced); -} - - - -/* If buffer size changes, free and reallocate. Otherwise update in - * place. - */ -int bmBufferData(struct intel_context *intel, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags ) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - LOCK(bm); - { - DBG("bmBufferData %d sz 0x%x data: %p\n", buf->id, size, data); - - assert(!buf->mapped); - - if (buf->block) { - struct block *block = buf->block; - - /* Optimistic check to see if we can reuse the block -- not - * required for correctness: - */ - if (block->fenced) - check_fenced(intel); - - if (block->on_hardware || - block->fenced || - (buf->size && buf->size != size) || - (data == NULL)) { - - assert(!block->referenced); - - free_block(intel, block); - buf->block = NULL; - buf->dirty = 1; - } - } - - buf->size = size; - if (buf->block) { - assert (buf->block->mem->size >= size); - } - - if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { - - assert(intel->locked || data == NULL); - - if (data != NULL) { - if (!buf->block && !evict_and_alloc_block(intel, buf)) { - bm->fail = 1; - retval = -1; - goto out; - } - - wait_quiescent(intel, buf->block); - - DBG("bmBufferData %d offset 0x%x sz 0x%x\n", - buf->id, buf->block->mem->ofs, size); - - assert(buf->block->virtual == buf->block->pool->virtual + buf->block->mem->ofs); - - do_memcpy(buf->block->virtual, data, size); - } - buf->dirty = 0; - } - else { - DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); - set_dirty(intel, buf); - free_backing_store(intel, buf); - - if (data != NULL) { - alloc_backing_store(intel, buf); - do_memcpy(buf->backing_store, data, size); - } - } - } - out: - UNLOCK(bm); - return retval; -} - - -/* Update the buffer in place, in whatever space it is currently resident: - */ -int bmBufferSubData(struct intel_context *intel, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data ) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - if (size == 0) - return 0; - - LOCK(bm); - { - DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); - - assert(offset+size <= buf->size); - - if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { - - assert(intel->locked); - - if (!buf->block && !evict_and_alloc_block(intel, buf)) { - bm->fail = 1; - retval = -1; - goto out; - } - - if (!(buf->flags & BM_NO_FENCE_SUBDATA)) - wait_quiescent(intel, buf->block); - - buf->dirty = 0; - - do_memcpy(buf->block->virtual + offset, data, size); - } - else { - DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); - set_dirty(intel, buf); - - if (buf->backing_store == NULL) - alloc_backing_store(intel, buf); - - do_memcpy(buf->backing_store + offset, data, size); - } - } - out: - UNLOCK(bm); - return retval; -} - -unsigned bmBufferOffset(struct intel_context *intel, - struct buffer *buf) -{ - struct bufmgr *bm = intel->bm; - unsigned retval = 0; - - LOCK(bm); - { - assert(intel->locked); - - if (!buf->block && - !evict_and_alloc_block(intel, buf)) { - bm->fail = 1; - retval = ~0; - } - else { - assert(buf->block); - assert(buf->block->buf == buf); - - DBG("Add buf %d (block %p, dirty %d) to referenced list\n", buf->id, buf->block, - buf->dirty); - - move_to_tail(&bm->referenced, buf->block); - buf->block->referenced = 1; - - retval = buf->block->mem->ofs; - } - } - UNLOCK(bm); - - return retval; -} - - - -/* Extract data from the buffer: - */ -void bmBufferGetSubData(struct intel_context *intel, - struct buffer *buf, - unsigned offset, - unsigned size, - void *data ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); - - if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { - if (buf->block && size) { - wait_quiescent(intel, buf->block); - do_memcpy(data, buf->block->virtual + offset, size); - } - } - else { - if (buf->backing_store && size) { - do_memcpy(data, buf->backing_store + offset, size); - } - } - } - UNLOCK(bm); -} - - -/* Return a pointer to whatever space the buffer is currently resident in: - */ -void *bmMapBuffer( struct intel_context *intel, - struct buffer *buf, - unsigned flags ) -{ - struct bufmgr *bm = intel->bm; - void *retval = NULL; - - LOCK(bm); - { - DBG("bmMapBuffer %d\n", buf->id); - - if (buf->mapped) { - _mesa_printf("%s: already mapped\n", __FUNCTION__); - retval = NULL; - } - else if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { - - assert(intel->locked); - - if (!buf->block && !evict_and_alloc_block(intel, buf)) { - DBG("%s: alloc failed\n", __FUNCTION__); - bm->fail = 1; - retval = NULL; - } - else { - assert(buf->block); - buf->dirty = 0; - - if (!(buf->flags & BM_NO_FENCE_SUBDATA)) - wait_quiescent(intel, buf->block); - - buf->mapped = 1; - retval = buf->block->virtual; - } - } - else { - DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); - set_dirty(intel, buf); - - if (buf->backing_store == 0) - alloc_backing_store(intel, buf); - - buf->mapped = 1; - retval = buf->backing_store; - } - } - UNLOCK(bm); - return retval; -} - -void bmUnmapBuffer( struct intel_context *intel, struct buffer *buf ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - DBG("bmUnmapBuffer %d\n", buf->id); - buf->mapped = 0; - } - UNLOCK(bm); -} - - - - -/* This is the big hack that turns on BM_NO_BACKING_STORE. Basically - * says that an external party will maintain the backing store, eg - * Mesa's local copy of texture data. - */ -void bmBufferSetInvalidateCB(struct intel_context *intel, - struct buffer *buf, - void (*invalidate_cb)( struct intel_context *, void *ptr ), - void *ptr, - GLboolean dont_fence_subdata) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - if (buf->backing_store) - free_backing_store(intel, buf); - - buf->flags |= BM_NO_BACKING_STORE; - - if (dont_fence_subdata) - buf->flags |= BM_NO_FENCE_SUBDATA; - - DBG("bmBufferSetInvalidateCB set buf %d dirty\n", buf->id); - buf->dirty = 1; - buf->invalidate_cb = invalidate_cb; - buf->invalidate_ptr = ptr; - - /* Note that it is invalid right from the start. Also note - * invalidate_cb is called with the bufmgr locked, so cannot - * itself make bufmgr calls. - */ - invalidate_cb( intel, ptr ); - } - UNLOCK(bm); -} - - - - - - - -/* This is only protected against thread interactions by the DRI lock - * and the policy of ensuring that all dma is flushed prior to - * releasing that lock. Otherwise you might have two threads building - * up a list of buffers to validate at once. - */ -int bmValidateBuffers( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - LOCK(bm); - { - DBG("%s fail %d\n", __FUNCTION__, bm->fail); - assert(intel->locked); - - if (!bm->fail) { - struct block *block, *tmp; - - foreach_s(block, tmp, &bm->referenced) { - struct buffer *buf = block->buf; - - DBG("Validate buf %d / block %p / dirty %d\n", buf->id, block, buf->dirty); - - /* Upload the buffer contents if necessary: - */ - if (buf->dirty) { - DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", buf->id, - buf->name, buf->size, block->mem->ofs); - - assert(!(buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT))); - - wait_quiescent(intel, buf->block); - - do_memcpy(buf->block->virtual, - buf->backing_store, - buf->size); - - buf->dirty = 0; - } - - block->referenced = 0; - block->on_hardware = 1; - move_to_tail(&bm->on_hardware, block); - } - - bm->need_fence = 1; - } - - retval = bm->fail ? -1 : 0; - } - UNLOCK(bm); - - - if (retval != 0) - DBG("%s failed\n", __FUNCTION__); - - return retval; -} - - - - -void bmReleaseBuffers( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - struct block *block, *tmp; - - foreach_s (block, tmp, &bm->referenced) { - - DBG("remove block %p from referenced list\n", block); - - if (block->on_hardware) { - /* Return to the on-hardware list. - */ - move_to_tail(&bm->on_hardware, block); - } - else if (block->fenced) { - struct block *s; - - /* Hmm - have to scan the fenced list to insert the - * buffers in order. This is O(nm), but rare and the - * numbers are low. - */ - foreach (s, &bm->fenced) { - if (FENCE_LTE(block->fence, s->fence)) - break; - } - - move_to_tail(s, block); - } - else { - /* Return to the lru list: - */ - move_to_tail(&block->pool->lru, block); - } - - block->referenced = 0; - } - } - UNLOCK(bm); -} - - -/* This functionality is used by the buffer manager, not really sure - * if we need to be exposing it in this way, probably libdrm will - * offer equivalent calls. - * - * For now they can stay, but will likely change/move before final: - */ -unsigned bmSetFence( struct intel_context *intel ) -{ - assert(intel->locked); - - /* Emit MI_FLUSH here: - */ - if (intel->bm->need_fence) { - - /* Emit a flush without using a batchbuffer. Can't rely on the - * batchbuffer at this level really. Would really prefer that - * the IRQ ioctly emitted the flush at the same time. - */ - GLuint dword[2]; - dword[0] = intel->vtbl.flush_cmd(); - dword[1] = 0; - intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword)); - - intel->bm->last_fence = intelEmitIrqLocked( intel ); - - fence_blocks(intel, intel->bm->last_fence); - - intel->vtbl.note_fence(intel, intel->bm->last_fence); - intel->bm->need_fence = 0; - - if (intel->thrashing) { - intel->thrashing--; - if (!intel->thrashing) - DBG("not thrashing\n"); - } - - intel->bm->free_on_hardware = 0; - } - - return intel->bm->last_fence; -} - -unsigned bmSetFenceLock( struct intel_context *intel ) -{ - unsigned last; - LOCK(intel->bm); - last = bmSetFence(intel); - UNLOCK(intel->bm); - return last; -} -unsigned bmLockAndFence( struct intel_context *intel ) -{ - if (intel->bm->need_fence) { - LOCK_HARDWARE(intel); - LOCK(intel->bm); - bmSetFence(intel); - UNLOCK(intel->bm); - UNLOCK_HARDWARE(intel); - } - - return intel->bm->last_fence; -} - - -void bmFinishFence( struct intel_context *intel, unsigned fence ) -{ - if (!bmTestFence(intel, fence)) { - DBG("...wait on fence %d\n", fence); - intelWaitIrq( intel, fence ); - } - assert(bmTestFence(intel, fence)); - check_fenced(intel); -} - -void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) -{ - LOCK(intel->bm); - bmFinishFence(intel, fence); - UNLOCK(intel->bm); -} - - -/* Specifically ignore texture memory sharing. - * -- just evict everything - * -- and wait for idle - */ -void bm_fake_NotifyContendedLockTake( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - struct block *block, *tmp; - GLuint i; - - assert(is_empty_list(&bm->referenced)); - - bm->need_fence = 1; - bm->fail = 0; - bmFinishFence(intel, bmSetFence(intel)); - - assert(is_empty_list(&bm->fenced)); - assert(is_empty_list(&bm->on_hardware)); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s(block, tmp, &bm->pool[i].lru) { - assert(bmTestFence(intel, block->fence)); - set_dirty(intel, block->buf); - } - } - } - } - UNLOCK(bm); -} - - - -void bmEvictAll( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - struct block *block, *tmp; - GLuint i; - - DBG("%s\n", __FUNCTION__); - - assert(is_empty_list(&bm->referenced)); - - bm->need_fence = 1; - bm->fail = 0; - bmFinishFence(intel, bmSetFence(intel)); - - assert(is_empty_list(&bm->fenced)); - assert(is_empty_list(&bm->on_hardware)); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s(block, tmp, &bm->pool[i].lru) { - assert(bmTestFence(intel, block->fence)); - set_dirty(intel, block->buf); - block->buf->block = NULL; - - free_block(intel, block); - } - } - } - } - UNLOCK(bm); -} - - -GLboolean bmError( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - GLboolean retval; - - LOCK(bm); - { - retval = bm->fail; - } - UNLOCK(bm); - - 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 2aaa10e1c2..e4557a3847 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -28,13 +28,24 @@ #include "imports.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" static void intel_batchbuffer_reset( struct intel_batchbuffer *batch ) { assert(batch->map == NULL); + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->offset = (unsigned long)batch->ptr; batch->offset = (batch->offset + 63) & ~63; batch->ptr = (unsigned char *) batch->offset; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index 25e0a65e99..a824966d2e 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -29,7 +29,7 @@ #define INTEL_BATCHBUFFER_H #include "mtypes.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" struct intel_context; @@ -43,7 +43,7 @@ struct intel_context; struct intel_batchbuffer { struct intel_context *intel; - struct buffer *buffer; + dri_bo *buffer; GLuint flags; unsigned long offset; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index f88cbb2328..4502c551a7 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -41,7 +41,7 @@ #include "intel_regions.h" #include "intel_structs.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - bmFinishFenceLock(intel, intel->last_swap_fence); + dri_fence_wait(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -154,8 +154,10 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, } intel_batchbuffer_flush( intel->batch ); + + dri_fence_unreference(intel->second_last_swap_fence); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = bmSetFenceLock( intel ); + intel->last_swap_fence = dri_fence_reference(intel->bmbmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) @@ -178,7 +180,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -250,11 +252,11 @@ static GLuint translate_raster_op(GLenum logicop) void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct buffer *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort src_x, GLshort src_y, @@ -528,7 +530,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index e361545c8f..45dd33db66 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_ioctl.h" -struct buffer; +dri_bo; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); @@ -40,11 +40,11 @@ extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct buffer *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort srcx, GLshort srcy, @@ -55,7 +55,7 @@ extern void intelEmitCopyBlit( struct intel_context *intel, extern void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -68,7 +68,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort dst_x, GLshort dst_y, diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c index 3349284f5d..32c458987d 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c @@ -32,7 +32,7 @@ #include "intel_context.h" #include "intel_buffer_objects.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" /** @@ -185,7 +185,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, return GL_TRUE; } -struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) +dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) { assert(intel_obj->Base.Name); assert(intel_obj->buffer); diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.h b/src/mesa/drivers/dri/i965/intel_buffer_objects.h index 4b38803e57..a80f448716 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.h @@ -39,13 +39,13 @@ struct gl_buffer_object; */ struct intel_buffer_object { struct gl_buffer_object Base; - struct buffer *buffer; /* the low-level buffer manager's buffer handle */ + dri_bo *buffer; /* the low-level buffer manager's buffer handle */ }; /* Get the bm buffer associated with a GL bufferobject: */ -struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); +dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); /* Hook the bufferobject implementation into mesa: */ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 022819d582..37c9fa3ec3 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -58,7 +58,7 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "utils.h" #include "vblank.h" @@ -635,10 +635,10 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags ) /* 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) { + if (sarea->texAge != intel->hHWContext) { DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr); - sarea->texAge = my_bufmgr; - bm_fake_NotifyContendedLockTake( intel ); + sarea->texAge = intel->hHWContext; + dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); } /* Drawable changed? @@ -668,11 +668,6 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; - if (bmError(intel)) { - bmEvictAll(intel); - intel->vtbl.lost_hardware( intel ); - } - /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -680,16 +675,8 @@ void LOCK_HARDWARE( struct intel_context *intel ) /* XXX: postpone, may not be needed: */ if (!intel_batchbuffer_map(intel->batch)) { - bmEvictAll(intel); - intel->vtbl.lost_hardware( intel ); - - /* This could only fail if the batchbuffer was greater in size - * than the available texture memory: - */ - if (!intel_batchbuffer_map(intel->batch)) { - _mesa_printf("double failure to map batchbuffer\n"); - assert(0); - } + _mesa_printf("failure to map batchbuffer\n"); + assert(0); } } diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index e7e736079f..88d5983027 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -41,7 +41,7 @@ #include "intel_blit.h" #include "intel_regions.h" #include "drm.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" static int intelWaitIdleLocked( struct intel_context *intel ) { diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 0fb33e27f4..8db61267b5 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -28,7 +28,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "enums.h" #include "imports.h" diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index b78eba898f..9bf858cacb 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -42,7 +42,7 @@ #include "intel_context.h" #include "intel_regions.h" #include "intel_blit.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "imports.h" /* XXX: Thread safety? @@ -51,7 +51,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi { DBG("%s\n", __FUNCTION__); if (!region->map_refcount++) { - region->map = bmMapBuffer(intel, region->buffer, 0); + region->map = dri_bo_map(region->buffer, GL_TRUE); if (!region->map) region->map_refcount--; } @@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel, { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - bmUnmapBuffer(intel, region->buffer); + dri_bo_unmap(region->buffer); region->map = NULL; } } @@ -84,8 +84,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel, region->height = height; /* needed? */ region->refcount = 1; - bmGenBuffers(intel, "tex", 1, ®ion->buffer, 6); - bmBufferData(intel, region->buffer, pitch * cpp * height, NULL, 0); + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); return region; } @@ -108,7 +108,7 @@ void intel_region_release( struct intel_context *intel, if (--(*region)->refcount == 0) { assert((*region)->map_refcount == 0); - bmDeleteBuffers(intel, 1, &(*region)->buffer); + dri_bo_unreference((*region)->buffer); free(*region); } *region = NULL; diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index d2235f1275..8505d7eedc 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -29,7 +29,7 @@ #define INTEL_REGIONS_H #include "mtypes.h" -#include "bufmgr.h" /* for DBG! */ +#include "dri_bufmgr.h" /* for DBG! */ struct intel_context; /* A layer on top of the bufmgr buffers that adds a few useful things: @@ -40,7 +40,7 @@ struct intel_context; * - Blitter commands for copying 2D regions between buffers. */ struct intel_region { - struct buffer *buffer; + dri_bo *buffer; GLuint refcount; GLuint cpp; GLuint pitch; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 5dac50df32..06bf9214f0 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -109,12 +109,18 @@ intelMapScreenRegions(__DRIscreenPrivate *sPriv) return GL_FALSE; } - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *)&intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; + if (intelScreen->tex.size != 0) { + intelScreen->ttm = GL_FALSE; + + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *)&intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + } else { + intelScreen->ttm = GL_TRUE; } if (0) @@ -163,6 +169,32 @@ intelUnmapScreenRegions(intelScreenPrivate *intelScreen) } } +/** Driver-specific fence emit implementation for the fake memory manager. */ +static unsigned int +intel_fence_emit(void *private) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + unsigned int fence; + + /* XXX: Need to emit a flush, if we haven't already (at least with the + * current batchbuffer implementation, we have). + */ + + fence = intelEmitIrqLocked(intelScreen); + + return fence; +} + +/** Driver-specific fence wait implementation for the fake memory manager. */ +static int +intel_fence_wait(void *private, unsigned int cookie) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + + intelWaitIrq(intelScreen, cookie); + + return 0; +} static void intelPrintDRIInfo(intelScreenPrivate *intelScreen, @@ -359,7 +391,19 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); } - + + assert(!intelScreen->ttm); + intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intelScreen); + if (intelScreen->bufmgr == FALSE) { + fprintf(stderr, "Couldn't initialize buffer manager\n"); + return GL_FALSE; + } + return GL_TRUE; } @@ -369,6 +413,7 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv) intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; intelUnmapScreenRegions(intelScreen); + dri_bufmgr_destroy(intelScreen->bufmgr); FREE(intelScreen); sPriv->private = NULL; } diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index bf9a716082..bb004822c4 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -80,6 +80,13 @@ typedef struct * Configuration cache with default values for all contexts */ driOptionCache optionCache; + + /** + * This value indicates that the kernel memory manager is being used + * instead of the fake client-side memory manager. + */ + GLboolean ttm; + dri_bufmgr *bufmgr; } intelScreenPrivate; diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c deleted file mode 120000 index fe61b44194..0000000000 --- a/src/mesa/drivers/dri/i965/intel_tex_layout.c +++ /dev/null @@ -1 +0,0 @@ -../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c new file mode 100644 index 0000000000..fcb5cc3906 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * 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 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" +#include "macros.h" + + +static int align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + +void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) +{ + GLint align_h = 2, align_w = 4; + GLuint level; + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + + mt->pitch = mt->width0; + + /* May need to adjust pitch to accomodate the placement of + * the 2nd mipmap. This occurs when the alignment + * constraints of mipmap placement push the right edge of the + * 2nd mipmap out past the width of its parent. + */ + if (mt->first_level != mt->last_level) { + GLuint mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + + if (mip1_width > mt->width0) + mt->pitch = mip1_width; + } + + /* Pitch must be a whole number of dwords, even though we + * express it in texels. + */ + mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; + mt->total_height = 0; + + for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + GLuint img_height; + + intel_miptree_set_level_info(mt, level, 1, x, y, width, + height, 1); + + if (mt->compressed) + img_height = MAX2(1, height/4); + else + img_height = align(height, align_h); + + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + mt->total_height = MAX2(mt->total_height, y + img_height); + + /* Layout_below: step right after second mipmap. + */ + if (level == mt->first_level + 1) { + x += align(width, align_w); + } + else { + y += img_height; + } + + width = minify(width); + height = minify(height); + } +} diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 8c05e7cdab..0cfb32f76d 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" /** * Compute which mipmap levels that really need to be sent to the hardware. diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c new file mode 100644 index 0000000000..8ee48b5a68 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -0,0 +1,331 @@ +/************************************************************************** + * + * 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 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 "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_decode.h" +#include "i915_debug.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->last_fence = NULL; + intel_batchbuffer_reset(batch); + + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + dri_bo_unmap(batch->buf); + batch->map = NULL; + } + dri_bo_unreference(batch->buf); + batch->buf = NULL; + free(batch); +} + +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; + + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); + } + + dri_bo_unmap(batch->buf); + batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + batch->buf->offset, + used, ignore_cliprects, allow_unlock); + } + + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. + */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); + + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); + batch->last_fence = fo; + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } + +done: + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + intel_decode(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } +} + + +void +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + + if (used == 0) + return; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint delta) +{ + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + + assert(batch->nr_relocs <= MAX_RELOCS); + + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h new file mode 100644 index 0000000000..850a91e1c9 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h @@ -0,0 +1,122 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + dri_bo *buf; + GLuint offset; + GLuint delta; /* not needed? */ + GLuint validate_flags; +}; + +struct intel_batchbuffer +{ + struct intel_context *intel; + + dri_bo *buf; + dri_fence *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif -- cgit v1.2.3 From e886ae4c58bc98897d6901e3f30deea008bc7f8a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Sep 2007 15:11:39 -0700 Subject: Revert "WIP 965 conversion to dri_bufmgr." This reverts commit b2f1aa2389473ed09170713301b042661d70a48e. Somehow I ended up with my branch's save-this-while-I-work-on-master commit actually on master. --- src/mesa/drivers/dri/i915/Makefile | 1 - src/mesa/drivers/dri/i915/intel_batchbuffer.c | 331 ++++++ src/mesa/drivers/dri/i915/intel_batchbuffer.h | 122 ++ src/mesa/drivers/dri/i965/Makefile | 2 +- src/mesa/drivers/dri/i965/brw_context.h | 4 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 6 +- src/mesa/drivers/dri/i965/brw_state_pool.c | 2 +- src/mesa/drivers/dri/i965/brw_state_upload.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/bufmgr.h | 191 +++ src/mesa/drivers/dri/i965/bufmgr_fake.c | 1360 ++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_batchbuffer.c | 13 +- src/mesa/drivers/dri/i965/intel_batchbuffer.h | 4 +- src/mesa/drivers/dri/i965/intel_blit.c | 16 +- src/mesa/drivers/dri/i965/intel_blit.h | 10 +- src/mesa/drivers/dri/i965/intel_buffer_objects.c | 4 +- src/mesa/drivers/dri/i965/intel_buffer_objects.h | 4 +- src/mesa/drivers/dri/i965/intel_context.c | 25 +- src/mesa/drivers/dri/i965/intel_ioctl.c | 2 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/i965/intel_regions.c | 12 +- src/mesa/drivers/dri/i965/intel_regions.h | 4 +- src/mesa/drivers/dri/i965/intel_screen.c | 59 +- src/mesa/drivers/dri/i965/intel_screen.h | 7 - src/mesa/drivers/dri/i965/intel_tex_layout.c | 103 +- src/mesa/drivers/dri/i965/intel_tex_validate.c | 2 +- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 331 ------ src/mesa/drivers/dri/intel/intel_batchbuffer.h | 122 -- 28 files changed, 2070 insertions(+), 673 deletions(-) create mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.h create mode 100644 src/mesa/drivers/dri/i965/bufmgr.h create mode 100644 src/mesa/drivers/dri/i965/bufmgr_fake.c mode change 100644 => 120000 src/mesa/drivers/dri/i965/intel_tex_layout.c delete mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.c delete mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.h (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index 0e2cdcb240..d3d0bd570c 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -66,7 +66,6 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ include ../Makefile.template -intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c symlinks: diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c new file mode 100644 index 0000000000..8ee48b5a68 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -0,0 +1,331 @@ +/************************************************************************** + * + * 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 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 "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_decode.h" +#include "i915_debug.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->last_fence = NULL; + intel_batchbuffer_reset(batch); + + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + dri_bo_unmap(batch->buf); + batch->map = NULL; + } + dri_bo_unreference(batch->buf); + batch->buf = NULL; + free(batch); +} + +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; + + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); + } + + dri_bo_unmap(batch->buf); + batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + batch->buf->offset, + used, ignore_cliprects, allow_unlock); + } + + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. + */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); + + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); + batch->last_fence = fo; + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } + +done: + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + intel_decode(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } +} + + +void +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + + if (used == 0) + return; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint delta) +{ + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + + assert(batch->nr_relocs <= MAX_RELOCS); + + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h new file mode 100644 index 0000000000..850a91e1c9 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h @@ -0,0 +1,122 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + dri_bo *buf; + GLuint offset; + GLuint delta; /* not needed? */ + GLuint validate_flags; +}; + +struct intel_batchbuffer +{ + struct intel_context *intel; + + dri_bo *buf; + dri_fence *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 07256ce1e5..5748d7ff05 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -5,6 +5,7 @@ include $(TOP)/configs/current LIBNAME = i965_dri.so DRIVER_SOURCES = \ + bufmgr_fake.c \ intel_batchbuffer.c \ intel_blit.c \ intel_buffer_objects.c \ @@ -91,7 +92,6 @@ DRIVER_DEFINES = -I../intel include ../Makefile.template -intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c server: diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 279baf8c83..aa797b72ce 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -242,7 +242,7 @@ struct brw_surface_binding_table { struct brw_cache; struct brw_mem_pool { - dri_bo *buffer; + struct buffer *buffer; GLuint size; GLuint offset; /* offset of first free byte */ @@ -605,7 +605,7 @@ struct brw_context GLuint nr_surfaces; GLuint max_threads; - dri_bo *scratch_buffer; + struct buffer *scratch_buffer; GLuint scratch_buffer_size; GLuint sampler_count; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 5f6f0ef5a6..fc2e3035af 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -58,7 +58,7 @@ struct brw_array_state { GLuint dword; } vb0; - dri_bo *buffer; + struct buffer *buffer; GLuint offset; GLuint max_index; @@ -68,7 +68,7 @@ struct brw_array_state { }; -static dri_bo *array_buffer( const struct gl_client_array *array ) +static struct buffer *array_buffer( const struct gl_client_array *array ) { return intel_bufferobj_buffer(intel_buffer_object(array->BufferObj)); } @@ -620,7 +620,7 @@ void brw_upload_indices( struct brw_context *brw, */ { struct brw_indexbuffer ib; - dri_bo *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); + struct buffer *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); memset(&ib, 0, sizeof(ib)); diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c index 9677c73583..708ae857ab 100644 --- a/src/mesa/drivers/dri/i965/brw_state_pool.c +++ b/src/mesa/drivers/dri/i965/brw_state_pool.c @@ -34,7 +34,7 @@ #include "imports.h" #include "intel_ioctl.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" GLboolean brw_pool_alloc( struct brw_mem_pool *pool, GLuint size, diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index d5e575ef66..92c07c2962 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -33,7 +33,7 @@ #include "brw_context.h" #include "brw_state.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "intel_batchbuffer.h" /* This is used to initialize brw->state.atoms[]. We could use this diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index b1de66d988..5b4f2abd0e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -34,7 +34,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" /*********************************************************************** * WM unit - fragment programs and rasterization diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h new file mode 100644 index 0000000000..b31c2e6d9b --- /dev/null +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -0,0 +1,191 @@ +/************************************************************************** + * + * 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 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. + * + **************************************************************************/ + +#ifndef BUFMGR_H +#define BUFMGR_H + +#include "intel_context.h" + + +/* The buffer manager context. Opaque. + */ +struct bufmgr; +struct buffer; + + +struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); + +/* Flags for validate and other calls. If both NO_UPLOAD and NO_EVICT + * are specified, ValidateBuffers is essentially a query. + */ +#define BM_MEM_LOCAL 0x1 +#define BM_MEM_AGP 0x2 +#define BM_MEM_VRAM 0x4 /* not yet used */ +#define BM_WRITE 0x8 /* not yet used */ +#define BM_READ 0x10 /* not yet used */ +#define BM_NO_UPLOAD 0x20 +#define BM_NO_EVICT 0x40 +#define BM_NO_MOVE 0x80 /* not yet used */ +#define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */ +#define BM_CLIENT 0x200 /* for map - pointer will be accessed + * without dri lock */ + +#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM) + + + + +/* Create a pool of a given memory type, from a certain offset and a + * certain size. + * + * Also passed in is a virtual pointer to the start of the pool. This + * is useful in the faked-out version in i915 so that MapBuffer can + * return a pointer to a buffer residing in AGP space. + * + * Flags passed into a pool are inherited by all buffers allocated in + * that pool. So pools representing the static front,back,depth + * buffer allocations should have MEM_AGP|NO_UPLOAD|NO_EVICT|NO_MOVE to match + * the behaviour of the legacy allocations. + * + * Returns -1 for failure, pool number for success. + */ +int bmInitPool( struct intel_context *, + unsigned long low_offset, + void *low_virtual, + unsigned long size, + unsigned flags); + + +/* Stick closely to ARB_vbo semantics - they're well defined and + * understood, and drivers can just pass the calls through without too + * much thunking. + */ +void bmGenBuffers(struct intel_context *, const char *, unsigned n, struct buffer **buffers, + int align ); +void bmDeleteBuffers(struct intel_context *, unsigned n, struct buffer **buffers); + + +/* Hook to inform faked buffer manager about fixed-position + * front,depth,back buffers. These may move to a fully memory-managed + * scheme, or they may continue to be managed as is. + */ +struct buffer *bmGenBufferStatic(struct intel_context *, + unsigned pool); + +/* On evict, buffer manager will call invalidate_cb() to note that the + * buffer needs to be reloaded. + * + * Buffer is uploaded by calling bmMapBuffer() and copying data into + * the returned pointer. + * + * This is basically a big hack to get some more performance by + * turning off backing store for buffers where we either have it + * already (textures) or don't need it (batch buffers, temporary + * vbo's). + */ +void bmBufferSetInvalidateCB(struct intel_context *, + struct buffer *buf, + void (*invalidate_cb)( struct intel_context *, void *ptr ), + void *ptr, + GLboolean dont_fence_subdata); + + +/* The driver has more intimate knowledge of the hardare than a GL + * client would, so flags here is more proscriptive than the usage + * values in the ARB_vbo interface: + */ +int bmBufferData(struct intel_context *, + struct buffer *buf, + unsigned size, + const void *data, + unsigned flags ); + +int bmBufferSubData(struct intel_context *, + struct buffer *buf, + unsigned offset, + unsigned size, + const void *data ); + +/* In this version, taking the offset will provoke an upload on + * buffers not already resident in AGP: + */ +unsigned bmBufferOffset(struct intel_context *, + struct buffer *buf); + + +/* Extract data from the buffer: + */ +void bmBufferGetSubData(struct intel_context *, + struct buffer *buf, + unsigned offset, + unsigned size, + void *data ); + +void *bmMapBuffer( struct intel_context *, + struct buffer *buf, + unsigned access ); + +void bmUnmapBuffer( struct intel_context *, + struct buffer *buf ); + +/* Pertains to all buffers who's offset has been taken since the last + * fence or release. + */ +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 * ); + +void *bmFindVirtual( struct intel_context *intel, + unsigned int offset, + size_t sz ); + +/* This functionality is used by the buffer manager, not really sure + * if we need to be exposing it in this way, probably libdrm will + * offer equivalent calls. + * + * For now they can stay, but will likely change/move before final: + */ +unsigned bmSetFence( struct intel_context * ); +unsigned bmSetFenceLock( struct intel_context * ); +unsigned bmLockAndFence( struct intel_context *intel ); +int bmTestFence( struct intel_context *, unsigned fence ); +void bmFinishFence( struct intel_context *, unsigned fence ); +void bmFinishFenceLock( struct intel_context *, unsigned fence ); + +void bm_fake_NotifyContendedLockTake( struct intel_context * ); + +extern int INTEL_DEBUG; +#define DEBUG_BUFMGR 0x10000000 + +#define DBG(...) do { if (INTEL_DEBUG & DEBUG_BUFMGR) _mesa_printf(__VA_ARGS__); } while(0) + +#endif diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c new file mode 100644 index 0000000000..a85121122f --- /dev/null +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -0,0 +1,1360 @@ +/************************************************************************** + * + * 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 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. + * + **************************************************************************/ + +/* Originally a fake version of the buffer manager so that we can + * prototype the changes in a driver fairly quickly, has been fleshed + * out to a fully functional interim solution. + * + * Basically wraps the old style memory management in the new + * programming interface, but is more expressive and avoids many of + * the bugs in the old texture manager. + */ +#include "bufmgr.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" + +#include "simple_list.h" +#include "mm.h" +#include "imports.h" + +#define BM_POOL_MAX 8 + +/* Internal flags: + */ +#define BM_NO_BACKING_STORE 0x2000 +#define BM_NO_FENCE_SUBDATA 0x4000 + + +static int check_fenced( struct intel_context *intel ); + +static int nr_attach = 0; + +/* Wrapper around mm.c's mem_block, which understands that you must + * wait for fences to expire before memory can be freed. This is + * specific to our use of memcpy for uploads - an upload that was + * processed through the command queue wouldn't need to care about + * fences. + */ +struct block { + struct block *next, *prev; + struct pool *pool; /* BM_MEM_AGP */ + struct mem_block *mem; /* BM_MEM_AGP */ + + unsigned referenced:1; + unsigned on_hardware:1; + unsigned fenced:1; + + + unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */ + + struct buffer *buf; + void *virtual; +}; + + +struct buffer { + unsigned id; /* debug only */ + const char *name; + unsigned size; + + unsigned mapped:1; + unsigned dirty:1; + unsigned alignment:13; + unsigned flags:16; + + struct block *block; + void *backing_store; + void (*invalidate_cb)( struct intel_context *, void * ); + void *invalidate_ptr; +}; + +struct pool { + unsigned size; + unsigned low_offset; + struct buffer *static_buffer; + unsigned flags; + struct mem_block *heap; + void *virtual; + struct block lru; /* only allocated, non-fence-pending blocks here */ +}; + +struct bufmgr { + _glthread_Mutex mutex; /**< for thread safety */ + struct pool pool[BM_POOL_MAX]; + unsigned nr_pools; + + unsigned buf_nr; /* for generating ids */ + + struct block referenced; /* after bmBufferOffset */ + struct block on_hardware; /* after bmValidateBuffers */ + 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; + + unsigned fail:1; + unsigned need_fence:1; +}; + +#define MAXFENCE 0x7fffffff + +static GLboolean FENCE_LTE( unsigned a, unsigned b ) +{ + if (a == b) + return GL_TRUE; + + if (a < b && b - a < (1<<24)) + return GL_TRUE; + + if (a > b && MAXFENCE - a + b < (1<<24)) + return GL_TRUE; + + return GL_FALSE; +} + +int bmTestFence( struct intel_context *intel, unsigned fence ) +{ + /* Slight problem with wrap-around: + */ + return fence == 0 || FENCE_LTE(fence, intel->sarea->last_dispatch); +} + +#define LOCK(bm) \ + int dolock = nr_attach > 1; \ + if (dolock) _glthread_LOCK_MUTEX(bm->mutex) + +#define UNLOCK(bm) \ + if (dolock) _glthread_UNLOCK_MUTEX(bm->mutex) + + + +static GLboolean alloc_from_pool( struct intel_context *intel, + unsigned pool_nr, + struct buffer *buf ) +{ + struct bufmgr *bm = intel->bm; + struct pool *pool = &bm->pool[pool_nr]; + struct block *block = (struct block *)calloc(sizeof *block, 1); + GLuint sz, align = (1<alignment); + + if (!block) + return GL_FALSE; + + sz = (buf->size + align-1) & ~(align-1); + + block->mem = mmAllocMem(pool->heap, + sz, + buf->alignment, 0); + if (!block->mem) { + free(block); + return GL_FALSE; + } + + make_empty_list(block); + + /* Insert at head or at tail??? + */ + insert_at_tail(&pool->lru, block); + + block->pool = pool; + block->virtual = pool->virtual + block->mem->ofs; + block->buf = buf; + + buf->block = block; + + return GL_TRUE; +} + + + + + + + + +/* Release the card storage associated with buf: + */ +static void free_block( struct intel_context *intel, struct block *block ) +{ + DBG("free block %p\n", block); + + if (!block) + return; + + check_fenced(intel); + + if (block->referenced) { + _mesa_printf("tried to free block on referenced list\n"); + assert(0); + } + else if (block->on_hardware) { + block->buf = NULL; + intel->bm->free_on_hardware += block->mem->size; + } + else if (block->fenced) { + block->buf = NULL; + } + else { + DBG(" - free immediately\n"); + remove_from_list(block); + + mmFreeMem(block->mem); + free(block); + } +} + + +static void alloc_backing_store( struct intel_context *intel, struct buffer *buf ) +{ + assert(!buf->backing_store); + assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); + + buf->backing_store = ALIGN_MALLOC(buf->size, 64); +} + +static void free_backing_store( struct intel_context *intel, struct buffer *buf ) +{ + assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); + + if (buf->backing_store) { + ALIGN_FREE(buf->backing_store); + buf->backing_store = NULL; + } +} + + + + + + +static void set_dirty( struct intel_context *intel, + struct buffer *buf ) +{ + if (buf->flags & BM_NO_BACKING_STORE) + buf->invalidate_cb(intel, buf->invalidate_ptr); + + assert(!(buf->flags & BM_NO_EVICT)); + + DBG("set_dirty - buf %d\n", buf->id); + buf->dirty = 1; +} + + +static int evict_lru( struct intel_context *intel, GLuint max_fence, GLuint *pool ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + int i; + + DBG("%s\n", __FUNCTION__); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s(block, tmp, &bm->pool[i].lru) { + + if (block->buf && + (block->buf->flags & BM_NO_FENCE_SUBDATA)) + continue; + + if (block->fence && max_fence && + !FENCE_LTE(block->fence, max_fence)) + return 0; + + set_dirty(intel, block->buf); + block->buf->block = NULL; + + free_block(intel, block); + *pool = i; + return 1; + } + } + } + + + return 0; +} + + +#define foreach_s_rev(ptr, t, list) \ + for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev) + +static int evict_mru( struct intel_context *intel, GLuint *pool ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + int i; + + DBG("%s\n", __FUNCTION__); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s_rev(block, tmp, &bm->pool[i].lru) { + + if (block->buf && + (block->buf->flags & BM_NO_FENCE_SUBDATA)) + continue; + + set_dirty(intel, block->buf); + block->buf->block = NULL; + + free_block(intel, block); + *pool = i; + return 1; + } + } + } + + + return 0; +} + + +static int check_fenced( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + int ret = 0; + + foreach_s(block, tmp, &bm->fenced ) { + assert(block->fenced); + + if (bmTestFence(intel, block->fence)) { + + block->fenced = 0; + + if (!block->buf) { + DBG("delayed free: offset %x sz %x\n", block->mem->ofs, block->mem->size); + remove_from_list(block); + mmFreeMem(block->mem); + free(block); + } + else { + DBG("return to lru: offset %x sz %x\n", block->mem->ofs, block->mem->size); + move_to_tail(&block->pool->lru, block); + } + + ret = 1; + } + else { + /* Blocks are ordered by fence, so if one fails, all from + * here will fail also: + */ + break; + } + } + + /* Also check the referenced list: + */ + foreach_s(block, tmp, &bm->referenced ) { + if (block->fenced && + bmTestFence(intel, block->fence)) { + block->fenced = 0; + } + } + + + DBG("%s: %d\n", __FUNCTION__, ret); + return ret; +} + + + +static void fence_blocks( struct intel_context *intel, + unsigned fence ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + + foreach_s (block, tmp, &bm->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->buf, fence); + block->fence = fence; + + block->on_hardware = 0; + block->fenced = 1; + + /* Move to tail of pending list here + */ + move_to_tail(&bm->fenced, block); + } + + /* Also check the referenced list: + */ + foreach_s (block, tmp, &bm->referenced) { + if (block->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->buf, fence); + + block->fence = fence; + block->on_hardware = 0; + block->fenced = 1; + } + } + + + bm->last_fence = fence; + assert(is_empty_list(&bm->on_hardware)); +} + + + + +static GLboolean alloc_block( struct intel_context *intel, + struct buffer *buf ) +{ + struct bufmgr *bm = intel->bm; + int i; + + assert(intel->locked); + + DBG("%s 0x%x bytes (%s)\n", __FUNCTION__, buf->size, buf->name); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_ALLOC) && + alloc_from_pool(intel, i, buf)) { + + DBG("%s --> 0x%x (sz %x)\n", __FUNCTION__, + buf->block->mem->ofs, buf->block->mem->size); + + return GL_TRUE; + } + } + + DBG("%s --> fail\n", __FUNCTION__); + return GL_FALSE; +} + + +static GLboolean evict_and_alloc_block( struct intel_context *intel, + struct buffer *buf ) +{ + GLuint pool; + struct bufmgr *bm = intel->bm; + + assert(buf->block == NULL); + + /* Put a cap on the amount of free memory we'll allow to accumulate + * before emitting a fence. + */ + if (bm->free_on_hardware > 1 * 1024 * 1024) { + DBG("fence for free space: %x\n", bm->free_on_hardware); + bmSetFence(intel); + } + + /* Search for already free memory: + */ + if (alloc_block(intel, buf)) + return GL_TRUE; + + /* Look for memory that may have become free: + */ + if (check_fenced(intel) && + alloc_block(intel, buf)) + return GL_TRUE; + + /* Look for memory blocks not used for >1 frame: + */ + while (evict_lru(intel, intel->second_last_swap_fence, &pool)) + if (alloc_from_pool(intel, pool, buf)) + return GL_TRUE; + + /* If we're not thrashing, allow lru eviction to dig deeper into + * recently used textures. We'll probably be thrashing soon: + */ + if (!intel->thrashing) { + while (evict_lru(intel, 0, &pool)) + if (alloc_from_pool(intel, pool, buf)) + return GL_TRUE; + } + + /* Keep thrashing counter alive? + */ + if (intel->thrashing) + intel->thrashing = 20; + + /* Wait on any already pending fences - here we are waiting for any + * freed memory that has been submitted to hardware and fenced to + * become available: + */ + while (!is_empty_list(&bm->fenced)) { + GLuint fence = bm->fenced.next->fence; + bmFinishFence(intel, fence); + + if (alloc_block(intel, buf)) + return GL_TRUE; + } + + + /* + */ + if (!is_empty_list(&bm->on_hardware)) { + bmSetFence(intel); + + while (!is_empty_list(&bm->fenced)) { + GLuint fence = bm->fenced.next->fence; + bmFinishFence(intel, fence); + } + + if (!intel->thrashing) { + DBG("thrashing\n"); + } + intel->thrashing = 20; + + if (alloc_block(intel, buf)) + return GL_TRUE; + } + + while (evict_mru(intel, &pool)) + if (alloc_from_pool(intel, pool, buf)) + return GL_TRUE; + + DBG("%s 0x%x bytes failed\n", __FUNCTION__, buf->size); + + assert(is_empty_list(&bm->on_hardware)); + assert(is_empty_list(&bm->fenced)); + + return GL_FALSE; +} + + + + + + + + + + +/*********************************************************************** + * Public functions + */ + + +/* The initialization functions are skewed in the fake implementation. + * This call would be to attach to an existing manager, rather than to + * create a local one. + */ +struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ) +{ + _glthread_DECLARE_STATIC_MUTEX(initMutex); + static struct bufmgr bm; + + /* This function needs a mutex of its own... + */ + _glthread_LOCK_MUTEX(initMutex); + + if (nr_attach == 0) { + _glthread_INIT_MUTEX(bm.mutex); + + 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++; + + _glthread_UNLOCK_MUTEX(initMutex); + + return &bm; +} + + + +/* The virtual pointer would go away in a true implementation. + */ +int bmInitPool( struct intel_context *intel, + unsigned long low_offset, + void *low_virtual, + unsigned long size, + unsigned flags) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + LOCK(bm); + { + GLuint i; + + for (i = 0; i < bm->nr_pools; i++) { + if (bm->pool[i].low_offset == low_offset && + bm->pool[i].size == size) { + retval = i; + goto out; + } + } + + + if (bm->nr_pools >= BM_POOL_MAX) + retval = -1; + else { + i = bm->nr_pools++; + + DBG("bmInitPool %d low_offset %x sz %x\n", + i, low_offset, size); + + bm->pool[i].low_offset = low_offset; + bm->pool[i].size = size; + bm->pool[i].heap = mmInit( low_offset, size ); + bm->pool[i].virtual = low_virtual - low_offset; + bm->pool[i].flags = flags; + + make_empty_list(&bm->pool[i].lru); + + retval = i; + } + } + out: + UNLOCK(bm); + return retval; +} + +static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name, int align) +{ + struct bufmgr *bm = intel->bm; + struct buffer *buf = calloc(sizeof(*buf), 1); + + buf->id = ++bm->buf_nr; + buf->name = name; + buf->alignment = align; + buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL; + + return buf; +} + + +void *bmFindVirtual( struct intel_context *intel, + unsigned int offset, + size_t sz ) +{ + struct bufmgr *bm = intel->bm; + int i; + + for (i = 0; i < bm->nr_pools; i++) + if (offset >= bm->pool[i].low_offset && + offset + sz <= bm->pool[i].low_offset + bm->pool[i].size) + return bm->pool[i].virtual + offset; + + return NULL; +} + + +void bmGenBuffers(struct intel_context *intel, + const char *name, unsigned n, + struct buffer **buffers, + int align ) +{ + struct bufmgr *bm = intel->bm; + LOCK(bm); + { + int i; + + for (i = 0; i < n; i++) + buffers[i] = do_GenBuffer(intel, name, align); + } + UNLOCK(bm); +} + + +void bmDeleteBuffers(struct intel_context *intel, unsigned n, struct buffer **buffers) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + unsigned i; + + for (i = 0; i < n; i++) { + struct buffer *buf = buffers[i]; + + if (buf && buf->block) + free_block(intel, buf->block); + + if (buf) + free(buf); + } + } + UNLOCK(bm); +} + + + + +/* Hook to inform faked buffer manager about fixed-position + * front,depth,back buffers. These may move to a fully memory-managed + * scheme, or they may continue to be managed as is. It will probably + * be useful to pass a fixed offset here one day. + */ +struct buffer *bmGenBufferStatic(struct intel_context *intel, + unsigned pool ) +{ + struct bufmgr *bm = intel->bm; + struct buffer *buf; + LOCK(bm); + { + assert(bm->pool[pool].flags & BM_NO_EVICT); + assert(bm->pool[pool].flags & BM_NO_MOVE); + + if (bm->pool[pool].static_buffer) + buf = bm->pool[pool].static_buffer; + else { + buf = do_GenBuffer(intel, "static", 12); + + bm->pool[pool].static_buffer = buf; + assert(!buf->block); + + buf->size = bm->pool[pool].size; + buf->flags = bm->pool[pool].flags; + buf->alignment = 12; + + if (!alloc_from_pool(intel, pool, buf)) + assert(0); + } + } + UNLOCK(bm); + return buf; +} + + +static void wait_quiescent(struct intel_context *intel, + struct block *block) +{ + if (block->on_hardware) { + assert(intel->bm->need_fence); + bmSetFence(intel); + assert(!block->on_hardware); + } + + + if (block->fenced) { + bmFinishFence(intel, block->fence); + } + + assert(!block->on_hardware); + assert(!block->fenced); +} + + + +/* If buffer size changes, free and reallocate. Otherwise update in + * place. + */ +int bmBufferData(struct intel_context *intel, + struct buffer *buf, + unsigned size, + const void *data, + unsigned flags ) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + LOCK(bm); + { + DBG("bmBufferData %d sz 0x%x data: %p\n", buf->id, size, data); + + assert(!buf->mapped); + + if (buf->block) { + struct block *block = buf->block; + + /* Optimistic check to see if we can reuse the block -- not + * required for correctness: + */ + if (block->fenced) + check_fenced(intel); + + if (block->on_hardware || + block->fenced || + (buf->size && buf->size != size) || + (data == NULL)) { + + assert(!block->referenced); + + free_block(intel, block); + buf->block = NULL; + buf->dirty = 1; + } + } + + buf->size = size; + if (buf->block) { + assert (buf->block->mem->size >= size); + } + + if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { + + assert(intel->locked || data == NULL); + + if (data != NULL) { + if (!buf->block && !evict_and_alloc_block(intel, buf)) { + bm->fail = 1; + retval = -1; + goto out; + } + + wait_quiescent(intel, buf->block); + + DBG("bmBufferData %d offset 0x%x sz 0x%x\n", + buf->id, buf->block->mem->ofs, size); + + assert(buf->block->virtual == buf->block->pool->virtual + buf->block->mem->ofs); + + do_memcpy(buf->block->virtual, data, size); + } + buf->dirty = 0; + } + else { + DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); + set_dirty(intel, buf); + free_backing_store(intel, buf); + + if (data != NULL) { + alloc_backing_store(intel, buf); + do_memcpy(buf->backing_store, data, size); + } + } + } + out: + UNLOCK(bm); + return retval; +} + + +/* Update the buffer in place, in whatever space it is currently resident: + */ +int bmBufferSubData(struct intel_context *intel, + struct buffer *buf, + unsigned offset, + unsigned size, + const void *data ) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + if (size == 0) + return 0; + + LOCK(bm); + { + DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); + + assert(offset+size <= buf->size); + + if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { + + assert(intel->locked); + + if (!buf->block && !evict_and_alloc_block(intel, buf)) { + bm->fail = 1; + retval = -1; + goto out; + } + + if (!(buf->flags & BM_NO_FENCE_SUBDATA)) + wait_quiescent(intel, buf->block); + + buf->dirty = 0; + + do_memcpy(buf->block->virtual + offset, data, size); + } + else { + DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); + set_dirty(intel, buf); + + if (buf->backing_store == NULL) + alloc_backing_store(intel, buf); + + do_memcpy(buf->backing_store + offset, data, size); + } + } + out: + UNLOCK(bm); + return retval; +} + +unsigned bmBufferOffset(struct intel_context *intel, + struct buffer *buf) +{ + struct bufmgr *bm = intel->bm; + unsigned retval = 0; + + LOCK(bm); + { + assert(intel->locked); + + if (!buf->block && + !evict_and_alloc_block(intel, buf)) { + bm->fail = 1; + retval = ~0; + } + else { + assert(buf->block); + assert(buf->block->buf == buf); + + DBG("Add buf %d (block %p, dirty %d) to referenced list\n", buf->id, buf->block, + buf->dirty); + + move_to_tail(&bm->referenced, buf->block); + buf->block->referenced = 1; + + retval = buf->block->mem->ofs; + } + } + UNLOCK(bm); + + return retval; +} + + + +/* Extract data from the buffer: + */ +void bmBufferGetSubData(struct intel_context *intel, + struct buffer *buf, + unsigned offset, + unsigned size, + void *data ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); + + if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { + if (buf->block && size) { + wait_quiescent(intel, buf->block); + do_memcpy(data, buf->block->virtual + offset, size); + } + } + else { + if (buf->backing_store && size) { + do_memcpy(data, buf->backing_store + offset, size); + } + } + } + UNLOCK(bm); +} + + +/* Return a pointer to whatever space the buffer is currently resident in: + */ +void *bmMapBuffer( struct intel_context *intel, + struct buffer *buf, + unsigned flags ) +{ + struct bufmgr *bm = intel->bm; + void *retval = NULL; + + LOCK(bm); + { + DBG("bmMapBuffer %d\n", buf->id); + + if (buf->mapped) { + _mesa_printf("%s: already mapped\n", __FUNCTION__); + retval = NULL; + } + else if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { + + assert(intel->locked); + + if (!buf->block && !evict_and_alloc_block(intel, buf)) { + DBG("%s: alloc failed\n", __FUNCTION__); + bm->fail = 1; + retval = NULL; + } + else { + assert(buf->block); + buf->dirty = 0; + + if (!(buf->flags & BM_NO_FENCE_SUBDATA)) + wait_quiescent(intel, buf->block); + + buf->mapped = 1; + retval = buf->block->virtual; + } + } + else { + DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); + set_dirty(intel, buf); + + if (buf->backing_store == 0) + alloc_backing_store(intel, buf); + + buf->mapped = 1; + retval = buf->backing_store; + } + } + UNLOCK(bm); + return retval; +} + +void bmUnmapBuffer( struct intel_context *intel, struct buffer *buf ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + DBG("bmUnmapBuffer %d\n", buf->id); + buf->mapped = 0; + } + UNLOCK(bm); +} + + + + +/* This is the big hack that turns on BM_NO_BACKING_STORE. Basically + * says that an external party will maintain the backing store, eg + * Mesa's local copy of texture data. + */ +void bmBufferSetInvalidateCB(struct intel_context *intel, + struct buffer *buf, + void (*invalidate_cb)( struct intel_context *, void *ptr ), + void *ptr, + GLboolean dont_fence_subdata) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + if (buf->backing_store) + free_backing_store(intel, buf); + + buf->flags |= BM_NO_BACKING_STORE; + + if (dont_fence_subdata) + buf->flags |= BM_NO_FENCE_SUBDATA; + + DBG("bmBufferSetInvalidateCB set buf %d dirty\n", buf->id); + buf->dirty = 1; + buf->invalidate_cb = invalidate_cb; + buf->invalidate_ptr = ptr; + + /* Note that it is invalid right from the start. Also note + * invalidate_cb is called with the bufmgr locked, so cannot + * itself make bufmgr calls. + */ + invalidate_cb( intel, ptr ); + } + UNLOCK(bm); +} + + + + + + + +/* This is only protected against thread interactions by the DRI lock + * and the policy of ensuring that all dma is flushed prior to + * releasing that lock. Otherwise you might have two threads building + * up a list of buffers to validate at once. + */ +int bmValidateBuffers( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + LOCK(bm); + { + DBG("%s fail %d\n", __FUNCTION__, bm->fail); + assert(intel->locked); + + if (!bm->fail) { + struct block *block, *tmp; + + foreach_s(block, tmp, &bm->referenced) { + struct buffer *buf = block->buf; + + DBG("Validate buf %d / block %p / dirty %d\n", buf->id, block, buf->dirty); + + /* Upload the buffer contents if necessary: + */ + if (buf->dirty) { + DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", buf->id, + buf->name, buf->size, block->mem->ofs); + + assert(!(buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT))); + + wait_quiescent(intel, buf->block); + + do_memcpy(buf->block->virtual, + buf->backing_store, + buf->size); + + buf->dirty = 0; + } + + block->referenced = 0; + block->on_hardware = 1; + move_to_tail(&bm->on_hardware, block); + } + + bm->need_fence = 1; + } + + retval = bm->fail ? -1 : 0; + } + UNLOCK(bm); + + + if (retval != 0) + DBG("%s failed\n", __FUNCTION__); + + return retval; +} + + + + +void bmReleaseBuffers( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + struct block *block, *tmp; + + foreach_s (block, tmp, &bm->referenced) { + + DBG("remove block %p from referenced list\n", block); + + if (block->on_hardware) { + /* Return to the on-hardware list. + */ + move_to_tail(&bm->on_hardware, block); + } + else if (block->fenced) { + struct block *s; + + /* Hmm - have to scan the fenced list to insert the + * buffers in order. This is O(nm), but rare and the + * numbers are low. + */ + foreach (s, &bm->fenced) { + if (FENCE_LTE(block->fence, s->fence)) + break; + } + + move_to_tail(s, block); + } + else { + /* Return to the lru list: + */ + move_to_tail(&block->pool->lru, block); + } + + block->referenced = 0; + } + } + UNLOCK(bm); +} + + +/* This functionality is used by the buffer manager, not really sure + * if we need to be exposing it in this way, probably libdrm will + * offer equivalent calls. + * + * For now they can stay, but will likely change/move before final: + */ +unsigned bmSetFence( struct intel_context *intel ) +{ + assert(intel->locked); + + /* Emit MI_FLUSH here: + */ + if (intel->bm->need_fence) { + + /* Emit a flush without using a batchbuffer. Can't rely on the + * batchbuffer at this level really. Would really prefer that + * the IRQ ioctly emitted the flush at the same time. + */ + GLuint dword[2]; + dword[0] = intel->vtbl.flush_cmd(); + dword[1] = 0; + intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword)); + + intel->bm->last_fence = intelEmitIrqLocked( intel ); + + fence_blocks(intel, intel->bm->last_fence); + + intel->vtbl.note_fence(intel, intel->bm->last_fence); + intel->bm->need_fence = 0; + + if (intel->thrashing) { + intel->thrashing--; + if (!intel->thrashing) + DBG("not thrashing\n"); + } + + intel->bm->free_on_hardware = 0; + } + + return intel->bm->last_fence; +} + +unsigned bmSetFenceLock( struct intel_context *intel ) +{ + unsigned last; + LOCK(intel->bm); + last = bmSetFence(intel); + UNLOCK(intel->bm); + return last; +} +unsigned bmLockAndFence( struct intel_context *intel ) +{ + if (intel->bm->need_fence) { + LOCK_HARDWARE(intel); + LOCK(intel->bm); + bmSetFence(intel); + UNLOCK(intel->bm); + UNLOCK_HARDWARE(intel); + } + + return intel->bm->last_fence; +} + + +void bmFinishFence( struct intel_context *intel, unsigned fence ) +{ + if (!bmTestFence(intel, fence)) { + DBG("...wait on fence %d\n", fence); + intelWaitIrq( intel, fence ); + } + assert(bmTestFence(intel, fence)); + check_fenced(intel); +} + +void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) +{ + LOCK(intel->bm); + bmFinishFence(intel, fence); + UNLOCK(intel->bm); +} + + +/* Specifically ignore texture memory sharing. + * -- just evict everything + * -- and wait for idle + */ +void bm_fake_NotifyContendedLockTake( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + struct block *block, *tmp; + GLuint i; + + assert(is_empty_list(&bm->referenced)); + + bm->need_fence = 1; + bm->fail = 0; + bmFinishFence(intel, bmSetFence(intel)); + + assert(is_empty_list(&bm->fenced)); + assert(is_empty_list(&bm->on_hardware)); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s(block, tmp, &bm->pool[i].lru) { + assert(bmTestFence(intel, block->fence)); + set_dirty(intel, block->buf); + } + } + } + } + UNLOCK(bm); +} + + + +void bmEvictAll( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + struct block *block, *tmp; + GLuint i; + + DBG("%s\n", __FUNCTION__); + + assert(is_empty_list(&bm->referenced)); + + bm->need_fence = 1; + bm->fail = 0; + bmFinishFence(intel, bmSetFence(intel)); + + assert(is_empty_list(&bm->fenced)); + assert(is_empty_list(&bm->on_hardware)); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s(block, tmp, &bm->pool[i].lru) { + assert(bmTestFence(intel, block->fence)); + set_dirty(intel, block->buf); + block->buf->block = NULL; + + free_block(intel, block); + } + } + } + } + UNLOCK(bm); +} + + +GLboolean bmError( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + GLboolean retval; + + LOCK(bm); + { + retval = bm->fail; + } + UNLOCK(bm); + + 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 e4557a3847..2aaa10e1c2 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -28,24 +28,13 @@ #include "imports.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" static void intel_batchbuffer_reset( struct intel_batchbuffer *batch ) { assert(batch->map == NULL); - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->offset = (unsigned long)batch->ptr; batch->offset = (batch->offset + 63) & ~63; batch->ptr = (unsigned char *) batch->offset; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index a824966d2e..25e0a65e99 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -29,7 +29,7 @@ #define INTEL_BATCHBUFFER_H #include "mtypes.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" struct intel_context; @@ -43,7 +43,7 @@ struct intel_context; struct intel_batchbuffer { struct intel_context *intel; - dri_bo *buffer; + struct buffer *buffer; GLuint flags; unsigned long offset; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 4502c551a7..f88cbb2328 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -41,7 +41,7 @@ #include "intel_regions.h" #include "intel_structs.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - dri_fence_wait(intel, intel->last_swap_fence); + bmFinishFenceLock(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -154,10 +154,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, } intel_batchbuffer_flush( intel->batch ); - - dri_fence_unreference(intel->second_last_swap_fence); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = dri_fence_reference(intel->bmbmSetFenceLock( intel ); + intel->last_swap_fence = bmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) @@ -180,7 +178,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -252,11 +250,11 @@ static GLuint translate_raster_op(GLenum logicop) void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - dri_bo *src_buffer, + struct buffer *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort src_x, GLshort src_y, @@ -530,7 +528,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index 45dd33db66..e361545c8f 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_ioctl.h" -dri_bo; +struct buffer; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); @@ -40,11 +40,11 @@ extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - dri_bo *src_buffer, + struct buffer *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort srcx, GLshort srcy, @@ -55,7 +55,7 @@ extern void intelEmitCopyBlit( struct intel_context *intel, extern void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -68,7 +68,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort dst_x, GLshort dst_y, diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c index 32c458987d..3349284f5d 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c @@ -32,7 +32,7 @@ #include "intel_context.h" #include "intel_buffer_objects.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" /** @@ -185,7 +185,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, return GL_TRUE; } -dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) +struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) { assert(intel_obj->Base.Name); assert(intel_obj->buffer); diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.h b/src/mesa/drivers/dri/i965/intel_buffer_objects.h index a80f448716..4b38803e57 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.h @@ -39,13 +39,13 @@ struct gl_buffer_object; */ struct intel_buffer_object { struct gl_buffer_object Base; - dri_bo *buffer; /* the low-level buffer manager's buffer handle */ + struct buffer *buffer; /* the low-level buffer manager's buffer handle */ }; /* Get the bm buffer associated with a GL bufferobject: */ -dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); +struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); /* Hook the bufferobject implementation into mesa: */ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 37c9fa3ec3..022819d582 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -58,7 +58,7 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "utils.h" #include "vblank.h" @@ -635,10 +635,10 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags ) /* As above, but don't evict the texture data on transitions * between contexts which all share a local buffer manager. */ - if (sarea->texAge != intel->hHWContext) { + if (sarea->texAge != my_bufmgr) { DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr); - sarea->texAge = intel->hHWContext; - dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + sarea->texAge = my_bufmgr; + bm_fake_NotifyContendedLockTake( intel ); } /* Drawable changed? @@ -668,6 +668,11 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; + if (bmError(intel)) { + bmEvictAll(intel); + intel->vtbl.lost_hardware( intel ); + } + /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -675,8 +680,16 @@ void LOCK_HARDWARE( struct intel_context *intel ) /* XXX: postpone, may not be needed: */ if (!intel_batchbuffer_map(intel->batch)) { - _mesa_printf("failure to map batchbuffer\n"); - assert(0); + bmEvictAll(intel); + intel->vtbl.lost_hardware( intel ); + + /* This could only fail if the batchbuffer was greater in size + * than the available texture memory: + */ + if (!intel_batchbuffer_map(intel->batch)) { + _mesa_printf("double failure to map batchbuffer\n"); + assert(0); + } } } diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 88d5983027..e7e736079f 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -41,7 +41,7 @@ #include "intel_blit.h" #include "intel_regions.h" #include "drm.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" static int intelWaitIdleLocked( struct intel_context *intel ) { diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 8db61267b5..0fb33e27f4 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -28,7 +28,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "enums.h" #include "imports.h" diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 9bf858cacb..b78eba898f 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -42,7 +42,7 @@ #include "intel_context.h" #include "intel_regions.h" #include "intel_blit.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "imports.h" /* XXX: Thread safety? @@ -51,7 +51,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi { DBG("%s\n", __FUNCTION__); if (!region->map_refcount++) { - region->map = dri_bo_map(region->buffer, GL_TRUE); + region->map = bmMapBuffer(intel, region->buffer, 0); if (!region->map) region->map_refcount--; } @@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel, { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - dri_bo_unmap(region->buffer); + bmUnmapBuffer(intel, region->buffer); region->map = NULL; } } @@ -84,8 +84,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel, region->height = height; /* needed? */ region->refcount = 1; - region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", - pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); + bmGenBuffers(intel, "tex", 1, ®ion->buffer, 6); + bmBufferData(intel, region->buffer, pitch * cpp * height, NULL, 0); return region; } @@ -108,7 +108,7 @@ void intel_region_release( struct intel_context *intel, if (--(*region)->refcount == 0) { assert((*region)->map_refcount == 0); - dri_bo_unreference((*region)->buffer); + bmDeleteBuffers(intel, 1, &(*region)->buffer); free(*region); } *region = NULL; diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index 8505d7eedc..d2235f1275 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -29,7 +29,7 @@ #define INTEL_REGIONS_H #include "mtypes.h" -#include "dri_bufmgr.h" /* for DBG! */ +#include "bufmgr.h" /* for DBG! */ struct intel_context; /* A layer on top of the bufmgr buffers that adds a few useful things: @@ -40,7 +40,7 @@ struct intel_context; * - Blitter commands for copying 2D regions between buffers. */ struct intel_region { - dri_bo *buffer; + struct buffer *buffer; GLuint refcount; GLuint cpp; GLuint pitch; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 06bf9214f0..5dac50df32 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -109,18 +109,12 @@ intelMapScreenRegions(__DRIscreenPrivate *sPriv) return GL_FALSE; } - if (intelScreen->tex.size != 0) { - intelScreen->ttm = GL_FALSE; - - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *)&intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - } else { - intelScreen->ttm = GL_TRUE; + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *)&intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; } if (0) @@ -169,32 +163,6 @@ intelUnmapScreenRegions(intelScreenPrivate *intelScreen) } } -/** Driver-specific fence emit implementation for the fake memory manager. */ -static unsigned int -intel_fence_emit(void *private) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; - unsigned int fence; - - /* XXX: Need to emit a flush, if we haven't already (at least with the - * current batchbuffer implementation, we have). - */ - - fence = intelEmitIrqLocked(intelScreen); - - return fence; -} - -/** Driver-specific fence wait implementation for the fake memory manager. */ -static int -intel_fence_wait(void *private, unsigned int cookie) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; - - intelWaitIrq(intelScreen, cookie); - - return 0; -} static void intelPrintDRIInfo(intelScreenPrivate *intelScreen, @@ -391,19 +359,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); } - - assert(!intelScreen->ttm); - intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, - intelScreen->tex.map, - intelScreen->tex.size, - intel_fence_emit, - intel_fence_wait, - intelScreen); - if (intelScreen->bufmgr == FALSE) { - fprintf(stderr, "Couldn't initialize buffer manager\n"); - return GL_FALSE; - } - + return GL_TRUE; } @@ -413,7 +369,6 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv) intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; intelUnmapScreenRegions(intelScreen); - dri_bufmgr_destroy(intelScreen->bufmgr); FREE(intelScreen); sPriv->private = NULL; } diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index bb004822c4..bf9a716082 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -80,13 +80,6 @@ typedef struct * Configuration cache with default values for all contexts */ driOptionCache optionCache; - - /** - * This value indicates that the kernel memory manager is being used - * instead of the fake client-side memory manager. - */ - GLboolean ttm; - dri_bufmgr *bufmgr; } intelScreenPrivate; diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c deleted file mode 100644 index fcb5cc3906..0000000000 --- a/src/mesa/drivers/dri/i965/intel_tex_layout.c +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * 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 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. - * - **************************************************************************/ - /* - * Authors: - * Keith Whitwell - * Michel Dänzer - */ - -#include "intel_mipmap_tree.h" -#include "intel_tex_layout.h" -#include "macros.h" - - -static int align(int value, int alignment) -{ - return (value + alignment - 1) & ~(alignment - 1); -} - -void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) -{ - GLint align_h = 2, align_w = 4; - GLuint level; - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - - mt->pitch = mt->width0; - - /* May need to adjust pitch to accomodate the placement of - * the 2nd mipmap. This occurs when the alignment - * constraints of mipmap placement push the right edge of the - * 2nd mipmap out past the width of its parent. - */ - if (mt->first_level != mt->last_level) { - GLuint mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); - - if (mip1_width > mt->width0) - mt->pitch = mip1_width; - } - - /* Pitch must be a whole number of dwords, even though we - * express it in texels. - */ - mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; - mt->total_height = 0; - - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { - GLuint img_height; - - intel_miptree_set_level_info(mt, level, 1, x, y, width, - height, 1); - - if (mt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align(height, align_h); - - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - mt->total_height = MAX2(mt->total_height, y + img_height); - - /* Layout_below: step right after second mipmap. - */ - if (level == mt->first_level + 1) { - x += align(width, align_w); - } - else { - y += img_height; - } - - width = minify(width); - height = minify(height); - } -} diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c new file mode 120000 index 0000000000..fe61b44194 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 0cfb32f76d..8c05e7cdab 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" /** * Compute which mipmap levels that really need to be sent to the hardware. diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c deleted file mode 100644 index 8ee48b5a68..0000000000 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - * - * 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 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 "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_decode.h" -#include "i915_debug.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->size = intel->intelScreen->maxBatchSize; - batch->ptr = batch->map; -} - -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->last_fence = NULL; - intel_batchbuffer_reset(batch); - - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - dri_fence_wait(batch->last_fence); - dri_fence_unreference(batch->last_fence); - batch->last_fence = NULL; - } - if (batch->map) { - dri_bo_unmap(batch->buf); - batch->map = NULL; - } - dri_bo_unreference(batch->buf); - batch->buf = NULL; - free(batch); -} - -static int -relocation_sort(const void *a_in, const void *b_in) { - const struct buffer_reloc *a = a_in, *b = b_in; - - return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; -} - - -/* TODO: Push this whole function into bufmgr. - */ -static void -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - GLuint *ptr; - GLuint i; - struct intel_context *intel = batch->intel; - dri_fence *fo; - GLboolean performed_rendering = GL_FALSE; - - assert(batch->buf->virtual != NULL); - ptr = batch->buf->virtual; - - /* Sort our relocation list in terms of referenced buffer pointer. - * This lets us uniquely validate the buffers with the sum of all the flags, - * while avoiding O(n^2) on number of relocations. - */ - qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), - relocation_sort); - - /* Perform the necessary validations of buffers, and enter the relocations - * in the batchbuffer. - */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - - if (r->validate_flags & DRM_BO_FLAG_WRITE) - performed_rendering = GL_TRUE; - - /* If this is the first time we've seen this buffer in the relocation - * list, figure out our flags and validate it. - */ - if (i == 0 || batch->reloc[i - 1].buf != r->buf) { - uint32_t validate_flags; - int j, ret; - - /* Accumulate the flags we need for validating this buffer. */ - validate_flags = r->validate_flags; - for (j = i + 1; j < batch->nr_relocs; j++) { - if (batch->reloc[j].buf != r->buf) - break; - validate_flags |= batch->reloc[j].validate_flags; - } - - /* Validate. If we fail, fence to clear the unfenced list and bail - * out. - */ - ret = dri_bo_validate(r->buf, validate_flags); - if (ret != 0) { - dri_bo_unmap(batch->buf); - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "batchbuffer failure fence", GL_TRUE); - dri_fence_unreference(fo); - goto done; - } - } - ptr[r->offset / 4] = r->buf->offset + r->delta; - dri_bo_unreference(r->buf); - } - - dri_bo_unmap(batch->buf); - batch->map = NULL; - batch->ptr = NULL; - - dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { - intel_batch_ioctl(batch->intel, - batch->buf->offset, - used, ignore_cliprects, allow_unlock); - } - - /* Associate a fence with the validated buffers, and note that we included - * a flush at the end. - */ - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "Batch fence", GL_TRUE); - - if (performed_rendering) { - dri_fence_unreference(batch->last_fence); - batch->last_fence = fo; - } else { - /* If we didn't validate any buffers for writing by the card, we don't - * need to track the fence for glFinish(). - */ - dri_fence_unreference(fo); - } - - if (intel->numClipRects == 0 && !ignore_cliprects) { - if (allow_unlock) { - /* If we are not doing any actual user-visible rendering, - * do a sched_yield to keep the app from pegging the cpu while - * achieving nothing. - */ - UNLOCK_HARDWARE(intel); - sched_yield(); - LOCK_HARDWARE(intel); - } - intel->vtbl.lost_hardware(intel); - } - -done: - if (INTEL_DEBUG & DEBUG_BATCH) { - dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); - dri_bo_unmap(batch->buf); - } -} - - -void -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - GLboolean was_locked = intel->locked; - - if (used == 0) - return; - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - intel_batchbuffer_flush(batch); - if (batch->last_fence != NULL) - dri_fence_wait(batch->last_fence); -} - - -/* This is the only way buffers get added to the validate list. - */ -GLboolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint delta) -{ - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - - assert(batch->nr_relocs <= MAX_RELOCS); - - dri_bo_reference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - r->validate_flags = flags; - - batch->ptr += 4; - return GL_TRUE; -} - - - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - __memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h deleted file mode 100644 index 850a91e1c9..0000000000 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "mtypes.h" -#include "dri_bufmgr.h" - -struct intel_context; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define MAX_RELOCS 4096 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct buffer_reloc -{ - dri_bo *buf; - GLuint offset; - GLuint delta; /* not needed? */ - GLuint validate_flags; -}; - -struct intel_batchbuffer -{ - struct intel_context *intel; - - dri_bo *buf; - dri_fence *last_fence; - GLuint flags; - - drmBOList list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - struct buffer_reloc reloc[MAX_RELOCS]; - GLuint nr_relocs; - GLuint size; -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -void intel_batchbuffer_flush(struct intel_batchbuffer *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint offset); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf, flags, delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ -} while (0) - -#define ADVANCE_BATCH() do { } while(0) - - -#endif -- cgit v1.2.3 From 35331a511fcd023a7b6f0eb298098d872b856a9f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Sep 2007 15:06:06 -0700 Subject: [965] Add batchbuffer dumping under INTEL_DEBUG=bat, like 915. --- src/mesa/drivers/dri/i915/Makefile | 1 + src/mesa/drivers/dri/i915/intel_batchbuffer.c | 3 +- src/mesa/drivers/dri/i915/intel_decode.c | 833 +----------------------- src/mesa/drivers/dri/i915/intel_decode.h | 29 - src/mesa/drivers/dri/i965/Makefile | 2 + src/mesa/drivers/dri/i965/intel_batchbuffer.c | 11 + src/mesa/drivers/dri/i965/intel_context.c | 2 + src/mesa/drivers/dri/i965/intel_context.h | 17 +- src/mesa/drivers/dri/i965/intel_decode.c | 1 + src/mesa/drivers/dri/intel/intel_chipset.h | 78 +++ src/mesa/drivers/dri/intel/intel_decode.c | 900 ++++++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_decode.h | 29 + 12 files changed, 1028 insertions(+), 878 deletions(-) mode change 100644 => 120000 src/mesa/drivers/dri/i915/intel_decode.c delete mode 100644 src/mesa/drivers/dri/i915/intel_decode.h create mode 120000 src/mesa/drivers/dri/i965/intel_decode.c create mode 100644 src/mesa/drivers/dri/intel/intel_chipset.h create mode 100644 src/mesa/drivers/dri/intel/intel_decode.c create mode 100644 src/mesa/drivers/dri/intel/intel_decode.h (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index d3d0bd570c..38e4090211 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -66,6 +66,7 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ include ../Makefile.template +intel_decode.o: ../intel/intel_decode.c intel_tex_layout.o: ../intel/intel_tex_layout.c symlinks: diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 8ee48b5a68..045ff0a5b0 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -240,7 +240,8 @@ do_flush_locked(struct intel_batchbuffer *batch, done: if (INTEL_DEBUG & DEBUG_BATCH) { dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); + intel_decode(ptr, used / 4, batch->buf->offset, + intel->intelScreen->deviceID); dri_bo_unmap(batch->buf); } } diff --git a/src/mesa/drivers/dri/i915/intel_decode.c b/src/mesa/drivers/dri/i915/intel_decode.c deleted file mode 100644 index bf3387b28e..0000000000 --- a/src/mesa/drivers/dri/i915/intel_decode.c +++ /dev/null @@ -1,832 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/* - * Copyright © 2007 Intel Corporation - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Authors: - * Eric Anholt - * - */ - -/** @file intel_decode.c - * This file contains code to print out batchbuffer contents in a - * human-readable format. - * - * The current version only supports i915 packets, and only pretty-prints a - * subset of them. The intention is for it to make just a best attempt to - * decode, but never crash in the process. - */ - -#include -#include -#include - -#include "intel_decode.h" -#include "i915_reg.h" - -#define BUFFER_FAIL(_count, _len, _name) do { \ - fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ - (_name), (_count), (_len)); \ - (*failures)++; \ - return count; \ -} while (0) - -static FILE *out; -static uint32_t saved_s2 = 0, saved_s4 = 0; -static char saved_s2_set = 0, saved_s4_set = 0; - -static float -int_as_float(uint32_t intval) -{ - union intfloat { - uint32_t i; - float f; - } uval; - - uval.i = intval; - return uval.f; -} - -static void -instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, - char *fmt, ...) -{ - va_list va; - - fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); - va_start(va, fmt); - vfprintf(out, fmt, va); - va_end(va); -} - - -static int -decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_mi[] = { - { 0x08, 1, 1, "MI_ARB_ON_OFF" }, - { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, - { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, - { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, - { 0x04, 1, 1, "MI_FLUSH" }, - { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, - { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, - { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, - { 0x00, 1, 1, "MI_NOOP" }, - { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, - { 0x07, 1, 1, "MI_REPORT_HEAD" }, - { 0x18, 2, 2, "MI_SET_CONTEXT" }, - { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, - { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, - { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, - { 0x02, 1, 1, "MI_USER_INTERRUPT" }, - { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, - }; - - - for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); - opcode++) { - if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { - unsigned int len = 1, i; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); - if (opcodes_mi[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; - if (len < opcodes_mi[opcode].min_len || - len > opcodes_mi[opcode].max_len) - { - fprintf(out, "Bad length in %s\n", - opcodes_mi[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_mi[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode, len; - char *format; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_2d[] = { - { 0x40, 5, 5, "COLOR_BLT" }, - { 0x43, 6, 6, "SRC_COPY_BLT" }, - { 0x01, 8, 8, "XY_SETUP_BLT" }, - { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, - { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, - { 0x24, 2, 2, "XY_PIXEL_BLT" }, - { 0x25, 3, 3, "XY_SCANLINES_BLT" }, - { 0x26, 4, 4, "Y_TEXT_BLT" }, - { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, - { 0x50, 6, 6, "XY_COLOR_BLT" }, - { 0x51, 6, 6, "XY_PAT_BLT" }, - { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, - { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, - { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, - { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, - { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, - { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, - { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, - { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, - { 0x55, 9, 9, "XY_FULL_BLT" }, - { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, - { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, - { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, - { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, - { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, - }; - - switch ((data[0] & 0x1fc00000) >> 22) { - case 0x50: - instr_out(data, hw_offset, 0, - "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", - (data[0] & (1 << 20)) ? "en" : "dis", - (data[0] & (1 << 21)) ? "en" : "dis"); - - len = (data[0] & 0x000000ff) + 2; - if (len != 6) - fprintf(out, "Bad count in XY_COLOR_BLT\n"); - if (count < 6) - BUFFER_FAIL(count, len, "XY_COLOR_BLT"); - - switch ((data[1] >> 24) & 0x3) { - case 0: - format="8"; - break; - case 1: - format="565"; - break; - case 2: - format="1555"; - break; - case 3: - format="8888"; - break; - } - - instr_out(data, hw_offset, 1, "format %s, pitch %d, " - "clipping %sabled\n", format, - data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); - instr_out(data, hw_offset, 2, "(%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 3, "(%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); - instr_out(data, hw_offset, 5, "color\n"); - return len; - case 0x53: - instr_out(data, hw_offset, 0, - "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", - (data[0] & (1 << 20)) ? "en" : "dis", - (data[0] & (1 << 21)) ? "en" : "dis"); - - len = (data[0] & 0x000000ff) + 2; - if (len != 8) - fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); - if (count < 8) - BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); - - switch ((data[1] >> 24) & 0x3) { - case 0: - format="8"; - break; - case 1: - format="565"; - break; - case 2: - format="1555"; - break; - case 3: - format="8888"; - break; - } - - instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " - "clipping %sabled\n", format, - data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); - instr_out(data, hw_offset, 2, "dst (%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 3, "dst (%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); - instr_out(data, hw_offset, 5, "src (%d,%d)\n", - data[5] & 0xffff, data[5] >> 16); - instr_out(data, hw_offset, 6, "src pitch %d\n", - data[6] & 0xffff); - instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); - return len; - } - - for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); - opcode++) { - if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { - unsigned int i; - - len = 1; - instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); - if (opcodes_2d[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; - if (len < opcodes_2d[opcode].min_len || - len > opcodes_2d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_2d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - switch ((data[0] & 0x00f80000) >> 19) { - case 0x11: - instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); - return 1; - case 0x10: - instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); - return 1; - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int len, i, c, opcode, word, map, sampler, instr; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_3d_1d[] = { - { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, - { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, - { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, - { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, - { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, - { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, - { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, - { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, - { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, - { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, - { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, - { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, - { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, - { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, - { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, - { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, - { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, - }; - - switch ((data[0] & 0x00ff0000) >> 16) { - case 0x07: - /* This instruction is unusual. A 0 length means just 1 DWORD instead of - * 2. The 0 length is specified in one place to be unsupported, but - * stated to be required in another, and 0 length LOAD_INDIRECTs appear - * to cause no harm at least. - */ - instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); - len = (data[0] & 0x000000ff) + 1; - i = 1; - if (data[0] & (0x01 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "SIS.0\n"); - instr_out(data, hw_offset, i++, "SIS.1\n"); - } - if (data[0] & (0x02 << 8)) { - if (i + 1 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "DIS.0\n"); - } - if (data[0] & (0x04 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "SSB.0\n"); - instr_out(data, hw_offset, i++, "SSB.1\n"); - } - if (data[0] & (0x08 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "MSB.0\n"); - instr_out(data, hw_offset, i++, "MSB.1\n"); - } - if (data[0] & (0x10 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "PSP.0\n"); - instr_out(data, hw_offset, i++, "PSP.1\n"); - } - if (data[0] & (0x20 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "PSC.0\n"); - instr_out(data, hw_offset, i++, "PSC.1\n"); - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); - (*failures)++; - return len; - } - return len; - case 0x04: - instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); - len = (data[0] & 0x0000000f) + 2; - i = 1; - for (word = 0; word <= 7; word++) { - if (data[0] & (1 << (4 + word))) { - if (i >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); - - /* save vertex state for decode */ - if (word == 2) { - saved_s2_set = 1; - saved_s2 = data[i]; - } - if (word == 4) { - saved_s4_set = 1; - saved_s4 = data[i]; - } - - instr_out(data, hw_offset, i++, "S%d\n", word); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); - (*failures)++; - } - return len; - case 0x00: - instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); - len = (data[0] & 0x0000003f) + 2; - - i = 1; - for (map = 0; map <= 15; map++) { - if (data[1] & (1 << map)) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); - instr_out(data, hw_offset, i++, "map %d MS2\n", map); - instr_out(data, hw_offset, i++, "map %d MS3\n", map); - instr_out(data, hw_offset, i++, "map %d MS4\n", map); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); - (*failures)++; - return len; - } - return len; - case 0x06: - instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); - len = (data[0] & 0x000000ff) + 2; - - i = 1; - for (c = 0; c <= 31; c++) { - if (data[1] & (1 << c)) { - if (i + 4 >= count) - BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); - instr_out(data, hw_offset, i, "C%d.X = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.Y = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.Z = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.W = %f\n", - c, int_as_float(data[i])); - i++; - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); - (*failures)++; - } - return len; - case 0x05: - instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); - len = (data[0] & 0x000000ff) + 2; - if ((len - 1) % 3 != 0 || len > 370) { - fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); - (*failures)++; - } - i = 1; - for (instr = 0; instr < (len - 1) / 3; instr++) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - } - return len; - case 0x01: - instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); - len = (data[0] & 0x0000003f) + 2; - i = 1; - for (sampler = 0; sampler <= 15; sampler++) { - if (data[1] & (1 << sampler)) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); - instr_out(data, hw_offset, i++, "sampler %d SS2\n", - sampler); - instr_out(data, hw_offset, i++, "sampler %d SS3\n", - sampler); - instr_out(data, hw_offset, i++, "sampler %d SS4\n", - sampler); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); - (*failures)++; - } - return len; - } - - for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); - opcode++) - { - if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { - len = 1; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); - if (opcodes_3d_1d[opcode].max_len > 1) { - len = (data[0] & 0x0000ffff) + 2; - if (len < opcodes_3d_1d[opcode].min_len || - len > opcodes_3d_1d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", - opcodes_3d_1d[opcode].name); - (*failures)++; - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, - int *failures) -{ - char immediate = (data[0] & (1 << 23)) == 0; - unsigned int len, i; - char *primtype; - - switch ((data[0] >> 18) & 0xf) { - case 0x0: primtype = "TRILIST"; break; - case 0x1: primtype = "TRISTRIP"; break; - case 0x2: primtype = "TRISTRIP_REVERSE"; break; - case 0x3: primtype = "TRIFAN"; break; - case 0x4: primtype = "POLYGON"; break; - case 0x5: primtype = "LINELIST"; break; - case 0x6: primtype = "LINESTRIP"; break; - case 0x7: primtype = "RECTLIST"; break; - case 0x8: primtype = "POINTLIST"; break; - case 0x9: primtype = "DIB"; break; - case 0xa: primtype = "CLEAR_RECT"; break; - default: primtype = "unknown"; break; - } - - /* XXX: 3DPRIM_DIB not supported */ - if (immediate) { - len = (data[0] & 0x0003ffff) + 2; - instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); - if (count < len) - BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); - if (!saved_s2_set || !saved_s4_set) { - fprintf(out, "unknown vertex format\n"); - for (i = 1; i < len; i++) { - instr_out(data, hw_offset, i, - " vertex data (%f float)\n", - int_as_float(data[i])); - } - } else { - unsigned int vertex = 0; - for (i = 1; i < len;) { - unsigned int tc; - -#define VERTEX_OUT(fmt, ...) do { \ - if (i < len) \ - instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ - else \ - fprintf(out, " missing data in V%d\n", vertex); \ - i++; \ -} while (0) - - VERTEX_OUT("X = %f", int_as_float(data[i])); - VERTEX_OUT("Y = %f", int_as_float(data[i])); - switch (saved_s4 >> 6 & 0x7) { - case 0x1: - VERTEX_OUT("Z = %f", int_as_float(data[i])); - break; - case 0x2: - VERTEX_OUT("Z = %f", int_as_float(data[i])); - VERTEX_OUT("W = %f", int_as_float(data[i])); - break; - case 0x3: - break; - case 0x4: - VERTEX_OUT("W = %f", int_as_float(data[i])); - break; - default: - fprintf(out, "bad S4 position mask\n"); - } - - if (saved_s4 & (1 << 10)) { - VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " - "B=0x%02x)", - data[i] >> 24, - (data[i] >> 16) & 0xff, - (data[i] >> 8) & 0xff, - data[i] & 0xff); - } - if (saved_s4 & (1 << 11)) { - VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " - "B=0x%02x)", - data[i] >> 24, - (data[i] >> 16) & 0xff, - (data[i] >> 8) & 0xff, - data[i] & 0xff); - } - if (saved_s4 & (1 << 12)) - VERTEX_OUT("width = 0x%08x)", data[i]); - - for (tc = 0; tc <= 7; tc++) { - switch ((saved_s2 >> (tc * 4)) & 0xf) { - case 0x0: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - break; - case 0x1: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); - break; - case 0x2: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); - break; - case 0x3: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - break; - case 0x4: - VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); - break; - case 0x5: - VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); - VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); - break; - case 0xf: - break; - default: - fprintf(out, "bad S2.T%d format\n", tc); - } - } - vertex++; - } - } - } else { - /* indirect vertices */ - len = data[0] & 0x0000ffff; /* index count */ - if (data[0] & (1 << 17)) { - /* random vertex access */ - if (count < (len + 1) / 2 + 1) { - BUFFER_FAIL(count, (len + 1) / 2 + 1, - "3DPRIMITIVE random indirect"); - } - instr_out(data, hw_offset, 0, - "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); - if (len == 0) { - /* vertex indices continue until 0xffff is found */ - for (i = 1; i < count; i++) { - if ((data[i] & 0xffff) == 0xffff) { - instr_out(data, hw_offset, i, - " indices: (terminator)\n"); - return i; - } else if ((data[i] >> 16) == 0xffff) { - instr_out(data, hw_offset, i, - " indices: 0x%04x, " - "(terminator)\n", - data[i] & 0xffff); - return i; - } else { - instr_out(data, hw_offset, i, - " indices: 0x%04x, 0x%04x\n", - data[i] & 0xffff, data[i] >> 16); - } - } - fprintf(out, - "3DPRIMITIVE: no terminator found in index buffer\n"); - (*failures)++; - return count; - } else { - /* fixed size vertex index buffer */ - for (i = 0; i < len; i += 2) { - if (i * 2 == len - 1) { - instr_out(data, hw_offset, i, - " indices: 0x%04x\n", - data[i] & 0xffff); - } else { - instr_out(data, hw_offset, i, - " indices: 0x%04x, 0x%04x\n", - data[i] & 0xffff, data[i] >> 16); - } - } - } - return (len + 1) / 2 + 1; - } else { - /* sequential vertex access */ - if (count < 2) - BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); - instr_out(data, hw_offset, 0, - "3DPRIMITIVE sequential indirect %s, %d starting from " - "%d\n", primtype, len, data[1] & 0xffff); - instr_out(data, hw_offset, 1, " start\n"); - return 2; - } - } - - return len; -} - -static int -decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_3d[] = { - { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, - { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, - { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, - { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, - { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, - { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, - { 0x0d, 1, 1, "3DSTATE_MODES_4" }, - { 0x0c, 1, 1, "3DSTATE_MODES_5" }, - { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, - }; - - switch ((data[0] & 0x1f000000) >> 24) { - case 0x1f: - return decode_3d_primitive(data, count, hw_offset, failures); - case 0x1d: - return decode_3d_1d(data, count, hw_offset, failures); - case 0x1c: - return decode_3d_1c(data, count, hw_offset, failures); - } - - for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); - opcode++) { - if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { - unsigned int len = 1, i; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); - if (opcodes_3d[opcode].max_len > 1) { - len = (data[0] & 0xff) + 2; - if (len < opcodes_3d[opcode].min_len || - len > opcodes_3d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_3d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - return len; - } - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -/** - * Decodes an i830-i915 batch buffer, writing the output to stdout. - * - * \param data batch buffer contents - * \param count number of DWORDs to decode in the batch buffer - * \param hw_offset hardware address for the buffer - */ -int -intel_decode(uint32_t *data, int count, uint32_t hw_offset) -{ - int index = 0; - int failures = 0; - - out = stdout; - - while (index < count) { - switch ((data[index] & 0xe0000000) >> 29) { - case 0x0: - index += decode_mi(data + index, count - index, - hw_offset + index * 4, &failures); - break; - case 0x2: - index += decode_2d(data + index, count - index, - hw_offset + index * 4, &failures); - break; - case 0x3: - index += decode_3d(data + index, count - index, - hw_offset + index * 4, &failures); - break; - default: - instr_out(data, hw_offset, index, "UNKNOWN\n"); - failures++; - index++; - break; - } - fflush(out); - } - - return failures; -} - -void intel_decode_context_reset() -{ - saved_s2_set = 0; - saved_s4_set = 1; -} - diff --git a/src/mesa/drivers/dri/i915/intel_decode.c b/src/mesa/drivers/dri/i915/intel_decode.c new file mode 120000 index 0000000000..f671b6cbb1 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_decode.c @@ -0,0 +1 @@ +../intel/intel_decode.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i915/intel_decode.h b/src/mesa/drivers/dri/i915/intel_decode.h deleted file mode 100644 index ef0cba153c..0000000000 --- a/src/mesa/drivers/dri/i915/intel_decode.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2007 Intel Corporation - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Authors: - * Eric Anholt - * - */ - -int intel_decode(uint32_t *data, int count, uint32_t hw_offset); -void intel_decode_context_reset(); diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 5748d7ff05..7e07bc9c1a 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -11,6 +11,7 @@ DRIVER_SOURCES = \ intel_buffer_objects.c \ intel_buffers.c \ intel_context.c \ + intel_decode.c \ intel_ioctl.c \ intel_mipmap_tree.c \ intel_regions.c \ @@ -92,6 +93,7 @@ DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_decode.o: ../intel/intel_decode.c intel_tex_layout.o: ../intel/intel_tex_layout.c server: diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 2aaa10e1c2..fb58c0e708 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -28,6 +28,7 @@ #include "imports.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "intel_decode.h" #include "bufmgr.h" @@ -168,6 +169,16 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) goto out; } + if (INTEL_DEBUG & DEBUG_BATCH) { + char *map; + + map = bmMapBuffer(batch->intel, batch->buffer, + BM_MEM_AGP|BM_MEM_LOCAL|BM_CLIENT); + intel_decode((uint32_t *)(map + batch->offset), used / 4, + offset + batch->offset, intel->intelScreen->deviceID); + bmUnmapBuffer(batch->intel, batch->buffer); + } + /* Fire the batch buffer, which was uploaded above: */ intel_batch_ioctl(batch->intel, diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 022819d582..2cf311c713 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -46,6 +46,7 @@ #include "drivers/common/driverfuncs.h" #include "intel_screen.h" +#include "intel_chipset.h" #include "i830_dri.h" #include "i830_common.h" @@ -225,6 +226,7 @@ static const struct dri_debug_control debug_control[] = { "thre", DEBUG_SINGLE_THREAD }, { "wm", DEBUG_WM }, { "vs", DEBUG_VS }, + { "bat", DEBUG_BATCH }, { NULL, 0 } }; diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 06cfc6946d..f63c2f613d 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -355,22 +355,7 @@ extern int INTEL_DEBUG; #define DEBUG_WM 0x10000 #define DEBUG_URB 0x20000 #define DEBUG_VS 0x40000 - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I965_G 0x29A2 -#define PCI_CHIP_I965_Q 0x2992 -#define PCI_CHIP_I965_G_1 0x2982 -#define PCI_CHIP_I946_GZ 0x2972 -#define PCI_CHIP_I965_GM 0x2A02 -#define PCI_CHIP_I965_GME 0x2A12 - +#define DEBUG_BATCH 0x80000 /* ================================================================ * intel_context.c: diff --git a/src/mesa/drivers/dri/i965/intel_decode.c b/src/mesa/drivers/dri/i965/intel_decode.c new file mode 120000 index 0000000000..f671b6cbb1 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_decode.c @@ -0,0 +1 @@ +../intel/intel_decode.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h new file mode 100644 index 0000000000..a18ca5be08 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_chipset.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Eric Anholt + * + */ + +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 + +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 + +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE + +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q33_G 0x29D2 + +#define PCI_CHIP_I965_G 0x29A2 +#define PCI_CHIP_I965_Q 0x2992 +#define PCI_CHIP_I965_G_1 0x2982 +#define PCI_CHIP_I946_GZ 0x2972 +#define PCI_CHIP_I965_GM 0x2A02 +#define PCI_CHIP_I965_GME 0x2A12 + +#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \ + devid == PCI_CHIP_I915_GM || \ + devid == PCI_CHIP_I945_GM || \ + devid == PCI_CHIP_I945_GME || \ + devid == PCI_CHIP_I965_GM || \ + devid == PCI_CHIP_I965_GME) + +#define IS_965(devid) (devid = PCI_CHIP_I965_G || \ + devid == PCI_CHIP_I965_Q || \ + devid == PCI_CHIP_I965_G_1 || \ + devid == PCI_CHIP_I965_GM || \ + devid == PCI_CHIP_I965_GME || \ + devid == PCI_CHIP_I946_GZ) + +#define IS_9XX(devid) (devid == PCI_CHIP_I915G || \ + devid == PCI_CHIP_I915GM || \ + devid == PCI_CHIP_I945G || \ + devid == PCI_CHIP_I945GM || \ + devid == PCI_CHIP_I945GME || \ + devid == PCI_CHIP_G33_G || \ + devid == PCI_CHIP_Q35_G || \ + devid == PCI_CHIP_Q33_G || \ + IS_965(devid)) + diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c new file mode 100644 index 0000000000..16881f297d --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -0,0 +1,900 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2007 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Eric Anholt + * + */ + +/** @file intel_decode.c + * This file contains code to print out batchbuffer contents in a + * human-readable format. + * + * The current version only supports i915 packets, and only pretty-prints a + * subset of them. The intention is for it to make just a best attempt to + * decode, but never crash in the process. + */ + +#include +#include +#include + +#include "intel_decode.h" +#include "intel_chipset.h" + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 1, 1, "MI_FLUSH" }, + { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 1, 1, "MI_NOOP" }, + { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length in %s\n", + opcodes_mi[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode, len; + char *format = NULL; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + data[6] & 0xffff); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int i; + + len = 1; + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + + i = 1; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 1; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + } + return len; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + i = 1; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x6000, 3, 3, "URB_FENCE" }, + { 0x6001, 2, 2, "CS_URB_STATE" }, + { 0x6002, 2, 2, "CONSTANT_BUFFER" }, + { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, + { 0x6102, 2, 2 , "STATE_SIP" }, + { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, + { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, + { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, + { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, + { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, + { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, + /* 0x7808: 3DSTATE_VERTEX_BUFFERS */ + /* 0x7809: 3DSTATE_VERTEX_ELEMENTS */ + { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, + { 0x7905, 5, 5, "3DSTATE_DEPTH_BUFFER" }, + { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, + { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, + { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, + { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, + { 0x7b00, 6, 6, "3DPRIMITIVE" }, + }; + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid) +{ + int index = 0; + int failures = 0; + + out = stdout; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + if (IS_965(devid)) { + index += decode_3d_965(data + index, count - index, + hw_offset + index * 4, &failures); + } else { + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + } + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} + +void intel_decode_context_reset(void) +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/mesa/drivers/dri/intel/intel_decode.h b/src/mesa/drivers/dri/intel/intel_decode.h new file mode 100644 index 0000000000..c50644a46b --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_decode.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Eric Anholt + * + */ + +int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid); +void intel_decode_context_reset(void); -- cgit v1.2.3