summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@fedoraproject.org>2006-09-29 19:07:15 +0000
committerKristian Høgsberg <krh@fedoraproject.org>2006-09-29 19:07:15 +0000
commit96b4a67d038167d3bc4fca9f77afc0fd92280a2c (patch)
treeb4418295346b962fee2ed0b90656b629554d214f
parent769a885a89a62e3795ed6f96a9884c5777f02541 (diff)
downloadmesa-96b4a67d038167d3bc4fca9f77afc0fd92280a2c.tar.gz
mesa-96b4a67d038167d3bc4fca9f77afc0fd92280a2c.tar.xz
mesa-96b4a67d038167d3bc4fca9f77afc0fd92280a2c.zip
- Add -fno-strict-aliasing to compiler flags for i965 driver.mesa-6_5_1-6_fc6
- Add post-6.5.1-i965-fixes.patch backport of i965 fixes from mesa CVS.
-rw-r--r--mesa.spec14
-rw-r--r--post-6.5.1-i965-fixes.patch1061
2 files changed, 1073 insertions, 2 deletions
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 <krh@redhat.com> - 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 <sandamnn@redhat.com> - 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);
+