mesa/post-6.5.1-i965-fixes.patch
Kristian Høgsberg 96b4a67d03 - 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.
2006-09-29 19:07:15 +00:00

1062 lines
33 KiB
Diff

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);