From 96b4a67d038167d3bc4fca9f77afc0fd92280a2c Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Sep 29 2006 19:07:15 +0000 Subject: - Add -fno-strict-aliasing to compiler flags for i965 driver. - Add post-6.5.1-i965-fixes.patch backport of i965 fixes from mesa CVS. --- diff --git a/mesa.spec b/mesa.spec index 8b4478b..b0c1c55 100644 --- a/mesa.spec +++ b/mesa.spec @@ -45,7 +45,7 @@ Summary: Mesa graphics libraries Name: mesa Version: 6.5.1 -Release: 5%{?dist} +Release: 6%{?dist} License: MIT/X11 Group: System Environment/Libraries URL: http://www.mesa3d.org @@ -66,6 +66,7 @@ Patch4: mesa-6.5-dont-libglut-me-harder-ok-thx-bye.patch Patch18: mesa-6.5.1-selinux-awareness.patch # General patches from upstream go here: +Patch50: post-6.5.1-i965-fixes.patch BuildRequires: pkgconfig %if %{with_dri} @@ -244,6 +245,7 @@ install -m 755 %{SOURCE12} ./ %patch0 -p1 -b .build-config %patch4 -p0 -b .dont-libglut-me-harder-ok-thx-bye %patch18 -p1 -b .selinux-awareness +%patch50 -p1 -b .post-6.5.1-i965-fixes # WARNING: The following files are copyright "Mark J. Kilgard" under the GLUT # license and are not open source/free software, so we remove them. @@ -251,7 +253,11 @@ rm -f include/GL/uglglutshapes.h #-- Build ------------------------------------------------------------ %build -export OPT_FLAGS="$RPM_OPT_FLAGS" + +# The i965 DRI driver breaks if compiled with -O2. It appears to be +# an aliasing problem, so we add -fno-strict-aliasing to the flags. + +export OPT_FLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" export DRI_DRIVER_DIR="%{_libdir}/dri" export LIB_DIR=%{_lib} @@ -407,6 +413,10 @@ rm -rf $RPM_BUILD_ROOT %{_bindir}/glxinfo %changelog +* Fri Sep 29 2006 Kristian - 6.5.1-6.fc6 +- Add -fno-strict-aliasing to compiler flags for i965 driver. +- Add post-6.5.1-i965-fixes.patch backport of i965 fixes from mesa CVS. + * Fri Sep 29 2006 Soren Sandmann - 6.5.1-5.fc6 - Give the correct path for man page file lists. diff --git a/post-6.5.1-i965-fixes.patch b/post-6.5.1-i965-fixes.patch new file mode 100644 index 0000000..a3d68fc --- /dev/null +++ b/post-6.5.1-i965-fixes.patch @@ -0,0 +1,1061 @@ +diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile +index e4fb451..dfa9318 100644 +--- a/src/mesa/drivers/dri/i965/Makefile ++++ b/src/mesa/drivers/dri/i965/Makefile +@@ -16,6 +16,7 @@ DRIVER_SOURCES = \ + intel_regions.c \ + intel_screen.c \ + intel_span.c \ ++ intel_pixel_copy.c \ + intel_state.c \ + intel_tex.c \ + intel_tex_validate.c \ +diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c +index f12fb4c..e476b18 100644 +--- a/src/mesa/drivers/dri/i965/brw_draw.c ++++ b/src/mesa/drivers/dri/i965/brw_draw.c +@@ -328,6 +328,7 @@ static GLboolean brw_try_draw_prims( GLc + brw_emit_prim(brw, &prim[i]); + } + ++ intel->need_flush = GL_TRUE; + retval = GL_TRUE; + } + +@@ -400,7 +401,7 @@ GLboolean brw_draw_prims( GLcontext *ctx + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + } + +- if (intel->aub_file) { ++ if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { + intelFinish( &intel->ctx ); + intel->aub_wrap = 1; + } +diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c +index ca012db..470fa6f 100644 +--- a/src/mesa/drivers/dri/i965/brw_exec_api.c ++++ b/src/mesa/drivers/dri/i965/brw_exec_api.c +@@ -394,7 +394,7 @@ static void GLAPIENTRY brw_exec_EvalCoor + + for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { + if (exec->eval.map1[i].map) +- if (exec->vtx.attrsz[i] != exec->eval.map1[i].sz) ++ if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) + brw_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); + } + } +diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c +index d70b2ea..8332d86 100644 +--- a/src/mesa/drivers/dri/i965/brw_tex.c ++++ b/src/mesa/drivers/dri/i965/brw_tex.c +@@ -49,34 +49,57 @@ #include "brw_defines.h" + + static const struct gl_texture_format * + brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, +- GLenum format, GLenum type ) ++ GLenum srcFormat, GLenum srcType ) + { + switch ( internalFormat ) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: ++ if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) ++ return &_mesa_texformat_argb4444; ++ else if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) ++ return &_mesa_texformat_argb1555; ++ else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || ++ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) || ++ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8)) ++ return &_mesa_texformat_rgba8888_rev; ++ else ++ return &_mesa_texformat_argb8888; ++ + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: +- case GL_RGBA4: +- case GL_RGBA2: +- case GL_RGB5_A1: + return &_mesa_texformat_argb8888; +-/* return &_mesa_texformat_rgba8888_rev; */ + +- case 3: +- case GL_RGB: +- case GL_COMPRESSED_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: ++ /* Broadwater doesn't support RGB888 textures, so these must be ++ * stored as ARGB. ++ */ ++ return &_mesa_texformat_argb8888; ++ ++ case 3: ++ case GL_COMPRESSED_RGB: ++ case GL_RGB: ++ if (srcFormat == GL_RGB && ++ srcType == GL_UNSIGNED_SHORT_5_6_5) ++ return &_mesa_texformat_rgb565; ++ else ++ return &_mesa_texformat_argb8888; ++ ++ + case GL_RGB5: +- case GL_RGB4: ++ case GL_RGB5_A1: ++ return &_mesa_texformat_argb1555; ++ + case GL_R3_G3_B2: +-/* return &_mesa_texformat_rgb888; */ +- return &_mesa_texformat_argb8888; ++ case GL_RGBA2: ++ case GL_RGBA4: ++ case GL_RGB4: ++ return &_mesa_texformat_argb4444; + + case GL_ALPHA: + case GL_ALPHA4: +@@ -115,8 +138,8 @@ brwChooseTextureFormat( GLcontext *ctx, + return &_mesa_texformat_i8; + + case GL_YCBCR_MESA: +- if (type == GL_UNSIGNED_SHORT_8_8_MESA || +- type == GL_UNSIGNED_BYTE) ++ if (srcType == GL_UNSIGNED_SHORT_8_8_MESA || ++ srcType == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; +diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c +index f8aa068..1353325 100644 +--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c ++++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c +@@ -138,13 +138,16 @@ GLboolean brw_miptree_layout( struct int + + /* Layout_below: step right after second mipmap. + */ +- if (level == mt->first_level + 1) ++ if (level == mt->first_level + 1) { + x += mt->pitch / 2; ++ x = (x + 3) & ~ 3; ++ } + else { + y += img_height; ++ y += align_h - 1; ++ y &= ~(align_h - 1); + } + +- + width = minify(width); + height = minify(height); + } +diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c +index 5957b71..9d12c26 100644 +--- a/src/mesa/drivers/dri/i965/brw_util.c ++++ b/src/mesa/drivers/dri/i965/brw_util.c +@@ -98,6 +98,8 @@ static GLuint brw_parameter_state_flags( + switch (state[1]) { + case STATE_NORMAL_SCALE: + return _NEW_MODELVIEW; ++ case STATE_TEXRECT_SCALE: ++ return _NEW_TEXTURE; + default: + assert(0); + return 0; +diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h +index 74c3bbe..ec6ad61 100644 +--- a/src/mesa/drivers/dri/i965/brw_wm.h ++++ b/src/mesa/drivers/dri/i965/brw_wm.h +@@ -167,6 +167,7 @@ #define WM_PINTERP (MAX_OPCODE + + #define WM_CINTERP (MAX_OPCODE + 5) + #define WM_WPOSXY (MAX_OPCODE + 6) + #define WM_FB_WRITE (MAX_OPCODE + 7) ++#define MAX_WM_OPCODE (MAX_OPCODE + 8) + + #define PROGRAM_PAYLOAD (PROGRAM_FILE_MAX) + #define PAYLOAD_DEPTH (FRAG_ATTRIB_MAX) +diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c +index 203eeea..8bf5579 100644 +--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c ++++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c +@@ -520,6 +520,35 @@ static void precalc_lit( struct brw_wm_c + static void precalc_tex( struct brw_wm_compile *c, + const struct prog_instruction *inst ) + { ++ struct prog_src_register coord; ++ struct prog_dst_register tmpcoord; ++ ++ if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { ++ struct prog_src_register scale = ++ search_or_add_param6( c, ++ STATE_INTERNAL, ++ STATE_TEXRECT_SCALE, ++ inst->TexSrcUnit, ++ 0,0,0 ); ++ ++ tmpcoord = get_temp(c); ++ ++ /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height } ++ */ ++ emit_op(c, ++ OPCODE_MUL, ++ tmpcoord, ++ 0, 0, 0, ++ inst->SrcReg[0], ++ scale, ++ src_undef()); ++ ++ coord = src_reg_from_dst(tmpcoord); ++ } ++ else { ++ coord = inst->SrcReg[0]; ++ } ++ + /* Need to emit YUV texture conversions by hand. Probably need to + * do this here - the alternative is in brw_wm_emit.c, but the + * conversion requires allocating a temporary variable which we +@@ -532,7 +561,7 @@ static void precalc_tex( struct brw_wm_c + inst->SaturateMode, + inst->TexSrcUnit, + inst->TexSrcTarget, +- inst->SrcReg[0], ++ coord, + src_undef(), + src_undef()); + } +@@ -604,7 +633,12 @@ static void precalc_tex( struct brw_wm_c + src_swizzle1(tmpsrc, Z), + src_swizzle1(C1, W), + src_swizzle1(src_reg_from_dst(dst), Y)); ++ ++ release_temp(c, tmp); + } ++ ++ if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV) ++ release_temp(c, tmpcoord); + } + + +@@ -769,6 +803,27 @@ static void validate_src_regs( struct br + + + ++static void print_insns( const struct prog_instruction *insn, ++ GLuint nr ) ++{ ++ GLuint i; ++ for (i = 0; i < nr; i++, insn++) { ++ _mesa_printf("%3d: ", i); ++ if (insn->Opcode < MAX_OPCODE) ++ _mesa_print_instruction(insn); ++ else if (insn->Opcode < MAX_WM_OPCODE) { ++ GLuint idx = insn->Opcode - MAX_OPCODE; ++ ++ _mesa_print_alu_instruction(insn, ++ wm_opcode_strings[idx], ++ 3); ++ } ++ else ++ _mesa_printf("UNKNOWN\n"); ++ ++ } ++} ++ + void brw_wm_pass_fp( struct brw_wm_compile *c ) + { + struct brw_fragment_program *fp = c->fp; +@@ -867,7 +922,7 @@ void brw_wm_pass_fp( struct brw_wm_compi + + if (INTEL_DEBUG & DEBUG_WM) { + _mesa_printf("\n\n\npass_fp:\n"); +-/* _mesa_debug_fp_inst(c->nr_fp_insns, c->prog_instructions, wm_opcode_strings, wm_file_strings); */ ++ print_insns( c->prog_instructions, c->nr_fp_insns ); + _mesa_printf("\n"); + } + } +diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +index 6ccf56e..5c7dc50 100644 +--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c ++++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +@@ -85,7 +85,8 @@ static GLuint translate_tex_format( GLui + return BRW_SURFACEFORMAT_L8A8_UNORM; + + case MESA_FORMAT_RGB888: +- return BRW_SURFACEFORMAT_R8G8B8_UNORM; ++ assert(0); /* not supported for sampling */ ++ return BRW_SURFACEFORMAT_R8G8B8_UNORM; + + case MESA_FORMAT_ARGB8888: + return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; +@@ -93,6 +94,15 @@ static GLuint translate_tex_format( GLui + case MESA_FORMAT_RGBA8888_REV: + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; + ++ case MESA_FORMAT_RGB565: ++ return BRW_SURFACEFORMAT_B5G6R5_UNORM; ++ ++ case MESA_FORMAT_ARGB1555: ++ return BRW_SURFACEFORMAT_B5G5R5A1_UNORM; ++ ++ case MESA_FORMAT_ARGB4444: ++ return BRW_SURFACEFORMAT_B4G4R4A4_UNORM; ++ + case MESA_FORMAT_YCBCR_REV: + return BRW_SURFACEFORMAT_YCRCB_NORMAL; + +diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h +index 83a810c..6932522 100644 +--- a/src/mesa/drivers/dri/i965/bufmgr.h ++++ b/src/mesa/drivers/dri/i965/bufmgr.h +@@ -182,6 +182,8 @@ void bmUnmapBufferAUB( struct intel_cont + int bmValidateBuffers( struct intel_context * ); + void bmReleaseBuffers( struct intel_context * ); + ++GLuint bmCtxId( struct intel_context *intel ); ++ + + GLboolean bmError( struct intel_context * ); + void bmEvictAll( struct intel_context * ); +diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c +index 8f182f3..30a235a 100644 +--- a/src/mesa/drivers/dri/i965/bufmgr_fake.c ++++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c +@@ -117,6 +117,7 @@ struct bufmgr { + struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ + /* then to pool->lru or free() */ + ++ unsigned ctxId; + unsigned last_fence; + unsigned free_on_hardware; + +@@ -578,6 +579,12 @@ struct bufmgr *bm_fake_intel_Attach( str + make_empty_list(&bm.referenced); + make_empty_list(&bm.fenced); + make_empty_list(&bm.on_hardware); ++ ++ /* The context id of any of the share group. This won't be used ++ * in communication with the kernel, so it doesn't matter if ++ * this context is eventually deleted. ++ */ ++ bm.ctxId = intel->hHWContext; + } + + nr_attach++; +@@ -1242,7 +1249,6 @@ void bmReleaseBuffers( struct intel_cont + LOCK(bm); + { + struct block *block, *tmp; +- assert(intel->locked); + + foreach_s (block, tmp, &bm->referenced) { + +@@ -1432,3 +1438,9 @@ GLboolean bmError( struct intel_context + + return retval; + } ++ ++ ++GLuint bmCtxId( struct intel_context *intel ) ++{ ++ return intel->bm->ctxId; ++} +diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c +index 2191dd5..b09b0a9 100644 +--- a/src/mesa/drivers/dri/i965/intel_blit.c ++++ b/src/mesa/drivers/dri/i965/intel_blit.c +@@ -74,9 +74,6 @@ void intelCopyBuffer( const __DRIdrawabl + + if (!rect) + { +- /* This is a really crappy way to do wait-for-vblank. I guess +- * it sortof works in the single-application case. +- */ + UNLOCK_HARDWARE( intel ); + driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target ); + LOCK_HARDWARE( intel ); +@@ -291,8 +288,12 @@ void intelEmitCopyBlit( struct intel_con + + /* Initial y values don't seem to work with negative pitches. If + * we adjust the offsets manually (below), it seems to work fine. ++ * ++ * On the other hand, if we always adjust, the hardware doesn't ++ * know which blit directions to use, so overlapping copypixels get ++ * the wrong result. + */ +- if (0) { ++ if (dst_pitch > 0 && src_pitch > 0) { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH( CMD ); + OUT_BATCH( dst_pitch | BR13 ); +diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c +index 59fc807..5f19137 100644 +--- a/src/mesa/drivers/dri/i965/intel_context.c ++++ b/src/mesa/drivers/dri/i965/intel_context.c +@@ -149,6 +149,10 @@ const struct dri_extension card_extensio + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_dot3", NULL }, + { "GL_ARB_texture_mirrored_repeat", NULL }, ++ { "GL_ARB_texture_non_power_of_two", NULL }, ++ { "GL_ARB_texture_rectangle", NULL }, ++ { "GL_NV_texture_rectangle", NULL }, ++ { "GL_EXT_texture_rectangle", NULL }, + { "GL_ARB_texture_rectangle", NULL }, + { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, + { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, +@@ -255,10 +259,14 @@ void intelInitDriverFunctions( struct dd + */ + functions->Accum = _swrast_Accum; + functions->Bitmap = _swrast_Bitmap; +- functions->CopyPixels = _swrast_CopyPixels; + functions->ReadPixels = _swrast_ReadPixels; + functions->DrawPixels = _swrast_DrawPixels; + ++ /* CopyPixels can be accelerated even with the current memory ++ * manager: ++ */ ++ functions->CopyPixels = intelCopyPixels; ++ + intelInitTextureFuncs( functions ); + intelInitStateFuncs( functions ); + intelInitBufferFuncs( functions ); +@@ -370,8 +378,6 @@ GLboolean intelInitContext( struct intel + exit(1); + } + +- _math_matrix_ctr (&intel->ViewportMatrix); +- + driInitExtensions( ctx, card_extensions, + GL_TRUE ); + +@@ -446,8 +452,6 @@ GLboolean intelInitContext( struct intel + /* DRI_TEXMGR_DO_TEXTURE_RECT ); */ + + +- intel->prim.primitive = ~0; +- + if (getenv("INTEL_NO_RAST")) { + fprintf(stderr, "disabling 3D rasterization\n"); + intel->no_rast = 1; +@@ -537,18 +541,13 @@ GLboolean intelMakeCurrent(__DRIcontextP + } + + +-static void lost_hardware( struct intel_context *intel ) +-{ +- bm_fake_NotifyContendedLockTake( intel ); +- intel->vtbl.lost_hardware( intel ); +-} +- + static void intelContendedLock( struct intel_context *intel, GLuint flags ) + { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + volatile drmI830Sarea * sarea = intel->sarea; + int me = intel->hHWContext; ++ int my_bufmgr = bmCtxId(intel); + + drmGetLock(intel->driFd, intel->hHWContext, flags); + +@@ -562,12 +561,23 @@ static void intelContendedLock( struct i + + + intel->locked = 1; ++ intel->need_flush = 1; + + /* Lost context? + */ + if (sarea->ctxOwner != me) { ++ DBG("Lost Context: sarea->ctxOwner %x me %x\n", sarea->ctxOwner, me); + sarea->ctxOwner = me; +- lost_hardware(intel); ++ intel->vtbl.lost_hardware( intel ); ++ } ++ ++ /* As above, but don't evict the texture data on transitions ++ * between contexts which all share a local buffer manager. ++ */ ++ if (sarea->texAge != my_bufmgr) { ++ DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr); ++ sarea->texAge = my_bufmgr; ++ bm_fake_NotifyContendedLockTake( intel ); + } + + /* Drawable changed? +diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h +index 0328cb9..d0354cf 100644 +--- a/src/mesa/drivers/dri/i965/intel_context.h ++++ b/src/mesa/drivers/dri/i965/intel_context.h +@@ -176,16 +176,6 @@ struct intel_context + + struct intel_batchbuffer *batch; + +- struct { +- GLuint id; +- GLuint primitive; +- GLubyte *start_ptr; +- void (*flush)( struct intel_context * ); +- } prim; +- +- GLboolean locked; +- GLboolean strict_conformance; +- + GLubyte clear_chan[4]; + GLuint ClearColor; + GLuint ClearDepth; +@@ -201,6 +191,10 @@ struct intel_context + GLboolean no_hw; + GLboolean no_rast; + GLboolean thrashing; ++ GLboolean locked; ++ GLboolean strict_conformance; ++ GLboolean need_flush; ++ + + + /* AGP memory buffer manager: +@@ -210,26 +204,14 @@ struct intel_context + + /* State for intelvb.c and inteltris.c. + */ +- GLuint RenderIndex; +- GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; +- GLuint vertex_size; +- GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ +- + + struct intel_region *front_region; + struct intel_region *back_region; + struct intel_region *draw_region; + struct intel_region *depth_region; + +- +- /* Fallback rasterization functions +- */ +- intel_point_func draw_point; +- intel_line_func draw_line; +- intel_tri_func draw_tri; +- + /* These refer to the current draw (front vs. back) buffer: + */ + int drawX; /* origin of drawable in draw buffer */ +@@ -496,6 +478,13 @@ extern GLboolean intel_intersect_cliprec + const drm_clip_rect_t *b ); + + ++/* ================================================================ ++ * intel_pixel_copy.c: ++ */ ++void intelCopyPixels(GLcontext * ctx, ++ GLint srcx, GLint srcy, ++ GLsizei width, GLsizei height, ++ GLint destx, GLint desty, GLenum type); + + #define _NEW_WINDOW_POS 0x40000000 + +diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c +new file mode 100644 +index 0000000..ad27867 +--- /dev/null ++++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c +@@ -0,0 +1,239 @@ ++/************************************************************************** ++ * ++ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ++ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ++ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++ ++#include "glheader.h" ++#include "enums.h" ++#include "image.h" ++#include "mtypes.h" ++#include "macros.h" ++#include "state.h" ++#include "swrast/swrast.h" ++ ++#include "intel_screen.h" ++#include "intel_context.h" ++#include "intel_ioctl.h" ++#include "intel_batchbuffer.h" ++#include "intel_blit.h" ++#include "intel_regions.h" ++ ++ ++static struct intel_region * ++copypix_src_region(struct intel_context *intel, GLenum type) ++{ ++ switch (type) { ++ case GL_COLOR: ++ return intel_readbuf_region(intel); ++ case GL_DEPTH: ++ /* Don't think this is really possible execpt at 16bpp, when we have no stencil. ++ */ ++ if (intel->depth_region && intel->depth_region->cpp == 2) ++ return intel->depth_region; ++ case GL_STENCIL: ++ /* Don't think this is really possible. ++ */ ++ break; ++ case GL_DEPTH_STENCIL_EXT: ++ /* Does it matter whether it is stencil/depth or depth/stencil? ++ */ ++ return intel->depth_region; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++ ++ ++ ++/** ++ * Check if any fragment operations are in effect which might effect ++ * glDraw/CopyPixels. ++ */ ++static GLboolean ++intel_check_blit_fragment_ops(GLcontext * ctx) ++{ ++ if (ctx->NewState) ++ _mesa_update_state(ctx); ++ ++ /* Could do logicop with the blitter: ++ */ ++ return !(ctx->_ImageTransferState || ++ ctx->Color.AlphaEnabled || ++ ctx->Depth.Test || ++ ctx->Fog.Enabled || ++ ctx->Stencil.Enabled || ++ !ctx->Color.ColorMask[0] || ++ !ctx->Color.ColorMask[1] || ++ !ctx->Color.ColorMask[2] || ++ !ctx->Color.ColorMask[3] || ++ ctx->Color.ColorLogicOpEnabled || ++ ctx->Texture._EnabledUnits || ++ ctx->FragmentProgram._Enabled); ++} ++ ++ ++ ++/** ++ * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. ++ */ ++static GLboolean ++do_blit_copypixels(GLcontext * ctx, ++ GLint srcx, GLint srcy, ++ GLsizei width, GLsizei height, ++ GLint dstx, GLint dsty, GLenum type) ++{ ++ struct intel_context *intel = intel_context(ctx); ++ struct intel_region *dst = intel_drawbuf_region(intel); ++ struct intel_region *src = copypix_src_region(intel, type); ++ ++ /* Copypixels can be more than a straight copy. Ensure all the ++ * extra operations are disabled: ++ */ ++ if (!intel_check_blit_fragment_ops(ctx) || ++ ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) ++ return GL_FALSE; ++ ++ if (!src || !dst) ++ return GL_FALSE; ++ ++ ++ ++ intelFlush(&intel->ctx); ++ ++/* intel->vtbl.render_start(intel); */ ++/* intel->vtbl.emit_state(intel); */ ++ ++ LOCK_HARDWARE(intel); ++ ++ if (intel->driDrawable->numClipRects) { ++ __DRIdrawablePrivate *dPriv = intel->driDrawable; ++ drm_clip_rect_t *box = dPriv->pClipRects; ++ drm_clip_rect_t dest_rect; ++ GLint nbox = dPriv->numClipRects; ++ GLint delta_x = 0; ++ GLint delta_y = 0; ++ GLuint i; ++ ++ /* Do scissoring in GL coordinates: ++ */ ++ if (ctx->Scissor.Enabled) ++ { ++ GLint x = ctx->Scissor.X; ++ GLint y = ctx->Scissor.Y; ++ GLuint w = ctx->Scissor.Width; ++ GLuint h = ctx->Scissor.Height; ++ GLint dx = dstx - srcx; ++ GLint dy = dsty - srcy; ++ ++ if (!_mesa_clip_to_region(x, y, x+w, y+h, &dstx, &dsty, &width, &height)) ++ goto out; ++ ++ srcx = dstx - dx; ++ srcy = dsty - dy; ++ } ++ ++ /* Convert from GL to hardware coordinates: ++ */ ++ dsty = dPriv->h - dsty - height; ++ srcy = dPriv->h - srcy - height; ++ dstx += dPriv->x; ++ dsty += dPriv->y; ++ srcx += dPriv->x; ++ srcy += dPriv->y; ++ ++ /* Clip against the source region. This is the only source ++ * clipping we do. Dst is clipped with cliprects below. ++ */ ++ { ++ delta_x = srcx - dstx; ++ delta_y = srcy - dsty; ++ ++ if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, ++ &srcx, &srcy, &width, &height)) ++ goto out; ++ ++ dstx = srcx - delta_x; ++ dsty = srcy - delta_y; ++ } ++ ++ dest_rect.x1 = dstx; ++ dest_rect.y1 = dsty; ++ dest_rect.x2 = dstx + width; ++ dest_rect.y2 = dsty + height; ++ ++/* intel->vtbl.emit_flush(intel, 0); */ ++ ++ /* Could do slightly more clipping: Eg, take the intersection of ++ * the existing set of cliprects and those cliprects translated ++ * by delta_x, delta_y: ++ * ++ * This code will not overwrite other windows, but will ++ * introduce garbage when copying from obscured window regions. ++ */ ++ for (i = 0; i < nbox; i++) { ++ drm_clip_rect_t rect; ++ ++ if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) ++ continue; ++ ++ ++ intelEmitCopyBlit(intel, ++ dst->cpp, ++ src->pitch, src->buffer, 0, src->tiled, ++ dst->pitch, dst->buffer, 0, dst->tiled, ++ rect.x1 + delta_x, ++ rect.y1 + delta_y, /* srcx, srcy */ ++ rect.x1, rect.y1, /* dstx, dsty */ ++ rect.x2 - rect.x1, rect.y2 - rect.y1); ++ } ++ ++ intel->need_flush = GL_TRUE; ++ out: ++ intel_batchbuffer_flush(intel->batch); ++ } ++ UNLOCK_HARDWARE(intel); ++ return GL_TRUE; ++} ++ ++void ++intelCopyPixels(GLcontext * ctx, ++ GLint srcx, GLint srcy, ++ GLsizei width, GLsizei height, ++ GLint destx, GLint desty, GLenum type) ++{ ++ if (INTEL_DEBUG & DEBUG_PIXEL) ++ fprintf(stderr, "%s\n", __FUNCTION__); ++ ++ if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) ++ return; ++ ++ if (INTEL_DEBUG & DEBUG_PIXEL) ++ _mesa_printf("fallback to _swrast_CopyPixels\n"); ++ ++ _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); ++} +diff --git a/src/mesa/drivers/dri/i965/intel_span.c b/src/mesa/drivers/dri/i965/intel_span.c +index c68def5..60fbecc 100644 +--- a/src/mesa/drivers/dri/i965/intel_span.c ++++ b/src/mesa/drivers/dri/i965/intel_span.c +@@ -35,6 +35,7 @@ #include "intel_regions.h" + #include "intel_span.h" + #include "intel_ioctl.h" + #include "intel_tex.h" ++#include "intel_batchbuffer.h" + #include "swrast/swrast.h" + + #undef DBG +@@ -207,6 +208,16 @@ void intelSpanRenderStart( GLcontext *ct + { + struct intel_context *intel = intel_context(ctx); + ++ if (intel->need_flush) { ++ LOCK_HARDWARE(intel); ++ intel->vtbl.emit_flush(intel, 0); ++ intel_batchbuffer_flush(intel->batch); ++ intel->need_flush = 0; ++ UNLOCK_HARDWARE(intel); ++ intelFinish(&intel->ctx); ++ } ++ ++ + LOCK_HARDWARE(intel); + + /* Just map the framebuffer and all textures. Bufmgr code will +diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c +index a471f67..ec6e046 100644 +--- a/src/mesa/drivers/dri/i965/intel_state.c ++++ b/src/mesa/drivers/dri/i965/intel_state.c +@@ -182,39 +182,6 @@ static void intelClearColor(GLcontext *c + } + + +-static void intelCalcViewport( GLcontext *ctx ) +-{ +- struct intel_context *intel = intel_context(ctx); +- const GLfloat *v = ctx->Viewport._WindowMap.m; +- GLfloat *m = intel->ViewportMatrix.m; +- GLint h = 0; +- +- if (intel->driDrawable) +- h = intel->driDrawable->h + SUBPIXEL_Y; +- +- /* See also intel_translate_vertex. SUBPIXEL adjustments can be done +- * via state vars, too. +- */ +- m[MAT_SX] = v[MAT_SX]; +- m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; +- m[MAT_SY] = - v[MAT_SY]; +- m[MAT_TY] = - v[MAT_TY] + h; +- m[MAT_SZ] = v[MAT_SZ] * intel->depth_scale; +- m[MAT_TZ] = v[MAT_TZ] * intel->depth_scale; +-} +- +-static void intelViewport( GLcontext *ctx, +- GLint x, GLint y, +- GLsizei width, GLsizei height ) +-{ +- intelCalcViewport( ctx ); +-} +- +-static void intelDepthRange( GLcontext *ctx, +- GLclampd nearval, GLclampd farval ) +-{ +- intelCalcViewport( ctx ); +-} + + /* Fallback to swrast for select and feedback. + */ +@@ -228,8 +195,6 @@ static void intelRenderMode( GLcontext * + void intelInitStateFuncs( struct dd_function_table *functions ) + { + functions->RenderMode = intelRenderMode; +- functions->Viewport = intelViewport; +- functions->DepthRange = intelDepthRange; + functions->ClearColor = intelClearColor; + } + +diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c +index 5f65242..91ae097 100644 +--- a/src/mesa/drivers/dri/i965/intel_tex_validate.c ++++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c +@@ -166,12 +166,15 @@ GLuint intel_finalize_mipmap_tree( struc + * target, imageFormat, etc. + */ + if (intelObj->mt && +- (intelObj->mt->first_level != intelObj->firstLevel || +- intelObj->mt->last_level != intelObj->lastLevel || ++ (intelObj->mt->target != intelObj->base.Target || + intelObj->mt->internal_format != firstImage->InternalFormat || ++ intelObj->mt->first_level != intelObj->firstLevel || ++ intelObj->mt->last_level != intelObj->lastLevel || + intelObj->mt->width0 != firstImage->Width || + intelObj->mt->height0 != firstImage->Height || +- intelObj->mt->depth0 != firstImage->Depth)) ++ intelObj->mt->depth0 != firstImage->Depth || ++ intelObj->mt->cpp != firstImage->TexFormat->TexelBytes || ++ intelObj->mt->compressed != firstImage->IsCompressed)) + { + intel_miptree_destroy(intel, intelObj->mt); + intelObj->mt = NULL; +diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c +index 590f357..f999e06 100644 +--- a/src/mesa/shader/program.c ++++ b/src/mesa/shader/program.c +@@ -917,6 +917,15 @@ _mesa_fetch_state(GLcontext *ctx, const + case STATE_NORMAL_SCALE: + ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); + break; ++ case STATE_TEXRECT_SCALE: { ++ const int unit = (int) state[2]; ++ const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; ++ if (texObj) { ++ struct gl_texture_image *texImage = texObj->Image[0][0]; ++ ASSIGN_4V(value, 1.0 / texImage->Width, 1.0 / texImage->Height, 0, 1); ++ } ++ break; ++ } + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; +@@ -988,6 +997,8 @@ static GLuint make_state_flags(const GLi + switch (state[1]) { + case STATE_NORMAL_SCALE: + return _NEW_MODELVIEW; ++ case STATE_TEXRECT_SCALE: ++ return _NEW_TEXTURE; + default: + _mesa_problem(NULL, "unexpected int. state in make_state_flags()"); + return 0; +@@ -1450,19 +1461,8 @@ static const struct instruction_info Ins + GLuint + _mesa_num_inst_src_regs(enum prog_opcode opcode) + { +- GLuint i; +-#ifdef DEBUG +- for (i = 0; i < MAX_OPCODE; i++) { +- ASSERT(i == InstInfo[i].Opcode); +- } +-#endif +- for (i = 0; i < MAX_OPCODE; i++) { +- if (InstInfo[i].Opcode == opcode) { +- return InstInfo[i].NumSrcRegs; +- } +- } +- _mesa_problem(NULL, "invalid opcode in _mesa_num_inst_src_regs"); +- return 0; ++ ASSERT(opcode == InstInfo[opcode].Opcode); ++ return InstInfo[opcode].NumSrcRegs; + } + + +@@ -1601,6 +1601,38 @@ print_src_reg(const struct prog_src_regi + srcReg->NegateBase, GL_FALSE)); + } + ++void ++_mesa_print_alu_instruction(const struct prog_instruction *inst, ++ const char *opcode_string, ++ GLuint numRegs) ++{ ++ GLuint j; ++ ++ _mesa_printf("%s", opcode_string); ++ ++ /* frag prog only */ ++ if (inst->SaturateMode == SATURATE_ZERO_ONE) ++ _mesa_printf("_SAT"); ++ ++ if (inst->DstReg.File != PROGRAM_UNDEFINED) { ++ _mesa_printf(" %s[%d]%s", ++ program_file_string((enum register_file) inst->DstReg.File), ++ inst->DstReg.Index, ++ writemask_string(inst->DstReg.WriteMask)); ++ } ++ ++ if (numRegs > 0) ++ _mesa_printf(", "); ++ ++ for (j = 0; j < numRegs; j++) { ++ print_src_reg(inst->SrcReg + j); ++ if (j + 1 < numRegs) ++ _mesa_printf(", "); ++ } ++ ++ _mesa_printf(";\n"); ++} ++ + + /** + * Print a single vertex/fragment program instruction. +@@ -1662,34 +1694,10 @@ _mesa_print_instruction(const struct pro + /* XXX may need for other special-case instructions */ + default: + /* typical alu instruction */ +- { +- const GLuint numRegs = _mesa_num_inst_src_regs(inst->Opcode); +- GLuint j; +- +- _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); +- +- /* frag prog only */ +- if (inst->SaturateMode == SATURATE_ZERO_ONE) +- _mesa_printf("_SAT"); +- +- if (inst->DstReg.File != PROGRAM_UNDEFINED) { +- _mesa_printf(" %s[%d]%s", +- program_file_string((enum register_file) inst->DstReg.File), +- inst->DstReg.Index, +- writemask_string(inst->DstReg.WriteMask)); +- } +- +- if (numRegs > 0) +- _mesa_printf(", "); +- +- for (j = 0; j < numRegs; j++) { +- print_src_reg(inst->SrcReg + j); +- if (j + 1 < numRegs) +- _mesa_printf(", "); +- } +- +- _mesa_printf(";\n"); +- } ++ _mesa_print_alu_instruction(inst, ++ _mesa_opcode_string(inst->Opcode), ++ _mesa_num_inst_src_regs(inst->Opcode)); ++ break; + } + } + +diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h +index 6a34533..cf3b1cc 100644 +--- a/src/mesa/shader/program.h ++++ b/src/mesa/shader/program.h +@@ -188,6 +188,7 @@ enum state_index { + + STATE_INTERNAL, /* Mesa additions */ + STATE_NORMAL_SCALE, ++ STATE_TEXRECT_SCALE, + STATE_POSITION_NORMALIZED /* normalized light position */ + }; + +@@ -264,6 +265,11 @@ _mesa_load_state_parameters(GLcontext *c + extern void + _mesa_print_instruction(const struct prog_instruction *inst); + ++void ++_mesa_print_alu_instruction(const struct prog_instruction *inst, ++ const char *opcode_string, ++ GLuint numRegs); ++ + extern void + _mesa_print_program(const struct gl_program *prog); +