summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2010-03-12 19:46:04 +0100
committerLuc Verhaegen <libv@skynet.be>2010-03-12 19:46:04 +0100
commit5c28087bfde504266a79dbbc8aef480009d88d2f (patch)
tree91c96846540390f5cb3c0daf36b17f1f65af9621
parent6e23622cb869c14d82f8c901c4bbea80ded6220e (diff)
Import i915 and i965 dri drivers from mesa 7.0.4 (debians 7.0.3-7).7.0.4
-rw-r--r--configure.ac7
-rw-r--r--i915/i915_context.h6
-rw-r--r--i915/i915_fragprog.c313
-rw-r--r--i915/i915_program.c38
-rw-r--r--i915/i915_program.h1
-rw-r--r--i915/i915_texprog.c2
-rw-r--r--i915/i915_texstate.c10
-rw-r--r--i915/intel_context.c2
-rw-r--r--i915/intel_context.h3
-rw-r--r--i915/intel_pixel.c8
-rw-r--r--i915/intel_screen.c3
-rw-r--r--i915/intel_state.c4
-rw-r--r--i915/intel_tex.c2
-rw-r--r--i915/intel_tris.c30
-rw-r--r--i965/Makefile.am1
-rw-r--r--i965/brw_aub_playback.c4
-rw-r--r--i965/brw_cc.c7
-rw-r--r--i965/brw_clip.h4
-rw-r--r--i965/brw_clip_line.c9
-rw-r--r--i965/brw_clip_state.c7
-rw-r--r--i965/brw_clip_tri.c108
-rw-r--r--i965/brw_clip_unfilled.c4
-rw-r--r--i965/brw_clip_util.c14
-rw-r--r--i965/brw_context.c11
-rw-r--r--i965/brw_curbe.c2
-rw-r--r--i965/brw_defines.h17
-rw-r--r--i965/brw_draw_upload.c27
-rw-r--r--i965/brw_eu.h26
-rw-r--r--i965/brw_eu_emit.c62
-rw-r--r--i965/brw_gs.h4
-rw-r--r--i965/brw_gs_state.c3
-rw-r--r--i965/brw_metaops.c2
-rw-r--r--i965/brw_misc_state.c4
-rw-r--r--i965/brw_program.c3
-rw-r--r--i965/brw_sf.c15
-rw-r--r--i965/brw_sf.h11
-rw-r--r--i965/brw_sf_emit.c98
-rw-r--r--i965/brw_sf_state.c11
-rw-r--r--i965/brw_state_cache.c2
-rw-r--r--i965/brw_state_pool.c5
-rw-r--r--i965/brw_structs.h2
-rw-r--r--i965/brw_tex.c31
-rw-r--r--i965/brw_tex_layout.c46
-rw-r--r--i965/brw_urb.c2
-rw-r--r--i965/brw_vs.h6
-rw-r--r--i965/brw_vs_emit.c254
-rw-r--r--i965/brw_vs_state.c2
-rw-r--r--i965/brw_vs_tnl.c19
-rw-r--r--i965/brw_wm.c119
-rw-r--r--i965/brw_wm.h17
-rw-r--r--i965/brw_wm_emit.c160
-rw-r--r--i965/brw_wm_fp.c123
-rw-r--r--i965/brw_wm_glsl.c1370
-rw-r--r--i965/brw_wm_pass0.c4
-rw-r--r--i965/brw_wm_pass1.c7
-rw-r--r--i965/brw_wm_pass2.c2
-rw-r--r--i965/brw_wm_sampler_state.c2
-rw-r--r--i965/brw_wm_state.c11
-rw-r--r--i965/brw_wm_surface_state.c31
-rw-r--r--i965/bufmgr_fake.c2
-rw-r--r--i965/intel_batchbuffer.c4
-rw-r--r--i965/intel_batchbuffer.h2
-rw-r--r--i965/intel_blit.c5
-rw-r--r--i965/intel_buffers.c5
-rw-r--r--i965/intel_context.c45
-rw-r--r--i965/intel_context.h11
-rw-r--r--i965/intel_mipmap_tree.c21
-rw-r--r--i965/intel_pixel_bitmap.c38
-rw-r--r--i965/intel_screen.c2
-rw-r--r--i965/intel_tex_validate.c36
-rw-r--r--shared/intel_tex_layout.c42
-rw-r--r--shared/intel_tex_layout.h1
72 files changed, 2816 insertions, 496 deletions
diff --git a/configure.ac b/configure.ac
index 70d46ac..4723f7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script
AC_PREREQ(2.57)
-AC_INIT([mesa-dri-i9xx], 7.0.3, [], mesa-dri-i9xx)
+AC_INIT([mesa-dri-i9xx], 7.0.4, [], mesa-dri-i9xx)
AM_INIT_AUTOMAKE([dist-bzip2])
@@ -16,8 +16,9 @@ AC_PROG_CC
AC_HEADER_STDC
PKG_CHECK_MODULES([DRM], [libdrm >= 2.3.0])
-PKG_CHECK_MODULES([DRI], [libmesadri >= 7.0.3 libmesadri < 7.1.0
- libmesadricommon >= 7.0.3 libmesadricommon < 7.1.0])
+# needs MESA_FORMAT_SRGB_DXT1
+PKG_CHECK_MODULES([DRI], [libmesadri >= 7.0.4 libmesadri < 7.1.0
+ libmesadricommon >= 7.0.4 libmesadricommon < 7.1.0])
AC_OUTPUT([
Makefile
diff --git a/i915/i915_context.h b/i915/i915_context.h
index ec15501..7b51d77 100644
--- a/i915/i915_context.h
+++ b/i915/i915_context.h
@@ -29,6 +29,7 @@
#define I915CONTEXT_INC
#include "intel_context.h"
+#include "i915_reg.h"
#define I915_FALLBACK_TEXTURE 0x1000
#define I915_FALLBACK_COLORMASK 0x2000
@@ -103,6 +104,7 @@
#define I915_PROGRAM_SIZE 192
+#define I915_MAX_INSN (I915_MAX_TEX_INSN+I915_MAX_ALU_INSN)
/* Hardware version of a parsed fragment program. "Derived" from the
* mesa fragment_program struct.
@@ -153,6 +155,10 @@ struct i915_fragment_program {
*/
+ /* Track which R registers are "live" for each instruction.
+ * A register is live between the time it's written to and the last time
+ * it's read. */
+ GLuint usedRegs[I915_MAX_INSN];
/* Helpers for i915_fragprog.c:
*/
diff --git a/i915/i915_fragprog.c b/i915/i915_fragprog.c
index a28c8bb..c46ef24 100644
--- a/i915/i915_fragprog.c
+++ b/i915/i915_fragprog.c
@@ -42,7 +42,20 @@
#include "program.h"
#include "programopt.h"
-
+static const GLfloat sin_quad_constants[2][4] = {
+ {
+ 2.0,
+ -1.0,
+ .5,
+ .75
+ },
+ {
+ 4.0,
+ -4.0,
+ 1.0 / (2.0 * M_PI),
+ .2225
+ }
+};
/* 1, -1/3!, 1/5!, -1/7! */
static const GLfloat sin_constants[4] = { 1.0,
@@ -91,7 +104,7 @@ static GLuint src_vector( struct i915_fragment_program *p,
break;
case FRAG_ATTRIB_FOGC:
src = i915_emit_decl( p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W );
- src = swizzle( src, W, W, W, W );
+ src = swizzle(src, W, ZERO, ZERO, ONE);
break;
case FRAG_ATTRIB_TEX0:
case FRAG_ATTRIB_TEX1:
@@ -211,7 +224,7 @@ do { \
GLuint coord = src_vector( p, &inst->SrcReg[0], program); \
/* Texel lookup */ \
\
- i915_emit_texld( p, \
+ i915_emit_texld( p, get_live_regs(p, inst), \
get_result_vector( p, inst ), \
get_result_flags( inst ), \
sampler, \
@@ -234,6 +247,43 @@ do { \
#define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 )
#define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 )
+/*
+ * TODO: consider moving this into core
+ */
+static void calc_live_regs( struct i915_fragment_program *p )
+{
+ const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current;
+ GLuint regsUsed = 0xffff0000;
+ GLint i;
+
+ for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
+ struct prog_instruction *inst = &program->Base.Instructions[i];
+ int opArgs = _mesa_num_inst_src_regs(inst->Opcode);
+ int a;
+
+ /* Register is written to: unmark as live for this and preceeding ops */
+ if (inst->DstReg.File == PROGRAM_TEMPORARY)
+ regsUsed &= ~(1 << inst->DstReg.Index);
+
+ for (a = 0; a < opArgs; a++) {
+ /* Register is read from: mark as live for this and preceeding ops */
+ if (inst->SrcReg[a].File == PROGRAM_TEMPORARY)
+ regsUsed |= 1 << inst->SrcReg[a].Index;
+ }
+
+ p->usedRegs[i] = regsUsed;
+ }
+}
+
+static GLuint get_live_regs( struct i915_fragment_program *p,
+ const struct prog_instruction *inst )
+{
+ const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current;
+ GLuint nr = inst - program->Base.Instructions;
+
+ return p->usedRegs[nr];
+}
+
/* Possible concerns:
*
@@ -267,9 +317,18 @@ static void upload_program( struct i915_fragment_program *p )
return;
}
+ if (program->Base.NumInstructions > I915_MAX_INSN) {
+ i915_program_error( p, "Exceeded max instructions" );
+ return;
+ }
+
+ /* Not always needed:
+ */
+ calc_live_regs(p);
+
while (1) {
GLuint src0, src1, src2, flags;
- GLuint tmp = 0;
+ GLuint tmp = 0, consts0 = 0, consts1 = 0;
switch (inst->Opcode) {
case OPCODE_ABS:
@@ -297,67 +356,87 @@ static void upload_program( struct i915_fragment_program *p )
break;
case OPCODE_COS:
- src0 = src_vector( p, &inst->SrcReg[0], program);
- tmp = i915_get_utemp( p );
-
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- src0,
- i915_emit_const1f(p, 1.0/(M_PI * 2)),
- 0);
-
- i915_emit_arith( p,
- A0_MOD,
+ src0 = src_vector(p, &inst->SrcReg[0], program);
+ tmp = i915_get_utemp(p);
+ consts0 = i915_emit_const4fv(p, sin_quad_constants[0]);
+ consts1 = i915_emit_const4fv(p, sin_quad_constants[1]);
+
+ /* Reduce range from repeating about [-pi,pi] to [-1,1] */
+ i915_emit_arith(p,
+ A0_MAD,
+ tmp, A0_DEST_CHANNEL_X, 0,
+ src0,
+ swizzle(consts1, Z, ZERO, ZERO, ZERO), /* 1/(2pi) */
+ swizzle(consts0, W, ZERO, ZERO, ZERO)); /* .75 */
+
+ i915_emit_arith(p, A0_FRC, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
+
+ i915_emit_arith(p,
+ A0_MAD,
tmp, A0_DEST_CHANNEL_X, 0,
- tmp,
- 0, 0 );
+ tmp,
+ swizzle(consts0, X, ZERO, ZERO, ZERO), /* 2 */
+ swizzle(consts0, Y, ZERO, ZERO, ZERO)); /* -1 */
- /* By choosing different taylor constants, could get rid of this mul:
+ /* Compute COS with the same calculation used for SIN, but a
+ * different source range has been mapped to [-1,1] this time.
*/
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp,
- i915_emit_const1f(p, (M_PI * 2)),
+
+ /* tmp.y = abs(tmp.x); {x, abs(x), 0, 0} */
+ i915_emit_arith(p,
+ A0_MAX,
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
0);
- /*
- * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
- * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1
- * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1
- * result = DP4 t0, cos_constants
- */
- i915_emit_arith( p,
+ /* tmp.y = tmp.y * tmp.x; {x, x * abs(x), 0, 0} */
+ i915_emit_arith(p,
A0_MUL,
- tmp, A0_DEST_CHANNEL_XY, 0,
- swizzle(tmp, X,X,ONE,ONE),
- swizzle(tmp, X,ONE,ONE,ONE), 0);
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ tmp,
+ 0);
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_XYZ, 0,
- swizzle(tmp, X,Y,X,ONE),
- swizzle(tmp, X,X,ONE,ONE), 0);
+ /* tmp.x = tmp.xy DP sin_quad_constants[2].xy */
+ i915_emit_arith(p,
+ A0_DP3,
+ tmp, A0_DEST_CHANNEL_X, 0,
+ tmp,
+ swizzle(consts1, X, Y, ZERO, ZERO),
+ 0);
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_XYZ, 0,
- swizzle(tmp, X,X,Z,ONE),
- swizzle(tmp, Z,ONE,ONE,ONE), 0);
-
- i915_emit_arith( p,
- A0_DP4,
- get_result_vector( p, inst ),
- get_result_flags( inst ), 0,
- swizzle(tmp, ONE,Z,Y,X),
- i915_emit_const4fv( p, cos_constants ), 0);
+ /* tmp.x now contains a first approximation (y). Now, weight it
+ * against tmp.y**2 to get closer.
+ */
+ i915_emit_arith(p,
+ A0_MAX,
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
+ 0);
- break;
+ /* tmp.y = tmp.x * tmp.y - tmp.x; {y, y * abs(y) - y, 0, 0} */
+ i915_emit_arith(p,
+ A0_MAD,
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ swizzle(tmp, ZERO, Y, ZERO, ZERO),
+ negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0));
- case OPCODE_DP3:
- EMIT_2ARG_ARITH( A0_DP3 );
- break;
+ /* result = .2225 * tmp.y + tmp.x =.2225(y * abs(y) - y) + y= */
+ i915_emit_arith(p,
+ A0_MAD,
+ get_result_vector(p, inst),
+ get_result_flags(inst), 0,
+ swizzle(consts1, W, W, W, W),
+ swizzle(tmp, Y, Y, Y, Y),
+ swizzle(tmp, X, X, X, X));
+ break;
+
+ case OPCODE_DP3:
+ EMIT_2ARG_ARITH(A0_DP3);
+ break;
case OPCODE_DP4:
EMIT_2ARG_ARITH( A0_DP4 );
@@ -414,11 +493,9 @@ static void upload_program( struct i915_fragment_program *p )
src0 = src_vector( p, &inst->SrcReg[0], program);
tmp = i915_get_utemp( p );
- i915_emit_texld( p,
- tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */
- 0,
- src0,
- T0_TEXKILL );
+ i915_emit_texld(p, get_live_regs(p, inst),
+ tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */
+ 0, src0, T0_TEXKILL);
break;
case OPCODE_LG2:
@@ -638,62 +715,86 @@ static void upload_program( struct i915_fragment_program *p )
break;
case OPCODE_SIN:
- src0 = src_vector( p, &inst->SrcReg[0], program);
- tmp = i915_get_utemp( p );
+ src0 = src_vector(p, &inst->SrcReg[0], program);
+ tmp = i915_get_utemp(p);
+ consts0 = i915_emit_const4fv(p, sin_quad_constants[0]);
+ consts1 = i915_emit_const4fv(p, sin_quad_constants[1]);
+
+ /* Reduce range from repeating about [-pi,pi] to [-1,1] */
+ i915_emit_arith(p,
+ A0_MAD,
+ tmp, A0_DEST_CHANNEL_X, 0,
+ src0,
+ swizzle(consts1, Z, ZERO, ZERO, ZERO), /* 1/(2pi) */
+ swizzle(consts0, Z, ZERO, ZERO, ZERO)); /* .5 */
+
+ i915_emit_arith(p, A0_FRC, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
+ i915_emit_arith(p,
+ A0_MAD,
+ tmp, A0_DEST_CHANNEL_X, 0,
+ tmp,
+ swizzle(consts0, X, ZERO, ZERO, ZERO), /* 2 */
+ swizzle(consts0, Y, ZERO, ZERO, ZERO)); /* -1 */
- i915_emit_arith( p,
+ /* Compute sin using a quadratic and quartic. It gives continuity
+ * that repeating the Taylor series lacks every 2*pi, and has
+ * reduced error.
+ *
+ * The idea was described at:
+ * http://www.devmaster.net/forums/showthread.php?t=5784
+ */
+ /* tmp.y = abs(tmp.x); {x, abs(x), 0, 0} */
+ i915_emit_arith(p,
+ A0_MAX,
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
+ 0);
+
+ /* tmp.y = tmp.y * tmp.x; {x, x * abs(x), 0, 0} */
+ i915_emit_arith(p,
A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- src0,
- i915_emit_const1f(p, 1.0/(M_PI * 2)),
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ tmp,
0);
- i915_emit_arith( p,
- A0_MOD,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp,
- 0, 0 );
+ /* tmp.x = tmp.xy DP sin_quad_constants[2].xy */
+ i915_emit_arith(p,
+ A0_DP3,
+ tmp, A0_DEST_CHANNEL_X, 0,
+ tmp,
+ swizzle(consts1, X, Y, ZERO, ZERO),
+ 0);
- /* By choosing different taylor constants, could get rid of this mul:
+ /* tmp.x now contains a first approximation (y). Now, weight it
+ * against tmp.y**2 to get closer.
*/
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp,
- i915_emit_const1f(p, (M_PI * 2)),
+ i915_emit_arith(p,
+ A0_MAX,
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
0);
- /*
- * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
- * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x
- * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x
- * result = DP4 t1.wzyx, sin_constants
- */
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_XY, 0,
- swizzle(tmp, X,X,ONE,ONE),
- swizzle(tmp, X,ONE,ONE,ONE), 0);
+ /* tmp.y = tmp.x * tmp.y - tmp.x; {y, y * abs(y) - y, 0, 0} */
+ i915_emit_arith(p,
+ A0_MAD,
+ tmp, A0_DEST_CHANNEL_Y, 0,
+ swizzle(tmp, ZERO, X, ZERO, ZERO),
+ swizzle(tmp, ZERO, Y, ZERO, ZERO),
+ negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0));
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_ALL, 0,
- swizzle(tmp, X,Y,X,Y),
- swizzle(tmp, X,X,ONE,ONE), 0);
+ /* result = .2225 * tmp.y + tmp.x =.2225(y * abs(y) - y) + y= */
+ i915_emit_arith(p,
+ A0_MAD,
+ get_result_vector(p, inst),
+ get_result_flags(inst), 0,
+ swizzle(consts1, W, W, W, W),
+ swizzle(tmp, Y, Y, Y, Y),
+ swizzle(tmp, X, X, X, X));
- i915_emit_arith( p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_ALL, 0,
- swizzle(tmp, X,Y,Y,W),
- swizzle(tmp, X,Z,ONE,ONE), 0);
-
- i915_emit_arith( p,
- A0_DP4,
- get_result_vector( p, inst ),
- get_result_flags( inst ), 0,
- swizzle(tmp, W, Z, Y, X ),
- i915_emit_const4fv( p, sin_constants ), 0);
- break;
+ break;
case OPCODE_SLT:
EMIT_2ARG_ARITH( A0_SLT );
diff --git a/i915/i915_program.c b/i915/i915_program.c
index 6849112..31be4b5 100644
--- a/i915/i915_program.c
+++ b/i915/i915_program.c
@@ -194,27 +194,43 @@ GLuint i915_emit_arith( struct i915_fragment_program *p,
return dest;
}
+static GLuint get_free_rreg (struct i915_fragment_program *p,
+ GLuint live_regs)
+{
+ int bit = ffs(~live_regs);
+ if (!bit) {
+ i915_program_error(p, "Can't find free R reg");
+ return UREG_BAD;
+ }
+ return UREG(REG_TYPE_R, bit - 1);
+}
+
GLuint i915_emit_texld( struct i915_fragment_program *p,
+ GLuint live_regs,
GLuint dest,
GLuint destmask,
GLuint sampler,
GLuint coord,
GLuint op )
{
- if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
- /* No real way to work around this in the general case - need to
- * allocate and declare a new temporary register (a utemp won't
- * do). Will fallback for now.
- */
- i915_program_error(p, "Can't (yet) swizzle TEX arguments");
- return 0;
- }
-
- /* Don't worry about saturate as we only support
+ if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
+ /* With the help of the "needed registers" table created earlier, pick
+ * a register we can MOV the swizzled TC to (since TEX doesn't support
+ * swizzled sources) */
+ GLuint swizCoord = get_free_rreg(p, live_regs);
+ if (swizCoord == UREG_BAD)
+ return 0;
+
+ i915_emit_arith( p, A0_MOV, swizCoord, A0_DEST_CHANNEL_ALL, 0, coord, 0, 0 );
+ coord = swizCoord;
+ }
+
+ /* Don't worry about saturate as we only support texture formats
+ * that are always in the 0..1 range.
*/
if (destmask != A0_DEST_CHANNEL_ALL) {
GLuint tmp = i915_get_utemp(p);
- i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
+ i915_emit_texld( p, 0, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
return dest;
}
diff --git a/i915/i915_program.h b/i915/i915_program.h
index 8891a17..d9760f9 100644
--- a/i915/i915_program.h
+++ b/i915/i915_program.h
@@ -110,6 +110,7 @@ extern void i915_release_utemps( struct i915_fragment_program *p );
extern GLuint i915_emit_texld( struct i915_fragment_program *p,
+ GLuint live_regs,
GLuint dest,
GLuint destmask,
GLuint sampler,
diff --git a/i915/i915_texprog.c b/i915/i915_texprog.c
index f6a8b02..c467fe1 100644
--- a/i915/i915_texprog.c
+++ b/i915/i915_texprog.c
@@ -69,7 +69,7 @@ static GLuint get_source( struct i915_fragment_program *p,
if (p->VB->TexCoordPtr[unit]->size == 4)
op = T0_TEXLDP;
- p->src_texture = i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL,
+ p->src_texture = i915_emit_texld( p, 0, tmp, A0_DEST_CHANNEL_ALL,
sampler, texcoord, op );
}
diff --git a/i915/i915_texstate.c b/i915/i915_texstate.c
index a19d4b6..08c561e 100644
--- a/i915/i915_texstate.c
+++ b/i915/i915_texstate.c
@@ -454,7 +454,12 @@ static void i915SetTexImages( i915ContextPtr i915,
case MESA_FORMAT_Z16:
t->intel.texelBytes = 2;
- textureFormat = (MAPSURF_16BIT | MT_16BIT_L16);
+ if (tObj->DepthMode == GL_ALPHA)
+ textureFormat = (MAPSURF_16BIT | MT_16BIT_A16);
+ else if (tObj->DepthMode == GL_INTENSITY)
+ textureFormat = (MAPSURF_16BIT | MT_16BIT_I16);
+ else
+ textureFormat = (MAPSURF_16BIT | MT_16BIT_L16);
break;
case MESA_FORMAT_RGBA_DXT1:
@@ -737,6 +742,9 @@ static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
return GL_FALSE;
}
+ if (tObj->Target == GL_TEXTURE_1D &&
+ tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB)
+ return GL_FALSE;
/* Update state if this is a different texture object to last
* time.
diff --git a/i915/intel_context.c b/i915/intel_context.c
index bb5ce64..9bca64a 100644
--- a/i915/intel_context.c
+++ b/i915/intel_context.c
@@ -117,6 +117,8 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
chipset = "Intel(R) 865G"; break;
case PCI_CHIP_I915_G:
chipset = "Intel(R) 915G"; break;
+ case PCI_CHIP_E7221_G:
+ chipset = "Intel (R) E7221G (i915)"; break;
case PCI_CHIP_I915_GM:
chipset = "Intel(R) 915GM"; break;
case PCI_CHIP_I945_G:
diff --git a/i915/intel_context.h b/i915/intel_context.h
index 50e6178..634d581 100644
--- a/i915/intel_context.h
+++ b/i915/intel_context.h
@@ -361,6 +361,8 @@ do { \
#define SUBPIXEL_X 0.125
#define SUBPIXEL_Y 0.125
+#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
+
#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
@@ -451,6 +453,7 @@ extern int INTEL_DEBUG;
#define PCI_CHIP_I855_GM 0x3582
#define PCI_CHIP_I865_G 0x2572
#define PCI_CHIP_I915_G 0x2582
+#define PCI_CHIP_E7221_G 0x258A
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_GM 0x27A2
diff --git a/i915/intel_pixel.c b/i915/intel_pixel.c
index 535cbfc..c5005ba 100644
--- a/i915/intel_pixel.c
+++ b/i915/intel_pixel.c
@@ -228,7 +228,7 @@ intelTryReadPixels( GLcontext *ctx,
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
int src_offset = intel->readRegion->offset;
- int src_pitch = intel->intelScreen->front.pitch;
+ int src_pitch = intel->intelScreen->front.pitch / intel->intelScreen->cpp; /* in pixels */
int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
drm_clip_rect_t *box = dPriv->pClipRects;
int i;
@@ -308,7 +308,7 @@ static void do_draw_pix( GLcontext *ctx,
int nbox = dPriv->numClipRects;
int i;
int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
- int src_pitch = pitch;
+ int src_pitch = pitch; /* in pixels */
assert(src_offset != ~0); /* should be caught earlier */
@@ -339,7 +339,7 @@ static void do_draw_pix( GLcontext *ctx,
intelEmitCopyBlitLocked( intel,
intel->intelScreen->cpp,
src_pitch, src_offset,
- intel->intelScreen->front.pitch,
+ intel->intelScreen->front.pitch / intel->intelScreen->cpp, /* in pixels */
intel->drawRegion->offset,
bx - x, by - y,
bx, by,
@@ -364,7 +364,7 @@ intelTryDrawPixels( GLcontext *ctx,
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
GLuint dest;
GLuint cpp = intel->intelScreen->cpp;
- GLint size = width * pitch * cpp;
+ GLint size = height * pitch * cpp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
diff --git a/i915/intel_screen.c b/i915/intel_screen.c
index ca8610b..a66cfd6 100644
--- a/i915/intel_screen.c
+++ b/i915/intel_screen.c
@@ -53,7 +53,7 @@ DRI_CONF_BEGIN
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
+ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
DRI_CONF_SECTION_END
DRI_CONF_END;
const GLuint __driNConfigOptions = 4;
@@ -511,6 +511,7 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
sharedContextPrivate );
case PCI_CHIP_I915_G:
+ case PCI_CHIP_E7221_G:
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
diff --git a/i915/intel_state.c b/i915/intel_state.c
index e5988a5..b333ec5 100644
--- a/i915/intel_state.c
+++ b/i915/intel_state.c
@@ -189,12 +189,12 @@ static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
- intelSetFrontClipRects( intel );
-
if (front) {
+ intelSetFrontClipRects( intel );
intel->drawRegion = &intel->intelScreen->front;
intel->readRegion = &intel->intelScreen->front;
} else {
+ intelSetBackClipRects( intel );
intel->drawRegion = &intel->intelScreen->back;
intel->readRegion = &intel->intelScreen->back;
}
diff --git a/i915/intel_tex.c b/i915/intel_tex.c
index 5bd2806..8460134 100644
--- a/i915/intel_tex.c
+++ b/i915/intel_tex.c
@@ -759,7 +759,7 @@ int intelUploadTexImages( intelContextPtr intel,
GLuint face)
{
const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
- const struct gl_texture_image *firstImage = t->image[face][t->base.firstLevel].image;
+ const struct gl_texture_image *firstImage = t->image[face][0].image;
int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes;
/* Can we texture out of the existing client data? */
diff --git a/i915/intel_tris.c b/i915/intel_tris.c
index b2787ee..3c5ed47 100644
--- a/i915/intel_tris.c
+++ b/i915/intel_tris.c
@@ -202,12 +202,19 @@ static void intel_wpos_triangle( intelContextPtr intel,
{
GLuint offset = intel->wpos_offset;
GLuint size = intel->wpos_size;
-
- __memcpy( ((char *)v0) + offset, v0, size );
- __memcpy( ((char *)v1) + offset, v1, size );
- __memcpy( ((char *)v2) + offset, v2, size );
+ GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset);
+ GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset);
+ GLfloat *v2_wpos = (GLfloat *)((char *)v2 + offset);
+
+ __memcpy(v0_wpos, v0, size);
+ __memcpy(v1_wpos, v1, size);
+ __memcpy(v2_wpos, v2, size);
- intel_draw_triangle( intel, v0, v1, v2 );
+ v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h;
+ v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h;
+ v2_wpos[1] = -v2_wpos[1] + intel->driDrawable->h;
+
+ intel_draw_triangle(intel, v0, v1, v2);
}
@@ -217,9 +224,14 @@ static void intel_wpos_line( intelContextPtr intel,
{
GLuint offset = intel->wpos_offset;
GLuint size = intel->wpos_size;
+ GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset);
+ GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset);
+
+ __memcpy(v0_wpos, v0, size);
+ __memcpy(v1_wpos, v1, size);
- __memcpy( ((char *)v0) + offset, v0, size );
- __memcpy( ((char *)v1) + offset, v1, size );
+ v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h;
+ v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h;
intel_draw_line( intel, v0, v1 );
}
@@ -230,8 +242,10 @@ static void intel_wpos_point( intelContextPtr intel,
{
GLuint offset = intel->wpos_offset;
GLuint size = intel->wpos_size;
+ GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset);
- __memcpy( ((char *)v0) + offset, v0, size );
+ __memcpy(v0_wpos, v0, size);
+ v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h;
intel_draw_point( intel, v0 );
}
diff --git a/i965/Makefile.am b/i965/Makefile.am
index 163ad0f..55d7cbc 100644
--- a/i965/Makefile.am
+++ b/i965/Makefile.am
@@ -71,6 +71,7 @@ i965_dri_la_SOURCES = \
brw_wm_emit.c \
brw_wm_fp.c \
brw_wm_iz.c \
+ brw_wm_glsl.c \
brw_wm_pass0.c \
brw_wm_pass1.c \
brw_wm_pass2.c \
diff --git a/i965/brw_aub_playback.c b/i965/brw_aub_playback.c
index 99d9475..3a6c4dd 100644
--- a/i965/brw_aub_playback.c
+++ b/i965/brw_aub_playback.c
@@ -144,14 +144,14 @@ static struct {
{ CMD_STATE_BASE_ADDRESS, "STATE_BASE_ADDRESS", 1 },
{ CMD_STATE_INSN_POINTER, "STATE_INSN_POINTER", 1 },
{ CMD_PIPELINE_SELECT_965, "PIPELINE_SELECT", 0, },
- { CMD_PIPELINE_SELECT_IGD, "PIPELINE_SELECT", 0,},
+ { CMD_PIPELINE_SELECT_GM45, "PIPELINE_SELECT", 0,},
{ CMD_PIPELINED_STATE_POINTERS, "PIPELINED_STATE_POINTERS", 1 },
{ CMD_BINDING_TABLE_PTRS, "BINDING_TABLE_PTRS", 1 },
{ CMD_VERTEX_BUFFER, "VERTEX_BUFFER", 1 },
{ CMD_VERTEX_ELEMENT, "VERTEX_ELEMENT", 1 },
{ CMD_INDEX_BUFFER, "INDEX_BUFFER", 1 },
{ CMD_VF_STATISTICS_965, "VF_STATISTICS", 0 },
- { CMD_VF_STATISTICS_IGD, "VF_STATISTICS", 0 },
+ { CMD_VF_STATISTICS_GM45, "VF_STATISTICS", 0 },
{ CMD_DRAW_RECT, "DRAW_RECT", 1 },
{ CMD_BLEND_CONSTANT_COLOR, "BLEND_CONSTANT_COLOR", 1 },
{ CMD_CHROMA_KEY, "CHROMA_KEY", 1 },
diff --git a/i965/brw_cc.c b/i965/brw_cc.c
index 8a1d152..1d7a3cb 100644
--- a/i965/brw_cc.c
+++ b/i965/brw_cc.c
@@ -76,8 +76,8 @@ static void upload_cc_unit( struct brw_context *brw )
cc.cc1.stencil_write_mask = brw->attribs.Stencil->WriteMask[0];
cc.cc1.stencil_test_mask = brw->attribs.Stencil->ValueMask[0];
- if (brw->attribs.Stencil->TestTwoSide) {
- cc.cc0.bf_stencil_enable = brw->attribs.Stencil->TestTwoSide;
+ if (brw->attribs.Stencil->_TestTwoSide) {
+ cc.cc0.bf_stencil_enable = brw->attribs.Stencil->_TestTwoSide;
cc.cc0.bf_stencil_func = intel_translate_compare_func(brw->attribs.Stencil->Function[1]);
cc.cc0.bf_stencil_fail_op = intel_translate_stencil_op(brw->attribs.Stencil->FailFunc[1]);
cc.cc0.bf_stencil_pass_depth_fail_op = intel_translate_stencil_op(brw->attribs.Stencil->ZFailFunc[1]);
@@ -90,7 +90,8 @@ static void upload_cc_unit( struct brw_context *brw )
/* Not really sure about this:
*/
if (brw->attribs.Stencil->WriteMask[0] ||
- (brw->attribs.Stencil->TestTwoSide && brw->attribs.Stencil->WriteMask[1]))
+ (brw->attribs.Stencil->_TestTwoSide &&
+ brw->attribs.Stencil->WriteMask[1]))
cc.cc0.stencil_write_enable = 1;
}
diff --git a/i965/brw_clip.h b/i965/brw_clip.h
index 49b2770..2a65697 100644
--- a/i965/brw_clip.h
+++ b/i965/brw_clip.h
@@ -42,7 +42,7 @@
* up polygon offset and flatshading at this point:
*/
struct brw_clip_prog_key {
- GLuint attrs:16;
+ GLuint attrs:32;
GLuint primitive:4;
GLuint nr_userclip:3;
GLuint do_flat_shading:1;
@@ -51,7 +51,7 @@ struct brw_clip_prog_key {
GLuint fill_ccw:2; /* includes cull information */
GLuint offset_cw:1;
GLuint offset_ccw:1;
- GLuint pad0:1;
+ GLuint pad0:17;
GLuint copy_bfc_cw:1;
GLuint copy_bfc_ccw:1;
diff --git a/i965/brw_clip_line.c b/i965/brw_clip_line.c
index 8318227..ff9003e 100644
--- a/i965/brw_clip_line.c
+++ b/i965/brw_clip_line.c
@@ -146,6 +146,15 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_clip_init_planes(c);
brw_clip_init_clipmask(c);
+ /* -ve rhw workaround */
+ if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw))) {
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+ brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
+ brw_imm_ud(1<<20));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ }
+
plane_loop = brw_DO(p, BRW_EXECUTE_1);
{
/* if (planemask & 1)
diff --git a/i965/brw_clip_state.c b/i965/brw_clip_state.c
index 37a25a9..b715aca 100644
--- a/i965/brw_clip_state.c
+++ b/i965/brw_clip_state.c
@@ -43,7 +43,8 @@ static void upload_clip_unit( struct brw_context *brw )
memset(&clip, 0, sizeof(clip));
/* CACHE_NEW_CLIP_PROG */
- clip.thread0.grf_reg_count = ((brw->clip.prog_data->total_grf-1) & ~15) / 16;
+ clip.thread0.grf_reg_count =
+ ALIGN(brw->clip.prog_data->total_grf, 16) / 16 - 1;
clip.thread0.kernel_start_pointer = brw->clip.prog_gs_offset >> 6;
clip.thread3.urb_entry_read_length = brw->clip.prog_data->urb_read_length;
clip.thread3.const_urb_entry_read_length = brw->clip.prog_data->curb_read_length;
@@ -55,7 +56,7 @@ static void upload_clip_unit( struct brw_context *brw )
/* BRW_NEW_URB_FENCE */
clip.thread4.nr_urb_entries = brw->urb.nr_clip_entries;
clip.thread4.urb_entry_allocation_size = brw->urb.vsize - 1;
- clip.thread4.max_threads = 0; /* Hmm, maybe the max is 1 or 2 threads */
+ clip.thread4.max_threads = 1; /* 2 threads */
if (INTEL_DEBUG & DEBUG_STATS)
clip.thread4.stats_enable = 1;
@@ -73,7 +74,7 @@ static void upload_clip_unit( struct brw_context *brw )
clip.clip5.vertex_position_space = BRW_CLIP_NDCSPACE;
clip.clip5.api_mode = BRW_CLIP_API_OGL;
- if (BRW_IS_IGD(brw))
+ if (BRW_IS_GM45(brw) || BRW_IS_G4X(brw))
clip.clip5.negative_w_clip_test = 1;
clip.clip6.clipper_viewport_state_ptr = 0;
diff --git a/i965/brw_clip_tri.c b/i965/brw_clip_tri.c
index 0fc7306..a602000 100644
--- a/i965/brw_clip_tri.c
+++ b/i965/brw_clip_tri.c
@@ -42,6 +42,20 @@
#include "brw_util.h"
#include "brw_clip.h"
+static struct brw_reg get_tmp( struct brw_clip_compile *c )
+{
+ struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
+
+ if (++c->last_tmp > c->prog_data.total_grf)
+ c->prog_data.total_grf = c->last_tmp;
+
+ return tmp;
+}
+
+static void release_tmps( struct brw_clip_compile *c )
+{
+ c->last_tmp = c->first_tmp;
+}
void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
@@ -435,15 +449,104 @@ static void maybe_do_clip_tri( struct brw_clip_compile *c )
brw_ENDIF(p, do_clip);
}
-
+static void brw_clip_test( struct brw_clip_compile *c )
+{
+ struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+ struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+ struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+ struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+
+ struct brw_reg v0 = get_tmp(c);
+ struct brw_reg v1 = get_tmp(c);
+ struct brw_reg v2 = get_tmp(c);
+
+ struct brw_indirect vt0 = brw_indirect(0, 0);
+ struct brw_indirect vt1 = brw_indirect(1, 0);
+ struct brw_indirect vt2 = brw_indirect(2, 0);
+
+ struct brw_compile *p = &c->func;
+
+ brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
+ brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
+ brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
+ brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
+ brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
+ brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
+
+ /* test nearz, xmin, ymin plane */
+ brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_XOR(p, t, t1, t2);
+ brw_XOR(p, t1, t2, t3);
+ brw_OR(p, t, t, t1);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+ get_element(t, 0), brw_imm_ud(0));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+ get_element(t, 1), brw_imm_ud(0));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+ get_element(t, 2), brw_imm_ud(0));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+ /* test farz, xmax, ymax plane */
+ brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+ brw_XOR(p, t, t1, t2);
+ brw_XOR(p, t1, t2, t3);
+ brw_OR(p, t, t, t1);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+ get_element(t, 0), brw_imm_ud(0));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+ get_element(t, 1), brw_imm_ud(0));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+ get_element(t, 2), brw_imm_ud(0));
+ brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+ release_tmps(c);
+}
void brw_emit_tri_clip( struct brw_clip_compile *c )
{
+ struct brw_instruction *neg_rhw;
+ struct brw_compile *p = &c->func;
brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
brw_clip_tri_init_vertices(c);
brw_clip_init_clipmask(c);
+ /* if -ve rhw workaround bit is set,
+ do cliptest */
+ if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw))) {
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+ brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
+ brw_imm_ud(1<<20));
+ neg_rhw = brw_IF(p, BRW_EXECUTE_1);
+ {
+ brw_clip_test(c);
+ }
+ brw_ENDIF(p, neg_rhw);
+ }
+
/* Can't push into do_clip_tri because with polygon (or quad)
* flatshading, need to apply the flatshade here because we don't
* respect the PV when converting to trifan for emit:
@@ -462,6 +565,3 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
*/
brw_clip_kill_thread(c);
}
-
-
-
diff --git a/i965/brw_clip_unfilled.c b/i965/brw_clip_unfilled.c
index 918e000..57ebf38 100644
--- a/i965/brw_clip_unfilled.c
+++ b/i965/brw_clip_unfilled.c
@@ -220,8 +220,8 @@ static void apply_one_offset( struct brw_clip_compile *c,
struct brw_indirect vert )
{
struct brw_compile *p = &c->func;
- struct brw_reg pos = deref_4f(vert, c->offset[VERT_RESULT_HPOS]);
- struct brw_reg z = get_element(pos, 2);
+ struct brw_reg z = deref_1f(vert, c->header_position_offset +
+ 2 * type_sz(BRW_REGISTER_TYPE_F));
brw_ADD(p, z, z, vec1(c->reg.offset));
}
diff --git a/i965/brw_clip_util.c b/i965/brw_clip_util.c
index 41d9b75..0ca2a67 100644
--- a/i965/brw_clip_util.c
+++ b/i965/brw_clip_util.c
@@ -272,6 +272,7 @@ void brw_clip_kill_thread(struct brw_clip_compile *c)
+
struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c )
{
return brw_address(c->reg.fixed_planes);
@@ -327,8 +328,7 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c )
/* Shift so that lowest outcode bit is rightmost:
*/
- brw_MOV(p, c->reg.planemask, incoming);
- brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(26));
+ brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26));
if (c->key.nr_userclip) {
struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD);
@@ -342,15 +342,5 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c )
release_tmp(c, tmp);
}
-
- if (!BRW_IS_IGD(p->brw)) {
- /* Test for -ve rhw workaround
- */
- brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
- brw_AND(p, vec1(brw_null_reg()), incoming, brw_imm_ud(1<<20));
- brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
- }
-
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
diff --git a/i965/brw_context.c b/i965/brw_context.c
index 397a9bd..e19d36e 100644
--- a/i965/brw_context.c
+++ b/i965/brw_context.c
@@ -44,6 +44,8 @@
#include "api_noop.h"
#include "vtxfmt.h"
+#include "shader/shader_api.h"
+
/***************************************
* Mesa's Driver Functions
***************************************/
@@ -60,12 +62,21 @@ static const struct dri_extension brw_extensions[] =
{ NULL, NULL }
};
+static void brwUseProgram(GLcontext *ctx, GLuint program)
+{
+ _mesa_use_program(ctx, program);
+}
+static void brwInitProgFuncs( struct dd_function_table *functions )
+{
+ functions->UseProgram = brwUseProgram;
+}
static void brwInitDriverFunctions( struct dd_function_table *functions )
{
intelInitDriverFunctions( functions );
brwInitTextureFuncs( functions );
brwInitFragProgFuncs( functions );
+ brwInitProgFuncs( functions );
}
diff --git a/i965/brw_curbe.c b/i965/brw_curbe.c
index 5bf0ed5..3343bed 100644
--- a/i965/brw_curbe.c
+++ b/i965/brw_curbe.c
@@ -305,7 +305,7 @@ static void upload_constant_buffer(struct brw_context *brw)
if (!brw_pool_alloc(pool,
bufsz,
- 6,
+ 1 << 6,
&brw->curbe.gs_offset)) {
_mesa_printf("out of GS memory for curbe\n");
assert(0);
diff --git a/i965/brw_defines.h b/i965/brw_defines.h
index 101828b..018da89 100644
--- a/i965/brw_defines.h
+++ b/i965/brw_defines.h
@@ -240,6 +240,8 @@
#define BRW_FRONTWINDING_CW 0
#define BRW_FRONTWINDING_CCW 1
+#define BRW_SPRITE_POINT_ENABLE 16
+
#define BRW_INDEX_BYTE 0
#define BRW_INDEX_WORD 1
#define BRW_INDEX_DWORD 2
@@ -816,7 +818,7 @@
#define CMD_STATE_BASE_ADDRESS 0x6101
#define CMD_STATE_INSN_POINTER 0x6102
#define CMD_PIPELINE_SELECT_965 0x6104
-#define CMD_PIPELINE_SELECT_IGD 0x6904
+#define CMD_PIPELINE_SELECT_GM45 0x6904
#define CMD_PIPELINED_STATE_POINTERS 0x7800
#define CMD_BINDING_TABLE_PTRS 0x7801
@@ -824,7 +826,7 @@
#define CMD_VERTEX_ELEMENT 0x7809
#define CMD_INDEX_BUFFER 0x780a
#define CMD_VF_STATISTICS_965 0x780b
-#define CMD_VF_STATISTICS_IGD 0x680b
+#define CMD_VF_STATISTICS_GM45 0x680b
#define CMD_DRAW_RECT 0x7900
#define CMD_BLEND_CONSTANT_COLOR 0x7901
@@ -848,9 +850,12 @@
#define R02_PRIM_END 0x1
#define R02_PRIM_START 0x2
-#define BRW_IS_IGD(brw) ((brw)->intel.intelScreen->deviceID == PCI_CHIP_IGD_GM)
-#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_IGD(brw)) ? CMD_PIPELINE_SELECT_IGD : CMD_PIPELINE_SELECT_965)
-#define CMD_VF_STATISTICS(brw) ((BRW_IS_IGD(brw)) ? CMD_VF_STATISTICS_IGD : CMD_VF_STATISTICS_965)
-#define URB_SIZES(brw) ((BRW_IS_IGD(brw)) ? 384 : 256) /* 512 bit unit */
+#define BRW_IS_GM45(brw) ((brw)->intel.intelScreen->deviceID == PCI_CHIP_GM45_GM)
+#define BRW_IS_G4X(brw) (((brw)->intel.intelScreen->deviceID == PCI_CHIP_IGD_E_G) || \
+ ((brw)->intel.intelScreen->deviceID == PCI_CHIP_G45_G) || \
+ ((brw)->intel.intelScreen->deviceID == PCI_CHIP_Q45_G))
+#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
+#define CMD_VF_STATISTICS(brw) ((BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
+#define URB_SIZES(brw) ((BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? 384 : 256) /* 512 bit unit */
#endif
diff --git a/i965/brw_draw_upload.c b/i965/brw_draw_upload.c
index 6150cac..133d8f4 100644
--- a/i965/brw_draw_upload.c
+++ b/i965/brw_draw_upload.c
@@ -291,7 +291,7 @@ static void get_space( struct brw_context *brw,
struct gl_buffer_object **vbo_return,
GLuint *offset_return )
{
- size = (size + 63) & ~63;
+ size = ALIGN(size, 64);
if (brw->vb.upload.offset + size > BRW_UPLOAD_INIT_SIZE)
wrap_buffers(brw, size);
@@ -593,6 +593,31 @@ void brw_upload_indices( struct brw_context *brw,
ib_size,
index_buffer->ptr,
bufferobj);
+ } else {
+ /* If the index buffer isn't aligned to its element size, we have to
+ * rebase it into a temporary.
+ */
+ if ((get_size(index_buffer->type) - 1) & offset) {
+ struct gl_buffer_object *vbo;
+ GLuint voffset;
+ GLubyte *map = ctx->Driver.MapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ GL_DYNAMIC_DRAW_ARB,
+ bufferobj);
+ map += offset;
+ get_space(brw, ib_size, &vbo, &voffset);
+
+ ctx->Driver.BufferSubData(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ voffset,
+ ib_size,
+ map,
+ vbo);
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj);
+
+ bufferobj = vbo;
+ offset = voffset;
+ }
}
/* Emit the indexbuffer packet:
diff --git a/i965/brw_eu.h b/i965/brw_eu.h
index 9d46aac..c138d15 100644
--- a/i965/brw_eu.h
+++ b/i965/brw_eu.h
@@ -335,14 +335,14 @@ static __inline struct brw_reg brw_imm_ud( GLuint ud )
static __inline struct brw_reg brw_imm_uw( GLushort uw )
{
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
- imm.dw1.ud = uw;
+ imm.dw1.ud = uw | (uw << 16);
return imm;
}
static __inline struct brw_reg brw_imm_w( GLshort w )
{
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
- imm.dw1.d = w;
+ imm.dw1.d = w | (w << 16);
return imm;
}
@@ -649,6 +649,16 @@ static __inline struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
}
+static __inline struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
+{
+ return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
+}
+
+static __inline struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
+{
+ return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
+}
+
static __inline struct brw_reg get_addr_reg(struct brw_indirect ptr)
{
return brw_address_reg(ptr.addr_subnr);
@@ -669,7 +679,10 @@ static __inline struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offse
return ptr;
}
-
+static __inline struct brw_instruction *current_insn( struct brw_compile *p)
+{
+ return &p->store[p->nr_insn];
+}
void brw_pop_insn_state( struct brw_compile *p );
void brw_push_insn_state( struct brw_compile *p );
@@ -809,9 +822,11 @@ void brw_ENDIF(struct brw_compile *p,
struct brw_instruction *brw_DO(struct brw_compile *p,
GLuint execute_size);
-void brw_WHILE(struct brw_compile *p,
+struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *patch_insn);
+struct brw_instruction *brw_BREAK(struct brw_compile *p);
+struct brw_instruction *brw_CONT(struct brw_compile *p);
/* Forward jumps:
*/
void brw_land_fwd_jump(struct brw_compile *p,
@@ -861,5 +876,6 @@ void brw_math_invert( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg src);
-
+void brw_set_src1( struct brw_instruction *insn,
+ struct brw_reg reg );
#endif
diff --git a/i965/brw_eu_emit.c b/i965/brw_eu_emit.c
index 1c717e4..d35b184 100644
--- a/i965/brw_eu_emit.c
+++ b/i965/brw_eu_emit.c
@@ -164,7 +164,7 @@ static void brw_set_src0( struct brw_instruction *insn,
}
-static void brw_set_src1( struct brw_instruction *insn,
+void brw_set_src1( struct brw_instruction *insn,
struct brw_reg reg )
{
assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
@@ -186,7 +186,7 @@ static void brw_set_src1( struct brw_instruction *insn,
* in the future:
*/
assert (reg.address_mode == BRW_ADDRESS_DIRECT);
- assert (reg.file == BRW_GENERAL_REGISTER_FILE);
+ //assert (reg.file == BRW_GENERAL_REGISTER_FILE);
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits3.da1.src1_subreg_nr = reg.subnr;
@@ -329,14 +329,14 @@ static void brw_set_sampler_message(struct brw_context *brw,
{
brw_set_src1(insn, brw_imm_d(0));
- if (BRW_IS_IGD(brw)) {
- insn->bits3.sampler_igd.binding_table_index = binding_table_index;
- insn->bits3.sampler_igd.sampler = sampler;
- insn->bits3.sampler_igd.msg_type = msg_type;
- insn->bits3.sampler_igd.response_length = response_length;
- insn->bits3.sampler_igd.msg_length = msg_length;
- insn->bits3.sampler_igd.end_of_thread = eot;
- insn->bits3.sampler_igd.msg_target = BRW_MESSAGE_TARGET_SAMPLER;
+ if (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) {
+ insn->bits3.sampler_gm45_g4x.binding_table_index = binding_table_index;
+ insn->bits3.sampler_gm45_g4x.sampler = sampler;
+ insn->bits3.sampler_gm45_g4x.msg_type = msg_type;
+ insn->bits3.sampler_gm45_g4x.response_length = response_length;
+ insn->bits3.sampler_gm45_g4x.msg_length = msg_length;
+ insn->bits3.sampler_gm45_g4x.end_of_thread = eot;
+ insn->bits3.sampler_gm45_g4x.msg_target = BRW_MESSAGE_TARGET_SAMPLER;
} else {
insn->bits3.sampler.binding_table_index = binding_table_index;
insn->bits3.sampler.sampler = sampler;
@@ -608,6 +608,34 @@ void brw_ENDIF(struct brw_compile *p,
}
}
+struct brw_instruction *brw_BREAK(struct brw_compile *p)
+{
+ struct brw_instruction *insn;
+ insn = next_insn(p, BRW_OPCODE_BREAK);
+ brw_set_dest(insn, brw_ip_reg());
+ brw_set_src0(insn, brw_ip_reg());
+ brw_set_src1(insn, brw_imm_d(0x0));
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = BRW_EXECUTE_8;
+ insn->header.mask_control = BRW_MASK_DISABLE;
+ insn->bits3.if_else.pad0 = 0;
+ return insn;
+}
+
+struct brw_instruction *brw_CONT(struct brw_compile *p)
+{
+ struct brw_instruction *insn;
+ insn = next_insn(p, BRW_OPCODE_CONTINUE);
+ brw_set_dest(insn, brw_ip_reg());
+ brw_set_src0(insn, brw_ip_reg());
+ brw_set_src1(insn, brw_imm_d(0x0));
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = BRW_EXECUTE_8;
+ insn->header.mask_control = BRW_MASK_DISABLE;
+ insn->bits3.if_else.pad0 = 0;
+ return insn;
+}
+
/* DO/WHILE loop:
*/
struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
@@ -619,13 +647,15 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
/* Override the defaults for this instruction:
*/
- brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
+ brw_set_dest(insn, brw_null_reg());
+ brw_set_src0(insn, brw_null_reg());
+ brw_set_src1(insn, brw_null_reg());
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = execute_size;
+ insn->header.predicate_control = BRW_PREDICATE_NONE;
/* insn->header.mask_control = BRW_MASK_ENABLE; */
+ insn->header.mask_control = BRW_MASK_DISABLE;
return insn;
}
@@ -633,7 +663,7 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
-void brw_WHILE(struct brw_compile *p,
+struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *do_insn)
{
struct brw_instruction *insn;
@@ -657,14 +687,16 @@ void brw_WHILE(struct brw_compile *p,
insn->header.execution_size = do_insn->header.execution_size;
assert(do_insn->header.opcode == BRW_OPCODE_DO);
- insn->bits3.if_else.jump_count = do_insn - insn;
+ insn->bits3.if_else.jump_count = do_insn - insn + 1;
insn->bits3.if_else.pop_count = 0;
insn->bits3.if_else.pad0 = 0;
}
/* insn->header.mask_control = BRW_MASK_ENABLE; */
+ insn->header.mask_control = BRW_MASK_DISABLE;
p->current->header.predicate_control = BRW_PREDICATE_NONE;
+ return insn;
}
diff --git a/i965/brw_gs.h b/i965/brw_gs.h
index 29a4e80..18a4537 100644
--- a/i965/brw_gs.h
+++ b/i965/brw_gs.h
@@ -40,11 +40,11 @@
#define MAX_GS_VERTS (4)
struct brw_gs_prog_key {
+ GLuint attrs:32;
GLuint primitive:4;
- GLuint attrs:16;
GLuint hint_gs_always:1;
GLuint need_gs_prog:1;
- GLuint pad:10;
+ GLuint pad:26;
};
struct brw_gs_compile {
diff --git a/i965/brw_gs_state.c b/i965/brw_gs_state.c
index 5826c01..5db4dd4 100644
--- a/i965/brw_gs_state.c
+++ b/i965/brw_gs_state.c
@@ -46,7 +46,8 @@ static void upload_gs_unit( struct brw_context *brw )
/* CACHE_NEW_GS_PROG */
if (brw->gs.prog_active) {
- gs.thread0.grf_reg_count = ((brw->gs.prog_data->total_grf-1) & ~15) / 16;
+ gs.thread0.grf_reg_count =
+ ALIGN(brw->gs.prog_data->total_grf, 16) / 16 - 1;
gs.thread0.kernel_start_pointer = brw->gs.prog_gs_offset >> 6;
gs.thread3.urb_entry_read_length = brw->gs.prog_data->urb_read_length;
}
diff --git a/i965/brw_metaops.c b/i965/brw_metaops.c
index 6e030f1..cd6d287 100644
--- a/i965/brw_metaops.c
+++ b/i965/brw_metaops.c
@@ -195,7 +195,7 @@ static void init_metaops_state( struct brw_context *brw )
vp_prog, strlen(vp_prog),
brw->metaops.vp);
- brw->metaops.attribs.VertexProgram->Current = brw->metaops.vp;
+ brw->metaops.attribs.VertexProgram->_Current = brw->metaops.vp;
brw->metaops.attribs.VertexProgram->_Enabled = GL_TRUE;
brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp;
diff --git a/i965/brw_misc_state.c b/i965/brw_misc_state.c
index fe476c9..8f23316 100644
--- a/i965/brw_misc_state.c
+++ b/i965/brw_misc_state.c
@@ -249,7 +249,7 @@ static void upload_depthbuffer(struct brw_context *brw)
memset(&bd, 0, sizeof(bd));
bd.header.bits.opcode = CMD_DEPTH_BUFFER;
- bd.header.bits.length = BRW_IS_IGD(brw) ? (sizeof(bd)/4-2) : (sizeof(bd)/4-3);
+ bd.header.bits.length = (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? (sizeof(bd)/4-2) : (sizeof(bd)/4-3);
bd.dword1.bits.pitch = (region->pitch * region->cpp) - 1;
switch (region->cpp) {
@@ -366,7 +366,7 @@ static void upload_aa_line_parameters(struct brw_context *brw)
{
struct brw_aa_line_parameters balp;
- if (!BRW_IS_IGD(brw))
+ if (!(BRW_IS_GM45(brw) || BRW_IS_G4X(brw)))
return;
/* use legacy aa line coverage computation */
diff --git a/i965/brw_program.c b/i965/brw_program.c
index 752fe49..389fd89 100644
--- a/i965/brw_program.c
+++ b/i965/brw_program.c
@@ -125,6 +125,9 @@ static void brwProgramStringNotify( GLcontext *ctx,
struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program;
if (p == vp)
brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
+ if (p->program.IsPositionInvariant) {
+ _mesa_insert_mvp_code(ctx, &p->program);
+ }
p->id = brw->program_id++;
p->param_state = p->program.Base.Parameters->StateFlags;
diff --git a/i965/brw_sf.c b/i965/brw_sf.c
index 6dcfa62..83e2314 100644
--- a/i965/brw_sf.c
+++ b/i965/brw_sf.c
@@ -74,6 +74,11 @@ static void compile_sf_prog( struct brw_context *brw,
if (c.key.attrs & (1<<i)) {
c.attr_to_idx[i] = idx;
c.idx_to_attr[idx] = i;
+ if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) {
+ c.point_attrs[i].CoordReplace =
+ brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0];
+ } else
+ c.point_attrs[i].CoordReplace = GL_FALSE;
idx++;
}
@@ -90,7 +95,10 @@ static void compile_sf_prog( struct brw_context *brw,
break;
case SF_POINTS:
c.nr_verts = 1;
- brw_emit_point_setup( &c, GL_TRUE );
+ if (key->do_point_sprite)
+ brw_emit_point_sprite_setup( &c, GL_TRUE );
+ else
+ brw_emit_point_setup( &c, GL_TRUE );
break;
case SF_UNFILLED_TRIS:
c.nr_verts = 3;
@@ -162,7 +170,8 @@ static void upload_sf_prog( struct brw_context *brw )
break;
}
-
+ key.do_point_sprite = brw->attribs.Point->PointSprite;
+ key.SpriteOrigin = brw->attribs.Point->SpriteOrigin;
/* _NEW_LIGHT */
key.do_flat_shading = (brw->attribs.Light->ShadeModel == GL_FLAT);
key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide);
@@ -179,7 +188,7 @@ static void upload_sf_prog( struct brw_context *brw )
const struct brw_tracked_state brw_sf_prog = {
.dirty = {
- .mesa = (_NEW_LIGHT|_NEW_POLYGON),
+ .mesa = (_NEW_LIGHT|_NEW_POLYGON|_NEW_POINT),
.brw = (BRW_NEW_REDUCED_PRIMITIVE),
.cache = CACHE_NEW_VS_PROG
},
diff --git a/i965/brw_sf.h b/i965/brw_sf.h
index b321cda..1aadc71 100644
--- a/i965/brw_sf.h
+++ b/i965/brw_sf.h
@@ -45,14 +45,19 @@
#define SF_UNFILLED_TRIS 3
struct brw_sf_prog_key {
+ GLuint attrs:32;
GLuint primitive:2;
GLuint do_twoside_color:1;
GLuint do_flat_shading:1;
- GLuint attrs:16;
GLuint frontface_ccw:1;
- GLuint pad:11;
+ GLuint do_point_sprite:1;
+ GLuint pad:10;
+ GLenum SpriteOrigin;
};
+struct brw_sf_point_tex {
+ GLboolean CoordReplace;
+};
struct brw_sf_compile {
struct brw_compile func;
@@ -94,12 +99,14 @@ struct brw_sf_compile {
GLubyte attr_to_idx[VERT_RESULT_MAX];
GLubyte idx_to_attr[VERT_RESULT_MAX];
+ struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX];
};
void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate );
void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate );
void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate );
+void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate );
void brw_emit_anyprim_setup( struct brw_sf_compile *c );
#endif
diff --git a/i965/brw_sf_emit.c b/i965/brw_sf_emit.c
index 94be815..2f06cc5 100644
--- a/i965/brw_sf_emit.c
+++ b/i965/brw_sf_emit.c
@@ -503,6 +503,90 @@ void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
}
}
+void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate )
+{
+ struct brw_compile *p = &c->func;
+ GLuint i;
+
+ c->nr_verts = 1;
+
+ if (allocate)
+ alloc_regs(c);
+
+ copy_z_inv_w(c);
+ for (i = 0; i < c->nr_setup_regs; i++)
+ {
+ struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]];
+ struct brw_reg a0 = offset(c->vert[0], i);
+ GLushort pc, pc_persp, pc_linear;
+ GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+
+ if (pc_persp)
+ {
+ if (!tex->CoordReplace) {
+ brw_set_predicate_control_flag_value(p, pc_persp);
+ brw_MUL(p, a0, a0, c->inv_w[0]);
+ }
+ }
+
+ if (tex->CoordReplace) {
+ /* Caculate 1.0/PointWidth */
+ brw_math(&c->func,
+ c->tmp,
+ BRW_MATH_FUNCTION_INV,
+ BRW_MATH_SATURATE_NONE,
+ 0,
+ c->dx0,
+ BRW_MATH_DATA_SCALAR,
+ BRW_MATH_PRECISION_FULL);
+
+ if (c->key.SpriteOrigin == GL_LOWER_LEFT) {
+ brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
+ brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
+ brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0]));
+ brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
+ } else {
+ brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
+ brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
+ brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]);
+ brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
+ }
+ } else {
+ brw_MOV(p, c->m1Cx, brw_imm_ud(0));
+ brw_MOV(p, c->m2Cy, brw_imm_ud(0));
+ }
+
+ {
+ brw_set_predicate_control_flag_value(p, pc);
+ if (tex->CoordReplace) {
+ if (c->key.SpriteOrigin == GL_LOWER_LEFT) {
+ brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
+ brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
+ }
+ else
+ brw_MOV(p, c->m3C0, brw_imm_f(0.0));
+ } else {
+ brw_MOV(p, c->m3C0, a0); /* constant value */
+ }
+
+ /* Copy m0..m3 to URB.
+ */
+ brw_urb_WRITE(p,
+ brw_null_reg(),
+ 0,
+ brw_vec8_grf(0, 0),
+ 0, /* allocate */
+ 1, /* used */
+ 4, /* msg len */
+ 0, /* response len */
+ last, /* eot */
+ last, /* writes complete */
+ i*4, /* urb destination offset */
+ BRW_URB_SWIZZLE_TRANSPOSE);
+ }
+ }
+}
+
/* Points setup - several simplifications as all attributes are
* constant across the face of the point (point sprites excluded!)
*/
@@ -569,6 +653,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
+ struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0);
struct brw_reg primmask;
struct brw_instruction *jmp;
struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
@@ -623,6 +708,19 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
}
brw_land_fwd_jump(p, jmp);
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+ brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
+ jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
+ {
+ saveflag = p->flag_value;
+ brw_push_insn_state(p);
+ brw_emit_point_sprite_setup( c, GL_FALSE );
+ brw_pop_insn_state(p);
+ p->flag_value = saveflag;
+ /* note - thread killed in subroutine */
+ }
+ brw_land_fwd_jump(p, jmp);
+
brw_emit_point_setup( c, GL_FALSE );
}
diff --git a/i965/brw_sf_state.c b/i965/brw_sf_state.c
index 2fd75a0..7445d59 100644
--- a/i965/brw_sf_state.c
+++ b/i965/brw_sf_state.c
@@ -38,6 +38,8 @@
static void upload_sf_vp(struct brw_context *brw)
{
+ GLcontext *ctx = &brw->intel.ctx;
+ const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
struct brw_sf_viewport sfv;
memset(&sfv, 0, sizeof(sfv));
@@ -47,14 +49,14 @@ static void upload_sf_vp(struct brw_context *brw)
/* _NEW_VIEWPORT, BRW_NEW_METAOPS */
if (!brw->metaops.active) {
- const GLfloat *v = brw->intel.ctx.Viewport._WindowMap.m;
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
sfv.viewport.m00 = v[MAT_SX];
sfv.viewport.m11 = - v[MAT_SY];
- sfv.viewport.m22 = v[MAT_SZ] * brw->intel.depth_scale;
+ sfv.viewport.m22 = v[MAT_SZ] * depth_scale;
sfv.viewport.m30 = v[MAT_TX];
sfv.viewport.m31 = - v[MAT_TY] + brw->intel.driDrawable->h;
- sfv.viewport.m32 = v[MAT_TZ] * brw->intel.depth_scale;
+ sfv.viewport.m32 = v[MAT_TZ] * depth_scale;
}
else {
sfv.viewport.m00 = 1;
@@ -118,7 +120,7 @@ static void upload_sf_unit( struct brw_context *brw )
memset(&sf, 0, sizeof(sf));
/* CACHE_NEW_SF_PROG */
- sf.thread0.grf_reg_count = ((brw->sf.prog_data->total_grf-1) & ~15) / 16;
+ sf.thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
sf.thread0.kernel_start_pointer = brw->sf.prog_gs_offset >> 6;
sf.thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length;
@@ -184,6 +186,7 @@ static void upload_sf_unit( struct brw_context *brw )
/* _NEW_POINT */
sf.sf6.point_rast_rule = 1; /* opengl conventions */
sf.sf7.point_size = brw->attribs.Point->_Size * (1<<3);
+ sf.sf7.sprite_point = brw->attribs.Point->PointSprite;
sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated;
sf.sf7.aa_line_distance_mode = 0;
diff --git a/i965/brw_state_cache.c b/i965/brw_state_cache.c
index 71c6938..5739c5c 100644
--- a/i965/brw_state_cache.c
+++ b/i965/brw_state_cache.c
@@ -149,7 +149,7 @@ GLuint brw_upload_cache( struct brw_cache *cache,
GLuint hash = hash_key(key, key_size);
void *tmp = _mesa_malloc(key_size + cache->aux_size);
- if (!brw_pool_alloc(cache->pool, data_size, 6, &offset)) {
+ if (!brw_pool_alloc(cache->pool, data_size, 1 << 6, &offset)) {
/* Should not be possible:
*/
_mesa_printf("brw_pool_alloc failed\n");
diff --git a/i965/brw_state_pool.c b/i965/brw_state_pool.c
index b9926f2..cf7cdd0 100644
--- a/i965/brw_state_pool.c
+++ b/i965/brw_state_pool.c
@@ -41,10 +41,9 @@ GLboolean brw_pool_alloc( struct brw_mem_pool *pool,
GLuint align,
GLuint *offset_return)
{
- GLuint align_mask = (1<<align)-1;
- GLuint fixup = ((pool->offset + align_mask) & ~align_mask) - pool->offset;
+ GLuint fixup = ALIGN(pool->offset, align) - pool->offset;
- size = (size + 3) & ~3;
+ size = ALIGN(size, 4);
if (pool->offset + fixup + size >= pool->size) {
_mesa_printf("%s failed\n", __FUNCTION__);
diff --git a/i965/brw_structs.h b/i965/brw_structs.h
index a799122..ee0e309 100644
--- a/i965/brw_structs.h
+++ b/i965/brw_structs.h
@@ -1362,7 +1362,7 @@ struct brw_instruction
GLuint msg_target:4;
GLuint pad1:3;
GLuint end_of_thread:1;
- } sampler_igd;
+ } sampler_gm45_g4x;
struct brw_urb_immediate urb;
diff --git a/i965/brw_tex.c b/i965/brw_tex.c
index 9d4b986..ad29316 100644
--- a/i965/brw_tex.c
+++ b/i965/brw_tex.c
@@ -154,13 +154,19 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgb_dxt1;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgba_dxt1;
+
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ return &_mesa_texformat_rgba_dxt3;
+
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgb_dxt1; /* there is no rgba support? */
+ return &_mesa_texformat_rgba_dxt5;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
@@ -168,6 +174,25 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
case GL_DEPTH_COMPONENT32:
return &_mesa_texformat_z16;
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+ return &_mesa_texformat_srgba8;
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ return &_mesa_texformat_srgb_dxt1;
+
default:
fprintf(stderr, "unexpected texture format %s in %s\n",
_mesa_lookup_enum_by_nr(internalFormat),
diff --git a/i965/brw_tex_layout.c b/i965/brw_tex_layout.c
index d4888a4..427a132 100644
--- a/i965/brw_tex_layout.c
+++ b/i965/brw_tex_layout.c
@@ -37,7 +37,6 @@
#include "intel_tex_layout.h"
#include "macros.h"
-
GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_tree *mt )
{
/* XXX: these vary depending on image format:
@@ -53,11 +52,20 @@ GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_t
GLuint pack_x_pitch, pack_x_nr;
GLuint pack_y_pitch;
GLuint level;
+ GLuint align_h = 2;
+ GLuint align_w = 4;
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
mt->total_height = 0;
+
+ if (mt->compressed) {
+ align_w = intel_compressed_alignment(mt->internal_format);
+ mt->pitch = ALIGN(width, align_w);
+ pack_y_pitch = (height + 3) / 4;
+ } else {
+ mt->pitch = ALIGN(mt->width0 * mt->cpp, 4) / mt->cpp;
+ pack_y_pitch = ALIGN(mt->height0, align_h);
+ }
- pack_y_pitch = MAX2(mt->height0, 2);
pack_x_pitch = mt->pitch;
pack_x_nr = 1;
@@ -83,20 +91,30 @@ GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_t
mt->total_height += y;
-
- if (pack_x_pitch > 4) {
- pack_x_pitch >>= 1;
- pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= mt->pitch);
- }
-
- if (pack_y_pitch > 2) {
- pack_y_pitch >>= 1;
- }
-
width = minify(width);
height = minify(height);
depth = minify(depth);
+
+ if (mt->compressed) {
+ pack_y_pitch = (height + 3) / 4;
+
+ if (pack_x_pitch > ALIGN(width, align_w)) {
+ pack_x_pitch = ALIGN(width, align_w);
+ pack_x_nr <<= 1;
+ }
+ } else {
+ if (pack_x_pitch > 4) {
+ pack_x_pitch >>= 1;
+ pack_x_nr <<= 1;
+ assert(pack_x_pitch * pack_x_nr <= mt->pitch);
+ }
+
+ if (pack_y_pitch > 2) {
+ pack_y_pitch >>= 1;
+ pack_y_pitch = ALIGN(pack_y_pitch, align_h);
+ }
+ }
+
}
break;
}
diff --git a/i965/brw_urb.c b/i965/brw_urb.c
index 4ca6e99..76d0c29 100644
--- a/i965/brw_urb.c
+++ b/i965/brw_urb.c
@@ -53,7 +53,7 @@ static const struct {
GLuint min_entry_size;
GLuint max_entry_size;
} limits[CS+1] = {
- { 8, 32, 1, 5 }, /* vs */
+ { 16, 32, 1, 5 }, /* vs */
{ 4, 8, 1, 5 }, /* gs */
{ 6, 8, 1, 5 }, /* clp */
{ 1, 8, 1, 12 }, /* sf */
diff --git a/i965/brw_vs.h b/i965/brw_vs.h
index fdb5785..36636b5 100644
--- a/i965/brw_vs.h
+++ b/i965/brw_vs.h
@@ -67,6 +67,12 @@ struct brw_vs_compile {
struct brw_reg r1;
struct brw_reg regs[PROGRAM_ADDRESS+1][128];
struct brw_reg tmp;
+ struct brw_reg stack;
+
+ struct {
+ GLboolean used_in_src;
+ struct brw_reg reg;
+ } output_regs[128];
struct brw_reg userplane[6];
diff --git a/i965/brw_vs_emit.c b/i965/brw_vs_emit.c
index c38e998..6d41205 100644
--- a/i965/brw_vs_emit.c
+++ b/i965/brw_vs_emit.c
@@ -134,6 +134,16 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
WRITEMASK_X);
reg++;
}
+
+ for (i = 0; i < 128; i++) {
+ if (c->output_regs[i].used_in_src) {
+ c->output_regs[i].reg = brw_vec8_grf(reg, 0);
+ reg++;
+ }
+ }
+
+ c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
+ reg += 2;
/* Some opcodes need an internal temporary:
@@ -213,57 +223,65 @@ static void unalias2( struct brw_vs_compile *c,
}
}
+static void emit_sop( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1,
+ GLuint cond)
+{
+ brw_MOV(p, dst, brw_imm_f(0.0f));
+ brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
+ brw_MOV(p, dst, brw_imm_f(1.0f));
+ brw_set_predicate_control_flag_value(p, 0xff);
+}
+static void emit_seq( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+}
-
+static void emit_sne( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+}
static void emit_slt( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- /* Could be done with an if/else/endif, but this method uses half
- * the instructions. Note that we are careful to reference the
- * arguments before writing the dest. That means we emit the
- * instructions in an odd order and have to play with the flag
- * values.
- */
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(1.0));
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+}
- /* Where the test succeeded, overwite with zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(0.0));
- brw_pop_insn_state(p);
+static void emit_sle( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
}
+static void emit_sgt( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+}
static void emit_sge( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(0));
-
- /* Where the test succeeded, overwite with 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(1.0));
- brw_pop_insn_state(p);
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
}
-
static void emit_max( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
@@ -592,9 +610,13 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
- case PROGRAM_STATE_VAR:
assert(c->regs[file][index].nr != 0);
return c->regs[file][index];
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_UNIFORM:
+ assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
+ return c->regs[PROGRAM_STATE_VAR][index];
case PROGRAM_ADDRESS:
assert(index == 0);
return c->regs[file][index];
@@ -668,28 +690,28 @@ static void emit_arl( struct brw_vs_compile *c,
* account.
*/
static struct brw_reg get_arg( struct brw_vs_compile *c,
- struct prog_src_register src )
+ struct prog_src_register *src )
{
struct brw_reg reg;
- if (src.File == PROGRAM_UNDEFINED)
+ if (src->File == PROGRAM_UNDEFINED)
return brw_null_reg();
- if (src.RelAddr)
- reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src.Index);
+ if (src->RelAddr)
+ reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index);
else
- reg = get_reg(c, src.File, src.Index);
+ reg = get_reg(c, src->File, src->Index);
/* Convert 3-bit swizzle to 2-bit.
*/
- reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src.Swizzle, 0),
- GET_SWZ(src.Swizzle, 1),
- GET_SWZ(src.Swizzle, 2),
- GET_SWZ(src.Swizzle, 3));
+ reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0),
+ GET_SWZ(src->Swizzle, 1),
+ GET_SWZ(src->Swizzle, 2),
+ GET_SWZ(src->Swizzle, 3));
/* Note this is ok for non-swizzle instructions:
*/
- reg.negate = src.NegateBase ? 1 : 0;
+ reg.negate = src->NegateBase ? 1 : 0;
return reg;
}
@@ -845,7 +867,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
* Later, clipping will detect ucp[6] and ensure the primitive is
* clipped against all fixed planes.
*/
- if (!BRW_IS_IGD(p->brw) && !c->key.know_w_is_one) {
+ if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw)) && !c->key.know_w_is_one) {
brw_CMP(p,
vec8(brw_null_reg()),
BRW_CONDITIONAL_L,
@@ -891,17 +913,50 @@ static void emit_vertex_write( struct brw_vs_compile *c)
}
-
-
+static void
+post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
+{
+ GLuint nr_insns = c->vp->program.Base.NumInstructions;
+ GLuint insn, target_insn;
+ struct prog_instruction *inst1, *inst2;
+ struct brw_instruction *brw_inst1, *brw_inst2;
+ int offset;
+ for (insn = 0; insn < nr_insns; insn++) {
+ inst1 = &c->vp->program.Base.Instructions[insn];
+ brw_inst1 = inst1->Data;
+ switch (inst1->Opcode) {
+ case OPCODE_CAL:
+ case OPCODE_BRA:
+ target_insn = inst1->BranchTarget;
+ inst2 = &c->vp->program.Base.Instructions[target_insn];
+ brw_inst2 = inst2->Data;
+ offset = brw_inst2 - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ case OPCODE_END:
+ offset = end_inst - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ default:
+ break;
+ }
+ }
+}
/* Emit the fragment program instructions here.
*/
-void brw_vs_emit( struct brw_vs_compile *c )
+void brw_vs_emit(struct brw_vs_compile *c )
{
+#define MAX_IFSN 32
struct brw_compile *p = &c->func;
GLuint nr_insns = c->vp->program.Base.NumInstructions;
- GLuint insn;
+ GLuint insn, if_insn = 0;
+ struct brw_instruction *end_inst;
+ struct brw_instruction *if_inst[MAX_IFSN];
+ struct brw_indirect stack_index = brw_indirect(0, 0);
+ GLuint index;
+ GLuint file;
if (INTEL_DEBUG & DEBUG_VS) {
_mesa_printf("\n\n\nvs-emit:\n");
@@ -912,9 +967,24 @@ void brw_vs_emit( struct brw_vs_compile *c )
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_access_mode(p, BRW_ALIGN_16);
+ /* Message registers can't be read, so copy the output into GRF register
+ if they are used in source registers */
+ for (insn = 0; insn < nr_insns; insn++) {
+ GLuint i;
+ struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
+ for (i = 0; i < 3; i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ GLuint index = src->Index;
+ GLuint file = src->File;
+ if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)
+ c->output_regs[index].used_in_src = GL_TRUE;
+ }
+ }
+
/* Static register allocation
*/
brw_vs_alloc_regs(c);
+ brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
for (insn = 0; insn < nr_insns; insn++) {
@@ -924,17 +994,29 @@ void brw_vs_emit( struct brw_vs_compile *c )
/* Get argument regs. SWZ is special and does this itself.
*/
+ inst->Data = &p->store[p->nr_insn];
if (inst->Opcode != OPCODE_SWZ)
- for (i = 0; i < 3; i++)
- args[i] = get_arg(c, inst->SrcReg[i]);
+ for (i = 0; i < 3; i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ index = src->Index;
+ file = src->File;
+ if (file == PROGRAM_OUTPUT&&c->output_regs[index].used_in_src)
+ args[i] = c->output_regs[index].reg;
+ else
+ args[i] = get_arg(c, src);
+ }
/* Get dest regs. Note that it is possible for a reg to be both
* dst and arg, given the static allocation of registers. So
* care needs to be taken emitting multi-operation instructions.
- */
- dst = get_dst(c, inst->DstReg);
+ */
+ index = inst->DstReg.Index;
+ file = inst->DstReg.File;
+ if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
+ dst = c->output_regs[index].reg;
+ else
+ dst = get_dst(c, inst->DstReg);
-
switch (inst->Opcode) {
case OPCODE_ABS:
brw_MOV(p, dst, brw_abs(args[0]));
@@ -1003,12 +1085,25 @@ void brw_vs_emit( struct brw_vs_compile *c )
case OPCODE_RSQ:
emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
break;
+
+ case OPCODE_SEQ:
+ emit_seq(p, dst, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, args[0], args[1]);
break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, args[0], args[1]);
+ break;
case OPCODE_SLT:
emit_slt(p, dst, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, args[0], args[1]);
+ break;
case OPCODE_SUB:
brw_ADD(p, dst, args[0], negate(args[1]));
break;
@@ -1021,21 +1116,60 @@ void brw_vs_emit( struct brw_vs_compile *c )
case OPCODE_XPD:
emit_xpd(p, dst, args[0], args[1]);
break;
+ case OPCODE_IF:
+ assert(if_insn < MAX_IFSN);
+ if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_ELSE:
+ if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
+ break;
+ case OPCODE_ENDIF:
+ assert(if_insn > 0);
+ brw_ENDIF(p, if_inst[--if_insn]);
+ break;
+ case OPCODE_BRA:
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ brw_set_predicate_control_flag_value(p, 0xff);
+ break;
+ case OPCODE_CAL:
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_ADD(p, deref_1d(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(4));
+ inst->Data = &p->store[p->nr_insn];
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
+ case OPCODE_RET:
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(-4));
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_MOV(p, brw_ip_reg(), deref_1d(stack_index, 0));
+ brw_set_access_mode(p, BRW_ALIGN_16);
case OPCODE_END:
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
case OPCODE_PRINT:
+ case OPCODE_BGNSUB:
+ case OPCODE_ENDSUB:
break;
default:
+ _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
break;
}
+ if (inst->DstReg.File == PROGRAM_OUTPUT
+ &&inst->DstReg.Index != VERT_RESULT_HPOS
+ &&c->output_regs[inst->DstReg.Index].used_in_src)
+ brw_MOV(p, get_dst(c, inst->DstReg), dst);
+
release_tmps(c);
}
+ end_inst = &p->store[p->nr_insn];
emit_vertex_write(c);
-
+ post_vs_emit(c, end_inst);
+ for (insn = 0; insn < nr_insns; insn++)
+ c->vp->program.Base.Instructions[insn].Data = NULL;
}
-
-
-
-
-
diff --git a/i965/brw_vs_state.c b/i965/brw_vs_state.c
index c225bf8..f561979 100644
--- a/i965/brw_vs_state.c
+++ b/i965/brw_vs_state.c
@@ -44,7 +44,7 @@ static void upload_vs_unit( struct brw_context *brw )
/* CACHE_NEW_VS_PROG */
vs.thread0.kernel_start_pointer = brw->vs.prog_gs_offset >> 6;
- vs.thread0.grf_reg_count = ((brw->vs.prog_data->total_grf-1) & ~15) / 16;
+ vs.thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs.thread3.urb_entry_read_length = brw->vs.prog_data->urb_read_length;
vs.thread3.const_urb_entry_read_length = brw->vs.prog_data->curb_read_length;
vs.thread3.dispatch_grf_start_reg = 1;
diff --git a/i965/brw_vs_tnl.c b/i965/brw_vs_tnl.c
index 14483b3..c06ef5c 100644
--- a/i965/brw_vs_tnl.c
+++ b/i965/brw_vs_tnl.c
@@ -524,10 +524,13 @@ static void emit_op3fn(struct tnl_program *p,
GLuint nr = p->program->Base.NumInstructions++;
if (nr >= p->nr_instructions) {
+ int new_nr_instructions = p->nr_instructions * 2;
+
p->program->Base.Instructions =
_mesa_realloc(p->program->Base.Instructions,
sizeof(struct prog_instruction) * p->nr_instructions,
- sizeof(struct prog_instruction) * (p->nr_instructions *= 2));
+ sizeof(struct prog_instruction) * new_nr_instructions);
+ p->nr_instructions = new_nr_instructions;
}
{
@@ -1167,6 +1170,11 @@ static void build_fog( struct tnl_program *p )
}
else {
input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
+ if (p->state->fog_option &&
+ p->state->tnl_do_vertex_fog)
+ input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
+ else
+ input = register_input(p, VERT_ATTRIB_FOG);
}
if (p->state->fog_option &&
@@ -1575,7 +1583,7 @@ static void update_tnl_program( struct brw_context *brw )
struct gl_vertex_program *old = brw->tnl_program;
/* _NEW_PROGRAM */
- if (brw->attribs.VertexProgram->_Enabled)
+ if (brw->attribs.VertexProgram->_Current)
return;
/* Grab all the relevent state and put it in a single structure:
@@ -1622,7 +1630,8 @@ const struct brw_tracked_state brw_tnl_vertprog = {
_NEW_FOG |
_NEW_HINT |
_NEW_POINT |
- _NEW_TEXTURE),
+ _NEW_TEXTURE |
+ _NEW_TEXTURE_MATRIX),
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_INPUT_VARYING),
.cache = 0
@@ -1638,8 +1647,8 @@ static void update_active_vertprog( struct brw_context *brw )
const struct gl_vertex_program *prev = brw->vertex_program;
/* NEW_PROGRAM */
- if (brw->attribs.VertexProgram->_Enabled) {
- brw->vertex_program = brw->attribs.VertexProgram->Current;
+ if (brw->attribs.VertexProgram->_Current) {
+ brw->vertex_program = brw->attribs.VertexProgram->_Current;
}
else {
/* BRW_NEW_TNL_PROGRAM */
diff --git a/i965/brw_wm.c b/i965/brw_wm.c
index f80ba17..b2ad0f7 100644
--- a/i965/brw_wm.c
+++ b/i965/brw_wm.c
@@ -29,7 +29,7 @@
* Keith Whitwell <keith@tungstengraphics.com>
*/
-
+#include "main/texformat.h"
#include "brw_context.h"
#include "brw_util.h"
#include "brw_wm.h"
@@ -66,7 +66,11 @@ GLuint brw_wm_nr_args( GLuint opcode )
case OPCODE_POW:
case OPCODE_SUB:
case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SLE:
case OPCODE_SLT:
+ case OPCODE_SEQ:
+ case OPCODE_SNE:
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
@@ -150,46 +154,50 @@ static void do_wm_prog( struct brw_context *brw,
c->fp = fp;
c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
- /* Augment fragment program. Add instructions for pre- and
- * post-fragment-program tasks such as interpolation and fogging.
- */
- brw_wm_pass_fp(c);
+ if (brw_wm_is_glsl(&c->fp->program)) {
+ brw_wm_glsl_emit(brw, c);
+ } else {
+ /* Augment fragment program. Add instructions for pre- and
+ * post-fragment-program tasks such as interpolation and fogging.
+ */
+ brw_wm_pass_fp(c);
- /* Translate to intermediate representation. Build register usage
- * chains.
- */
- brw_wm_pass0(c);
-
- /* Dead code removal.
- */
- brw_wm_pass1(c);
-
- /* Hal optimization
- */
- brw_wm_pass_hal (c);
+ /* Translate to intermediate representation. Build register usage
+ * chains.
+ */
+ brw_wm_pass0(c);
+
+ /* Dead code removal.
+ */
+ brw_wm_pass1(c);
+
+ /* Hal optimization
+ */
+ brw_wm_pass_hal (c);
- /* Register allocation.
- */
- c->grf_limit = BRW_WM_MAX_GRF/2;
-
- /* This is where we start emitting gen4 code:
- */
- brw_init_compile(brw, &c->func);
-
- brw_wm_pass2(c);
-
- c->prog_data.total_grf = c->max_wm_grf;
- if (c->last_scratch) {
- c->prog_data.total_scratch =
- c->last_scratch + 0x40;
- } else {
- c->prog_data.total_scratch = 0;
+ /* Register allocation.
+ */
+ c->grf_limit = BRW_WM_MAX_GRF/2;
+
+ /* This is where we start emitting gen4 code:
+ */
+ brw_init_compile(brw, &c->func);
+
+ brw_wm_pass2(c);
+
+ c->prog_data.total_grf = c->max_wm_grf;
+ if (c->last_scratch) {
+ c->prog_data.total_scratch =
+ c->last_scratch + 0x40;
+ } else {
+ c->prog_data.total_scratch = 0;
+ }
+
+ /* Emit GEN4 code.
+ */
+ brw_wm_emit(c);
}
- /* Emit GEN4 code.
- */
- brw_wm_emit(c);
-
/* get the program
*/
program = brw_get_program(&c->func, &program_size);
@@ -242,7 +250,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
if (brw->attribs.Stencil->WriteMask[0] ||
- (brw->attribs.Stencil->TestTwoSide && brw->attribs.Stencil->WriteMask[1]))
+ (brw->attribs.Stencil->_TestTwoSide &&
+ brw->attribs.Stencil->WriteMask[1]))
lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
}
@@ -284,7 +293,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* BRW_NEW_WM_INPUT_DIMENSIONS */
- key->projtex_mask = brw->wm.input_size_masks[4-1];
+ key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS);
/* _NEW_LIGHT */
key->flat_shade = (brw->attribs.Light->ShadeModel == GL_FLAT);
@@ -301,11 +310,38 @@ static void brw_wm_populate_key( struct brw_context *brw,
key->shadowtex_mask |= 1<<i;
}
- if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA)
+ if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) {
key->yuvtex_mask |= 1<<i;
+ if (t->Image[0][t->BaseLevel]->TexFormat->MesaFormat ==
+ MESA_FORMAT_YCBCR)
+ key->yuvtex_swap_mask |= 1<< i;
+ }
}
}
-
+
+ /* _NEW_BUFFERS */
+ /*
+ * Include the draw buffer origin and height so that we can calculate
+ * fragment position values relative to the bottom left of the drawable,
+ * from the incoming screen origin relative position we get as part of our
+ * payload.
+ *
+ * We could avoid recompiling by including this as a constant referenced by
+ * our program, but if we were to do that it would also be nice to handle
+ * getting that constant updated at batchbuffer submit time (when we
+ * hold the lock and know where the buffer really is) rather than at emit
+ * time when we don't hold the lock and are just guessing. We could also
+ * just avoid using this as key data if the program doesn't use
+ * fragment.position.
+ *
+ * This pretty much becomes moot with DRI2 and redirected buffers anyway,
+ * as our origins will always be zero then.
+ */
+ if (brw->intel.driDrawable != NULL) {
+ key->origin_x = brw->intel.driDrawable->x;
+ key->origin_y = brw->intel.driDrawable->y;
+ key->drawable_height = brw->intel.driDrawable->h;
+ }
/* Extra info:
*/
@@ -344,6 +380,7 @@ const struct brw_tracked_state brw_wm_prog = {
_NEW_POLYGON |
_NEW_LINE |
_NEW_LIGHT |
+ _NEW_BUFFERS |
_NEW_TEXTURE),
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_WM_INPUT_DIMENSIONS |
diff --git a/i965/brw_wm.h b/i965/brw_wm.h
index f5fddfd..9fb231d 100644
--- a/i965/brw_wm.h
+++ b/i965/brw_wm.h
@@ -69,9 +69,12 @@ struct brw_wm_prog_key {
GLuint runtime_check_aads_emit:1;
GLuint yuvtex_mask:8;
- GLuint pad1:24;
+ GLuint yuvtex_swap_mask:8; /* UV swaped */
+ GLuint pad1:16;
GLuint program_string_id:32;
+ GLuint origin_x, origin_y;
+ GLuint drawable_height;
};
@@ -194,6 +197,7 @@ struct brw_wm_compile {
GLuint nr_fp_insns;
GLuint fp_temp;
GLuint fp_interp_emitted;
+ GLuint fp_deriv_emitted;
struct prog_src_register pixel_xy;
struct prog_src_register delta_xy;
@@ -231,6 +235,15 @@ struct brw_wm_compile {
GLuint grf_limit;
GLuint max_wm_grf;
GLuint last_scratch;
+
+ struct {
+ GLboolean inited;
+ struct brw_reg reg;
+ } wm_regs[PROGRAM_PAYLOAD+1][256][4];
+ struct brw_reg stack;
+ struct brw_reg emit_mask_reg;
+ GLuint reg_index;
+ GLuint tmp_index;
};
@@ -259,4 +272,6 @@ void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
struct brw_wm_prog_key *key );
+GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
+void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c);
#endif
diff --git a/i965/brw_wm_emit.c b/i965/brw_wm_emit.c
index 80bd576..fd66631 100644
--- a/i965/brw_wm_emit.c
+++ b/i965/brw_wm_emit.c
@@ -122,26 +122,30 @@ static void emit_delta_xy(struct brw_compile *p,
}
}
-static void emit_wpos_xy(struct brw_compile *p,
- const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0)
+static void emit_wpos_xy(struct brw_wm_compile *c,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0)
{
- /* Calc delta X,Y by subtracting origin in r1 from the pixel
- * centers.
+ struct brw_compile *p = &c->func;
+
+ /* Calculate the pixel offset from window bottom left into destination
+ * X and Y channels.
*/
if (mask & WRITEMASK_X) {
- brw_MOV(p,
+ /* X' = X - origin */
+ brw_ADD(p,
dst[0],
- retype(arg0[0], BRW_REGISTER_TYPE_UW));
+ retype(arg0[0], BRW_REGISTER_TYPE_W),
+ brw_imm_d(0 - c->key.origin_x));
}
if (mask & WRITEMASK_Y) {
- /* TODO -- window_height - Y */
- brw_MOV(p,
+ /* Y' = height - (Y - origin_y) = height + origin_y - Y */
+ brw_ADD(p,
dst[1],
- negate(retype(arg0[1], BRW_REGISTER_TYPE_UW)));
-
+ negate(retype(arg0[1], BRW_REGISTER_TYPE_W)),
+ brw_imm_d(c->key.origin_y + c->key.drawable_height - 1));
}
}
@@ -219,6 +223,10 @@ static void emit_pinterp( struct brw_compile *p,
if (mask & (1<<i)) {
brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);
brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]);
+ }
+ }
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
brw_MUL(p, dst[i], dst[i], w[3]);
}
}
@@ -229,20 +237,20 @@ static void emit_cinterp( struct brw_compile *p,
GLuint mask,
const struct brw_reg *arg0 )
{
- struct brw_reg interp[4];
- GLuint nr = arg0[0].nr;
- GLuint i;
-
- interp[0] = brw_vec1_grf(nr, 0);
- interp[1] = brw_vec1_grf(nr, 4);
- interp[2] = brw_vec1_grf(nr+1, 0);
- interp[3] = brw_vec1_grf(nr+1, 4);
-
- for(i = 0; i < 4; i++ ) {
- if (mask & (1<<i)) {
- brw_MOV(p, dst[i], suboffset(interp[i],3)); /* TODO: optimize away like other moves */
- }
- }
+ struct brw_reg interp[4];
+ GLuint nr = arg0[0].nr;
+ GLuint i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ brw_MOV(p, dst[i], suboffset(interp[i],3)); /* TODO: optimize away like other moves */
+ }
+ }
}
@@ -343,11 +351,10 @@ static void emit_lrp( struct brw_compile *p,
}
}
}
-
-
-static void emit_slt( struct brw_compile *p,
+static void emit_sop( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
+ GLuint cond,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
@@ -356,34 +363,66 @@ static void emit_slt( struct brw_compile *p,
for (i = 0; i < 4; i++) {
if (mask & (1<<i)) {
brw_MOV(p, dst[i], brw_imm_f(0));
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
+ brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
brw_MOV(p, dst[i], brw_imm_f(1.0));
brw_set_predicate_control_flag_value(p, 0xff);
}
}
}
-/* Isn't this just the same as the above with the args swapped?
- */
-static void emit_sge( struct brw_compile *p,
+static void emit_slt( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
- GLuint i;
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
+}
- for (i = 0; i < 4; i++) {
- if (mask & (1<<i)) {
- brw_MOV(p, dst[i], brw_imm_f(0));
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], arg1[i]);
- brw_MOV(p, dst[i], brw_imm_f(1.0));
- brw_set_predicate_control_flag_value(p, 0xff);
- }
- }
+static void emit_sle( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1);
+}
+
+static void emit_sgt( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1);
+}
+
+static void emit_sge( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1);
}
+static void emit_seq( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1);
+}
+static void emit_sne( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1);
+}
static void emit_cmp( struct brw_compile *p,
const struct brw_reg *dst,
@@ -465,6 +504,9 @@ static void emit_dp3( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ if (!(mask & WRITEMASK_XYZW))
+ return; /* Do not emit dead code*/
+
assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
@@ -482,6 +524,9 @@ static void emit_dp4( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ if (!(mask & WRITEMASK_XYZW))
+ return; /* Do not emit dead code*/
+
assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
@@ -500,6 +545,9 @@ static void emit_dph( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ if (!(mask & WRITEMASK_XYZW))
+ return; /* Do not emit dead code*/
+
assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
@@ -543,8 +591,11 @@ static void emit_math1( struct brw_compile *p,
GLuint mask,
const struct brw_reg *arg0 )
{
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
- function == BRW_MATH_FUNCTION_SINCOS);
+ if (!(mask & WRITEMASK_XYZW))
+ return; /* Do not emit dead code*/
+
+ //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
+ // function == BRW_MATH_FUNCTION_SINCOS);
brw_MOV(p, brw_message_reg(2), arg0[0]);
@@ -567,6 +618,9 @@ static void emit_math2( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1)
{
+ if (!(mask & WRITEMASK_XYZW))
+ return; /* Do not emit dead code*/
+
assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
brw_push_insn_state(p);
@@ -670,7 +724,6 @@ static void emit_tex( struct brw_wm_compile *c,
responseLength,
msgLength,
0);
-
}
@@ -1081,7 +1134,7 @@ void brw_wm_emit( struct brw_wm_compile *c )
break;
case WM_WPOSXY:
- emit_wpos_xy(p, dst, dst_flags, args[0]);
+ emit_wpos_xy(c, dst, dst_flags, args[0]);
break;
case WM_PIXELW:
@@ -1209,9 +1262,21 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_slt(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, dst_flags, args[0], args[1]);
+ break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SEQ:
+ emit_seq(p, dst, dst_flags, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_LIT:
emit_lit(p, dst, dst_flags, args[0]);
@@ -1232,7 +1297,8 @@ void brw_wm_emit( struct brw_wm_compile *c )
break;
default:
- assert(0);
+ _mesa_printf("unsupport opcode %d in fragment program\n",
+ inst->opcode);
}
for (i = 0; i < 4; i++)
diff --git a/i965/brw_wm_fp.c b/i965/brw_wm_fp.c
index dc57fd2..f895f96 100644
--- a/i965/brw_wm_fp.c
+++ b/i965/brw_wm_fp.c
@@ -144,7 +144,7 @@ static struct prog_dst_register dst_undef( void )
static struct prog_dst_register get_temp( struct brw_wm_compile *c )
{
- int bit = ffs( ~c->fp_temp );
+ int bit = _mesa_ffs( ~c->fp_temp );
if (!bit) {
_mesa_printf("%s: out of temporaries\n", __FILE__);
@@ -158,7 +158,7 @@ static struct prog_dst_register get_temp( struct brw_wm_compile *c )
static void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )
{
- c->fp_temp &= ~1<<(temp.Index + 1 - FIRST_INTERNAL_TEMP);
+ c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));
}
@@ -176,6 +176,7 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c,
{
struct prog_instruction *inst = get_fp_inst(c);
*inst = *inst0;
+ inst->Data = (void *)inst0;
return inst;
}
@@ -201,7 +202,6 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
inst->SrcReg[0] = src0;
inst->SrcReg[1] = src1;
inst->SrcReg[2] = src2;
-
return inst;
}
@@ -361,6 +361,37 @@ static void emit_interp( struct brw_wm_compile *c,
c->fp_interp_emitted |= 1<<idx;
}
+static void emit_ddx( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ GLuint idx = inst->SrcReg[0].Index;
+ struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+ c->fp_deriv_emitted |= 1<<idx;
+ emit_op(c,
+ OPCODE_DDX,
+ inst->DstReg,
+ 0, 0, 0,
+ interp,
+ get_pixel_w(c),
+ src_undef());
+}
+
+static void emit_ddy( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ GLuint idx = inst->SrcReg[0].Index;
+ struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+ c->fp_deriv_emitted |= 1<<idx;
+ emit_op(c,
+ OPCODE_DDY,
+ inst->DstReg,
+ 0, 0, 0,
+ interp,
+ get_pixel_w(c),
+ src_undef());
+}
/***********************************************************************
* Hacks to extend the program parameter and constant lists.
@@ -463,17 +494,20 @@ static void precalc_dst( struct brw_wm_compile *c,
if (dst.WriteMask & WRITEMASK_XZ) {
+ struct prog_instruction *swz;
GLuint z = GET_SWZ(src0.Swizzle, Z);
/* dst.xz = swz src0.1zzz
*/
- emit_op(c,
- OPCODE_SWZ,
- dst_mask(dst, WRITEMASK_XZ),
- inst->SaturateMode, 0, 0,
- src_swizzle(src0, SWIZZLE_ONE, z, z, z),
- src_undef(),
- src_undef());
+ swz = emit_op(c,
+ OPCODE_SWZ,
+ dst_mask(dst, WRITEMASK_XZ),
+ inst->SaturateMode, 0, 0,
+ src_swizzle(src0, SWIZZLE_ONE, z, z, z),
+ src_undef(),
+ src_undef());
+ /* Avoid letting negation flag of src0 affect our 1 constant. */
+ swz->SrcReg[0].NegateBase &= ~NEGATE_X;
}
if (dst.WriteMask & WRITEMASK_W) {
/* dst.w = mov src1.w
@@ -496,15 +530,19 @@ static void precalc_lit( struct brw_wm_compile *c,
struct prog_dst_register dst = inst->DstReg;
if (dst.WriteMask & WRITEMASK_XW) {
+ struct prog_instruction *swz;
+
/* dst.xw = swz src0.1111
*/
- emit_op(c,
- OPCODE_SWZ,
- dst_mask(dst, WRITEMASK_XW),
- 0, 0, 0,
- src_swizzle1(src0, SWIZZLE_ONE),
- src_undef(),
- src_undef());
+ swz = emit_op(c,
+ OPCODE_SWZ,
+ dst_mask(dst, WRITEMASK_XW),
+ 0, 0, 0,
+ src_swizzle1(src0, SWIZZLE_ONE),
+ src_undef(),
+ src_undef());
+ /* Avoid letting the negation flag of src0 affect our 1 constant. */
+ swz->SrcReg[0].NegateBase = 0;
}
@@ -618,17 +656,21 @@ static void precalc_tex( struct brw_wm_compile *c,
src_undef());
}
else {
+ GLboolean swap_uv = c->key.yuvtex_swap_mask & (1<<inst->TexSrcUnit);
+
/*
CONST C0 = { -.5, -.0625, -.5, 1.164 }
CONST C1 = { 1.596, -0.813, 2.018, -.391 }
UYV = TEX ...
UYV.xyz = ADD UYV, C0
UYV.y = MUL UYV.y, C0.w
- RGB.xyz = MAD UYV.xxz, C1, UYV.y
+ if (UV swaped)
+ RGB.xyz = MAD UYV.zzx, C1, UYV.y
+ else
+ RGB.xyz = MAD UYV.xxz, C1, UYV.y
RGB.y = MAD UYV.z, C1.w, RGB.y
*/
struct prog_dst_register dst = inst->DstReg;
- struct prog_src_register src0 = inst->SrcReg[0];
struct prog_dst_register tmp = get_temp(c);
struct prog_src_register tmpsrc = src_reg_from_dst(tmp);
struct prog_src_register C0 = search_or_add_const4f( c, -.5, -.0625, -.5, 1.164 );
@@ -642,7 +684,7 @@ static void precalc_tex( struct brw_wm_compile *c,
inst->SaturateMode,
inst->TexSrcUnit,
inst->TexSrcTarget,
- src0,
+ coord,
src_undef(),
src_undef());
@@ -658,6 +700,7 @@ static void precalc_tex( struct brw_wm_compile *c,
/* YUV.y = MUL YUV.y, C0.w
*/
+
emit_op(c,
OPCODE_MUL,
dst_mask(tmp, WRITEMASK_Y),
@@ -666,13 +709,18 @@ static void precalc_tex( struct brw_wm_compile *c,
src_swizzle1(C0, W),
src_undef());
- /* RGB.xyz = MAD YUV.xxz, C1, YUV.y
+ /*
+ * if (UV swaped)
+ * RGB.xyz = MAD YUV.zzx, C1, YUV.y
+ * else
+ * RGB.xyz = MAD YUV.xxz, C1, YUV.y
*/
+
emit_op(c,
OPCODE_MAD,
dst_mask(dst, WRITEMASK_XYZ),
0, 0, 0,
- src_swizzle(tmpsrc, X,X,Z,Z),
+ swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
C1,
src_swizzle1(tmpsrc, Y));
@@ -689,7 +737,8 @@ static void precalc_tex( struct brw_wm_compile *c,
release_temp(c, tmp);
}
- if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV)
+ if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
+ (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
release_temp(c, tmpcoord);
}
@@ -710,7 +759,7 @@ static GLboolean projtex( struct brw_wm_compile *c,
return 0; /* ut2004 gun rendering !?! */
else if (src.File == PROGRAM_INPUT &&
GET_SWZ(src.Swizzle, W) == W &&
- (c->key.projtex_mask & (1<<src.Index)) == 0)
+ (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0)
return 0;
else
return 1;
@@ -939,7 +988,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
case OPCODE_LIT:
precalc_lit(c, inst);
break;
-
+
+ case OPCODE_TEX:
+ precalc_tex(c, inst);
+ break;
+
case OPCODE_TXP:
precalc_txp(c, inst);
break;
@@ -957,8 +1010,16 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
*/
out->DstReg.WriteMask = 0;
break;
-
+ case OPCODE_DDX:
+ emit_ddx(c, inst);
+ break;
+ case OPCODE_DDY:
+ emit_ddy(c, inst);
+ break;
case OPCODE_END:
+ emit_fog(c);
+ emit_fb_write(c);
+ break;
case OPCODE_PRINT:
break;
@@ -967,15 +1028,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
break;
}
}
-
- emit_fog(c);
- emit_fb_write(c);
-
if (INTEL_DEBUG & DEBUG_WM) {
- _mesa_printf("\n\n\npass_fp:\n");
- print_insns( c->prog_instructions, c->nr_fp_insns );
- _mesa_printf("\n");
+ _mesa_printf("\n\n\npass_fp:\n");
+ print_insns( c->prog_instructions, c->nr_fp_insns );
+ _mesa_printf("\n");
}
}
diff --git a/i965/brw_wm_glsl.c b/i965/brw_wm_glsl.c
new file mode 100644
index 0000000..5a1f80d
--- /dev/null
+++ b/i965/brw_wm_glsl.c
@@ -0,0 +1,1370 @@
+#include "macros.h"
+#include "shader/prog_parameter.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_wm.h"
+
+/* Only guess, need a flag in gl_fragment_program later */
+GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
+{
+ int i;
+ for (i = 0; i < fp->Base.NumInstructions; i++) {
+ struct prog_instruction *inst = &fp->Base.Instructions[i];
+ switch (inst->Opcode) {
+ case OPCODE_IF:
+ case OPCODE_INT:
+ case OPCODE_ENDIF:
+ case OPCODE_CAL:
+ case OPCODE_BRK:
+ case OPCODE_RET:
+ case OPCODE_DDX:
+ case OPCODE_DDY:
+ case OPCODE_BGNLOOP:
+ return GL_TRUE;
+ default:
+ break;
+ }
+ }
+ return GL_FALSE;
+}
+
+static void set_reg(struct brw_wm_compile *c, int file, int index,
+ int component, struct brw_reg reg)
+{
+ c->wm_regs[file][index][component].reg = reg;
+ c->wm_regs[file][index][component].inited = GL_TRUE;
+}
+
+static int get_scalar_dst_index(struct prog_instruction *inst)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ if (inst->DstReg.WriteMask & (1<<i))
+ break;
+ return i;
+}
+
+static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
+{
+ struct brw_reg reg;
+ reg = brw_vec8_grf(c->tmp_index--, 0);
+ return reg;
+}
+
+static void release_tmps(struct brw_wm_compile *c)
+{
+ c->tmp_index = 127;
+}
+
+static struct brw_reg
+get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GLuint neg, GLuint abs)
+{
+ struct brw_reg reg;
+ switch (file) {
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_UNIFORM:
+ file = PROGRAM_STATE_VAR;
+ break;
+ case PROGRAM_UNDEFINED:
+ return brw_null_reg();
+ default:
+ break;
+ }
+
+ if(c->wm_regs[file][index][component].inited)
+ reg = c->wm_regs[file][index][component].reg;
+ else
+ reg = brw_vec8_grf(c->reg_index, 0);
+
+ if(!c->wm_regs[file][index][component].inited) {
+ set_reg(c, file, index, component, reg);
+ c->reg_index++;
+ }
+
+ if (neg & (1<< component)) {
+ reg = negate(reg);
+ }
+ if (abs)
+ reg = brw_abs(reg);
+ return reg;
+}
+
+static void prealloc_reg(struct brw_wm_compile *c)
+{
+ int i, j;
+ struct brw_reg reg;
+ int nr_interp_regs = 0;
+ GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
+
+ for (i = 0; i < 4; i++) {
+ reg = (i < c->key.nr_depth_regs)
+ ? brw_vec8_grf(i*2, 0) : brw_vec8_grf(0, 0);
+ set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
+ }
+ c->reg_index += 2*c->key.nr_depth_regs;
+ {
+ int nr_params = c->fp->program.Base.Parameters->NumParameters;
+ struct gl_program_parameter_list *plist =
+ c->fp->program.Base.Parameters;
+ int index = 0;
+ c->prog_data.nr_params = 4*nr_params;
+ for (i = 0; i < nr_params; i++) {
+ for (j = 0; j < 4; j++, index++) {
+ reg = brw_vec1_grf(c->reg_index + index/8,
+ index%8);
+ c->prog_data.param[index] =
+ &plist->ParameterValues[i][j];
+ set_reg(c, PROGRAM_STATE_VAR, i, j, reg);
+ }
+ }
+ c->nr_creg = 2*((4*nr_params+15)/16);
+ c->reg_index += c->nr_creg;
+ }
+ for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
+ if (inputs & (1<<i)) {
+ nr_interp_regs++;
+ reg = brw_vec8_grf(c->reg_index, 0);
+ for (j = 0; j < 4; j++)
+ set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
+ c->reg_index += 2;
+
+ }
+ }
+ c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+ c->prog_data.urb_read_length = nr_interp_regs * 2;
+ c->prog_data.curb_read_length = c->nr_creg;
+ c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+ c->reg_index++;
+ c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+ c->reg_index += 2;
+}
+
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
+ struct prog_instruction *inst, int component, int nr)
+{
+ return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
+ 0, 0);
+}
+
+static struct brw_reg get_src_reg(struct brw_wm_compile *c,
+ struct prog_src_register *src, int index, int nr)
+{
+ int component = GET_SWZ(src->Swizzle, index);
+ return get_reg(c, src->File, src->Index, component, nr,
+ src->NegateBase, src->Abs);
+}
+
+static void emit_abs( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for (i = 0; i < 4; i++) {
+ if (inst->DstReg.WriteMask & (1<<i)) {
+ struct brw_reg src, dst;
+ dst = get_dst_reg(c, inst, i, 1);
+ src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_MOV(p, dst, brw_abs(src));
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_int( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ struct brw_reg src, dst;
+ dst = get_dst_reg(c, inst, i, 1) ;
+ src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_RNDD(p, dst, src);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_mov( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ struct brw_reg src, dst;
+ dst = get_dst_reg(c, inst, i, 1);
+ src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_MOV(p, dst, src);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_pixel_xy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg r1 = brw_vec1_grf(1, 0);
+ struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
+
+ struct brw_reg dst0, dst1;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ dst0 = get_dst_reg(c, inst, 0, 1);
+ dst1 = get_dst_reg(c, inst, 1, 1);
+ /* Calculate pixel centers by adding 1 or 0 to each of the
+ * micro-tile coordinates passed in r1.
+ */
+ if (mask & WRITEMASK_X) {
+ brw_ADD(p,
+ vec8(retype(dst0, BRW_REGISTER_TYPE_UW)),
+ stride(suboffset(r1_uw, 4), 2, 4, 0),
+ brw_imm_v(0x10101010));
+ }
+
+ if (mask & WRITEMASK_Y) {
+ brw_ADD(p,
+ vec8(retype(dst1, BRW_REGISTER_TYPE_UW)),
+ stride(suboffset(r1_uw, 5), 2, 4, 0),
+ brw_imm_v(0x11001100));
+ }
+
+}
+
+static void emit_delta_xy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg r1 = brw_vec1_grf(1, 0);
+ struct brw_reg dst0, dst1, src0, src1;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ dst0 = get_dst_reg(c, inst, 0, 1);
+ dst1 = get_dst_reg(c, inst, 1, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+ /* Calc delta X,Y by subtracting origin in r1 from the pixel
+ * centers.
+ */
+ if (mask & WRITEMASK_X) {
+ brw_ADD(p,
+ dst0,
+ retype(src0, BRW_REGISTER_TYPE_UW),
+ negate(r1));
+ }
+
+ if (mask & WRITEMASK_Y) {
+ brw_ADD(p,
+ dst1,
+ retype(src1, BRW_REGISTER_TYPE_UW),
+ negate(suboffset(r1,1)));
+
+ }
+
+}
+
+
+static void fire_fb_write( struct brw_wm_compile *c,
+ GLuint base_reg,
+ GLuint nr )
+{
+ struct brw_compile *p = &c->func;
+
+ /* Pass through control information:
+ */
+ /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */
+ {
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
+ brw_MOV(p,
+ brw_message_reg(base_reg + 1),
+ brw_vec8_grf(1, 0));
+ brw_pop_insn_state(p);
+ }
+ /* Send framebuffer write message: */
+ brw_fb_WRITE(p,
+ retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
+ base_reg,
+ retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+ 0, /* render surface always 0 */
+ nr,
+ 0,
+ 1);
+}
+
+static void emit_fb_write(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ int nr = 2;
+ int channel;
+ struct brw_reg src0;//, src1, src2, dst;
+
+ /* Reserve a space for AA - may not be needed:
+ */
+ if (c->key.aa_dest_stencil_reg)
+ nr += 1;
+ {
+ brw_push_insn_state(p);
+ for (channel = 0; channel < 4; channel++) {
+ src0 = get_src_reg(c, &inst->SrcReg[0], channel, 1);
+ /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */
+ /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */
+ brw_MOV(p, brw_message_reg(nr + channel), src0);
+ }
+ /* skip over the regs populated above: */
+ nr += 8;
+ brw_pop_insn_state(p);
+ }
+
+ if (c->key.source_depth_to_render_target)
+ {
+ if (c->key.computes_depth) {
+ src0 = get_src_reg(c, &inst->SrcReg[2], 2, 1);
+ brw_MOV(p, brw_message_reg(nr), src0);
+ } else {
+ src0 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+ brw_MOV(p, brw_message_reg(nr), src0);
+ }
+
+ nr += 2;
+ }
+
+ fire_fb_write(c, 0, nr);
+}
+
+static void emit_pixel_w( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ if (mask & WRITEMASK_W) {
+ struct brw_reg dst, src0, delta0, delta1;
+ struct brw_reg interp3;
+
+ dst = get_dst_reg(c, inst, 3, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+ delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+
+ interp3 = brw_vec1_grf(src0.nr+1, 4);
+ /* Calc 1/w - just linterp wpos[3] optimized by putting the
+ * result straight into a message reg.
+ */
+ brw_LINE(p, brw_null_reg(), interp3, delta0);
+ brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1);
+
+ /* Calc w */
+ brw_math_16( p, dst,
+ BRW_MATH_FUNCTION_INV,
+ BRW_MATH_SATURATE_NONE,
+ 2, brw_null_reg(),
+ BRW_MATH_PRECISION_FULL);
+ }
+}
+
+static void emit_linterp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg interp[4];
+ struct brw_reg dst, delta0, delta1;
+ struct brw_reg src0;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+ delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+ GLuint nr = src0.nr;
+ int i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_LINE(p, brw_null_reg(), interp[i], delta0);
+ brw_MAC(p, dst, suboffset(interp[i],1), delta1);
+ }
+ }
+}
+
+static void emit_cinterp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ struct brw_reg interp[4];
+ struct brw_reg dst, src0;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ GLuint nr = src0.nr;
+ int i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_MOV(p, dst, suboffset(interp[i],3));
+ }
+ }
+}
+
+static void emit_pinterp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ struct brw_reg interp[4];
+ struct brw_reg dst, delta0, delta1;
+ struct brw_reg src0, w;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+ delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+ w = get_src_reg(c, &inst->SrcReg[2], 3, 1);
+ GLuint nr = src0.nr;
+ int i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_LINE(p, brw_null_reg(), interp[i], delta0);
+ brw_MAC(p, dst, suboffset(interp[i],1),
+ delta1);
+ brw_MUL(p, dst, dst, w);
+ }
+ }
+}
+
+static void emit_xpd(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ for (i = 0; i < 4; i++) {
+ GLuint i2 = (i+2)%3;
+ GLuint i1 = (i+1)%3;
+ if (mask & (1<<i)) {
+ struct brw_reg src0, src1, dst;
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = negate(get_src_reg(c, &inst->SrcReg[0], i2, 1));
+ src1 = get_src_reg(c, &inst->SrcReg[1], i1, 1);
+ brw_MUL(p, brw_null_reg(), src0, src1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i1, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i2, 1);
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ brw_MAC(p, dst, src0, src1);
+ brw_set_saturate(p, 0);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_dp3(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg src0[3], src1[3], dst;
+ int i;
+ struct brw_compile *p = &c->func;
+ for (i = 0; i < 3; i++) {
+ src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ }
+
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+ brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MAC(p, dst, src0[2], src1[2]);
+ brw_set_saturate(p, 0);
+}
+
+static void emit_dp4(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg src0[4], src1[4], dst;
+ int i;
+ struct brw_compile *p = &c->func;
+ for (i = 0; i < 4; i++) {
+ src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ }
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+ brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+ brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MAC(p, dst, src0[3], src1[3]);
+ brw_set_saturate(p, 0);
+}
+
+static void emit_dph(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg src0[4], src1[4], dst;
+ int i;
+ struct brw_compile *p = &c->func;
+ for (i = 0; i < 4; i++) {
+ src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ }
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+ brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+ brw_MAC(p, dst, src0[2], src1[2]);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_ADD(p, dst, src0[3], src1[3]);
+ brw_set_saturate(p, 0);
+}
+
+static void emit_math1(struct brw_wm_compile *c,
+ struct prog_instruction *inst, GLuint func)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, dst;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MOV(p, brw_message_reg(2), src0);
+ brw_math(p,
+ dst,
+ func,
+ (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+ 2,
+ brw_null_reg(),
+ BRW_MATH_DATA_VECTOR,
+ BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_rcp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
+}
+
+static void emit_rsq(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
+}
+
+static void emit_sin(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
+}
+
+static void emit_cos(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
+}
+
+static void emit_ex2(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
+}
+
+static void emit_lg2(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
+}
+
+static void emit_add(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, src1, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_ADD(p, dst, src0, src1);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_sub(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, src1, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_ADD(p, dst, src0, negate(src1));
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_mul(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, src1, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_MUL(p, dst, src0, src1);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_frc(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_FRC(p, dst, src0);
+ }
+ }
+ if (inst->SaturateMode != SATURATE_OFF)
+ brw_set_saturate(p, 0);
+}
+
+static void emit_flr(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_RNDD(p, dst, src0);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_max(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg src0, src1, dst;
+ int i;
+ brw_push_insn_state(p);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MOV(p, dst, src0);
+ brw_set_saturate(p, 0);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, src1);
+ brw_set_saturate(p, 0);
+ brw_set_predicate_control_flag_value(p, 0xff);
+ }
+ }
+ brw_pop_insn_state(p);
+}
+
+static void emit_min(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg src0, src1, dst;
+ int i;
+ brw_push_insn_state(p);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MOV(p, dst, src0);
+ brw_set_saturate(p, 0);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, src1);
+ brw_set_saturate(p, 0);
+ brw_set_predicate_control_flag_value(p, 0xff);
+ }
+ }
+ brw_pop_insn_state(p);
+}
+
+static void emit_pow(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg dst, src0, src1;
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+
+ brw_MOV(p, brw_message_reg(2), src0);
+ brw_MOV(p, brw_message_reg(3), src1);
+
+ brw_math(p,
+ dst,
+ BRW_MATH_FUNCTION_POW,
+ (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+ 2,
+ brw_null_reg(),
+ BRW_MATH_DATA_VECTOR,
+ BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_lrp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
+ int i;
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+
+ if (src1.nr == dst.nr) {
+ tmp1 = alloc_tmp(c);
+ brw_MOV(p, tmp1, src1);
+ } else
+ tmp1 = src1;
+
+ src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+ if (src2.nr == dst.nr) {
+ tmp2 = alloc_tmp(c);
+ brw_MOV(p, tmp2, src2);
+ } else
+ tmp2 = src2;
+
+ brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
+ brw_MUL(p, brw_null_reg(), dst, tmp2);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MAC(p, dst, src0, tmp1);
+ brw_set_saturate(p, 0);
+ }
+ release_tmps(c);
+ }
+}
+
+static void emit_kil(struct brw_wm_compile *c)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+ brw_AND(p, depth, c->emit_mask_reg, depth);
+ brw_pop_insn_state(p);
+}
+
+static void emit_mad(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg dst, src0, src1, src2;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+ brw_MUL(p, dst, src0, src1);
+
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_ADD(p, dst, dst, src2);
+ brw_set_saturate(p, 0);
+ }
+ }
+}
+
+static void emit_sop(struct brw_wm_compile *c,
+ struct prog_instruction *inst, GLuint cond)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg dst, src0, src1;
+ int i;
+
+ brw_push_insn_state(p);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_CMP(p, brw_null_reg(), cond, src0, src1);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_MOV(p, dst, brw_imm_f(0.0));
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, brw_imm_f(1.0));
+ }
+ }
+ brw_pop_insn_state(p);
+}
+
+static void emit_slt(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_L);
+}
+
+static void emit_sle(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_LE);
+}
+
+static void emit_sgt(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_G);
+}
+
+static void emit_sge(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_GE);
+}
+
+static void emit_seq(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_EQ);
+}
+
+static void emit_sne(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
+}
+
+static void emit_ddx(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg interp[4];
+ struct brw_reg dst;
+ struct brw_reg src0, w;
+ GLuint nr, i;
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+ nr = src0.nr;
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_MOV(p, dst, interp[i]);
+ brw_MUL(p, dst, dst, w);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_ddy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg interp[4];
+ struct brw_reg dst;
+ struct brw_reg src0, w;
+ GLuint nr, i;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ nr = src0.nr;
+ w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_MOV(p, dst, suboffset(interp[i], 1));
+ brw_MUL(p, dst, dst, w);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_wpos_xy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg src0[2], dst[2];
+
+ dst[0] = get_dst_reg(c, inst, 0, 1);
+ dst[1] = get_dst_reg(c, inst, 1, 1);
+
+ src0[0] = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ src0[1] = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+
+ /* Calculate the pixel offset from window bottom left into destination
+ * X and Y channels.
+ */
+ if (mask & WRITEMASK_X) {
+ /* X' = X - origin_x */
+ brw_ADD(p,
+ dst[0],
+ retype(src0[0], BRW_REGISTER_TYPE_W),
+ brw_imm_d(0 - c->key.origin_x));
+ }
+
+ if (mask & WRITEMASK_Y) {
+ /* Y' = height - (Y - origin_y) = height + origin_y - Y */
+ brw_ADD(p,
+ dst[1],
+ negate(retype(src0[1], BRW_REGISTER_TYPE_W)),
+ brw_imm_d(c->key.origin_y + c->key.drawable_height - 1));
+ }
+}
+
+/* TODO
+ BIAS on SIMD8 not workind yet...
+ */
+static void emit_txb(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg dst[4], src[4], payload_reg;
+ GLuint i;
+ payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+ for (i = 0; i < 4; i++)
+ dst[i] = get_dst_reg(c, inst, i, 1);
+ for (i = 0; i < 4; i++)
+ src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX:
+ brw_MOV(p, brw_message_reg(2), src[0]);
+ brw_MOV(p, brw_message_reg(3), brw_imm_f(0));
+ brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+ break;
+ case TEXTURE_2D_INDEX:
+ case TEXTURE_RECT_INDEX:
+ brw_MOV(p, brw_message_reg(2), src[0]);
+ brw_MOV(p, brw_message_reg(3), src[1]);
+ brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+ break;
+ default:
+ brw_MOV(p, brw_message_reg(2), src[0]);
+ brw_MOV(p, brw_message_reg(3), src[1]);
+ brw_MOV(p, brw_message_reg(4), src[2]);
+ break;
+ }
+ brw_MOV(p, brw_message_reg(5), src[3]);
+ brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+ brw_SAMPLE(p,
+ retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
+ 1,
+ retype(payload_reg, BRW_REGISTER_TYPE_UW),
+ inst->TexSrcUnit + 1, /* surface */
+ inst->TexSrcUnit, /* sampler */
+ inst->DstReg.WriteMask,
+ BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
+ 4,
+ 4,
+ 0);
+}
+
+static void emit_tex(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg dst[4], src[4], payload_reg;
+ GLuint msg_len;
+ GLuint i, nr;
+ GLuint emit;
+ GLboolean shadow = (c->key.shadowtex_mask & (1<<inst->TexSrcUnit)) ? 1 : 0;
+
+ payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+
+ for (i = 0; i < 4; i++)
+ dst[i] = get_dst_reg(c, inst, i, 1);
+ for (i = 0; i < 4; i++)
+ src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX:
+ emit = WRITEMASK_X;
+ nr = 1;
+ break;
+ case TEXTURE_2D_INDEX:
+ case TEXTURE_RECT_INDEX:
+ emit = WRITEMASK_XY;
+ nr = 2;
+ break;
+ default:
+ emit = WRITEMASK_XYZ;
+ nr = 3;
+ break;
+ }
+ msg_len = 1;
+
+ for (i = 0; i < nr; i++) {
+ static const GLuint swz[4] = {0,1,2,2};
+ if (emit & (1<<i))
+ brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
+ else
+ brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
+ msg_len += 1;
+ }
+
+ if (shadow) {
+ brw_MOV(p, brw_message_reg(5), brw_imm_f(0));
+ brw_MOV(p, brw_message_reg(6), src[2]);
+ }
+
+ brw_SAMPLE(p,
+ retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
+ 1,
+ retype(payload_reg, BRW_REGISTER_TYPE_UW),
+ inst->TexSrcUnit + 1, /* surface */
+ inst->TexSrcUnit, /* sampler */
+ inst->DstReg.WriteMask,
+ BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
+ 4,
+ shadow ? 6 : 4,
+ 0);
+
+ if (shadow)
+ brw_MOV(p, dst[3], brw_imm_f(1.0));
+}
+
+static void post_wm_emit( struct brw_wm_compile *c )
+{
+ GLuint nr_insns = c->fp->program.Base.NumInstructions;
+ GLuint insn, target_insn;
+ struct prog_instruction *inst1, *inst2;
+ struct brw_instruction *brw_inst1, *brw_inst2;
+ int offset;
+ for (insn = 0; insn < nr_insns; insn++) {
+ inst1 = &c->fp->program.Base.Instructions[insn];
+ brw_inst1 = inst1->Data;
+ switch (inst1->Opcode) {
+ case OPCODE_CAL:
+ target_insn = inst1->BranchTarget;
+ inst2 = &c->fp->program.Base.Instructions[target_insn];
+ brw_inst2 = inst2->Data;
+ offset = brw_inst2 - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
+
+{
+#define MAX_IFSN 32
+#define MAX_LOOP_DEPTH 32
+ struct brw_instruction *if_inst[MAX_IFSN], *loop_inst[MAX_LOOP_DEPTH];
+ struct brw_instruction *inst0, *inst1;
+ int i, if_insn = 0, loop_insn = 0;
+ struct brw_compile *p = &c->func;
+ struct brw_indirect stack_index = brw_indirect(0, 0);
+
+ brw_init_compile(brw, &c->func);
+ c->reg_index = 0;
+ prealloc_reg(c);
+ brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+ brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
+
+ for (i = 0; i < c->nr_fp_insns; i++) {
+ struct prog_instruction *inst = &c->prog_instructions[i];
+ struct prog_instruction *orig_inst;
+
+ if ((orig_inst = inst->Data) != 0)
+ orig_inst->Data = current_insn(p);
+
+ if (inst->CondUpdate)
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+ else
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+
+ switch (inst->Opcode) {
+ case WM_PIXELXY:
+ emit_pixel_xy(c, inst);
+ break;
+ case WM_DELTAXY:
+ emit_delta_xy(c, inst);
+ break;
+ case WM_PIXELW:
+ emit_pixel_w(c, inst);
+ break;
+ case WM_LINTERP:
+ emit_linterp(c, inst);
+ break;
+ case WM_PINTERP:
+ emit_pinterp(c, inst);
+ break;
+ case WM_CINTERP:
+ emit_cinterp(c, inst);
+ break;
+ case WM_WPOSXY:
+ emit_wpos_xy(c, inst);
+ break;
+ case WM_FB_WRITE:
+ emit_fb_write(c, inst);
+ break;
+ case OPCODE_ABS:
+ emit_abs(c, inst);
+ break;
+ case OPCODE_ADD:
+ emit_add(c, inst);
+ break;
+ case OPCODE_SUB:
+ emit_sub(c, inst);
+ break;
+ case OPCODE_FRC:
+ emit_frc(c, inst);
+ break;
+ case OPCODE_FLR:
+ emit_flr(c, inst);
+ break;
+ case OPCODE_LRP:
+ emit_lrp(c, inst);
+ break;
+ case OPCODE_INT:
+ emit_int(c, inst);
+ break;
+ case OPCODE_MOV:
+ emit_mov(c, inst);
+ break;
+ case OPCODE_DP3:
+ emit_dp3(c, inst);
+ break;
+ case OPCODE_DP4:
+ emit_dp4(c, inst);
+ break;
+ case OPCODE_XPD:
+ emit_xpd(c, inst);
+ break;
+ case OPCODE_DPH:
+ emit_dph(c, inst);
+ break;
+ case OPCODE_RCP:
+ emit_rcp(c, inst);
+ break;
+ case OPCODE_RSQ:
+ emit_rsq(c, inst);
+ break;
+ case OPCODE_SIN:
+ emit_sin(c, inst);
+ break;
+ case OPCODE_COS:
+ emit_cos(c, inst);
+ break;
+ case OPCODE_EX2:
+ emit_ex2(c, inst);
+ break;
+ case OPCODE_LG2:
+ emit_lg2(c, inst);
+ break;
+ case OPCODE_MAX:
+ emit_max(c, inst);
+ break;
+ case OPCODE_MIN:
+ emit_min(c, inst);
+ break;
+ case OPCODE_DDX:
+ emit_ddx(c, inst);
+ break;
+ case OPCODE_DDY:
+ emit_ddy(c, inst);
+ break;
+ case OPCODE_SLT:
+ emit_slt(c, inst);
+ break;
+ case OPCODE_SLE:
+ emit_sle(c, inst);
+ break;
+ case OPCODE_SGT:
+ emit_sgt(c, inst);
+ break;
+ case OPCODE_SGE:
+ emit_sge(c, inst);
+ break;
+ case OPCODE_SEQ:
+ emit_seq(c, inst);
+ break;
+ case OPCODE_SNE:
+ emit_sne(c, inst);
+ break;
+ case OPCODE_MUL:
+ emit_mul(c, inst);
+ break;
+ case OPCODE_POW:
+ emit_pow(c, inst);
+ break;
+ case OPCODE_MAD:
+ emit_mad(c, inst);
+ break;
+ case OPCODE_TEX:
+ emit_tex(c, inst);
+ break;
+ case OPCODE_TXB:
+ emit_txb(c, inst);
+ break;
+ case OPCODE_KIL_NV:
+ emit_kil(c);
+ break;
+ case OPCODE_IF:
+ assert(if_insn < MAX_IFSN);
+ if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_ELSE:
+ if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
+ break;
+ case OPCODE_ENDIF:
+ assert(if_insn > 0);
+ brw_ENDIF(p, if_inst[--if_insn]);
+ break;
+ case OPCODE_BGNSUB:
+ case OPCODE_ENDSUB:
+ break;
+ case OPCODE_CAL:
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_ADD(p, deref_1ud(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(4));
+ orig_inst = inst->Data;
+ orig_inst->Data = &p->store[p->nr_insn];
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ brw_pop_insn_state(p);
+ break;
+
+ case OPCODE_RET:
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(-4));
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_MOV(p, brw_ip_reg(), deref_1ud(stack_index, 0));
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ brw_pop_insn_state(p);
+
+ break;
+ case OPCODE_BGNLOOP:
+ loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_BRK:
+ brw_BREAK(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case OPCODE_CONT:
+ brw_CONT(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case OPCODE_ENDLOOP:
+ loop_insn--;
+ inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]);
+ /* patch all the BREAK instructions from
+ last BEGINLOOP */
+ while (inst0 > loop_inst[loop_insn]) {
+ inst0--;
+ if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+ inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
+ inst0->bits3.if_else.pop_count = 0;
+ } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+ inst0->bits3.if_else.jump_count = inst1 - inst0;
+ inst0->bits3.if_else.pop_count = 0;
+ }
+ }
+ break;
+ default:
+ _mesa_printf("unsupported IR in fragment shader %d\n",
+ inst->Opcode);
+ }
+ if (inst->CondUpdate)
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ else
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ }
+ post_wm_emit(c);
+ for (i = 0; i < c->fp->program.Base.NumInstructions; i++)
+ c->fp->program.Base.Instructions[i].Data = NULL;
+}
+
+void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
+{
+ brw_wm_pass_fp(c);
+ c->tmp_index = 127;
+ brw_wm_emit_glsl(brw, c);
+ c->prog_data.total_grf = c->reg_index;
+ c->prog_data.total_scratch = 0;
+}
diff --git a/i965/brw_wm_pass0.c b/i965/brw_wm_pass0.c
index 00f6f6b..1bfae5a 100644
--- a/i965/brw_wm_pass0.c
+++ b/i965/brw_wm_pass0.c
@@ -168,6 +168,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
case PROGRAM_PAYLOAD:
case PROGRAM_TEMPORARY:
case PROGRAM_OUTPUT:
+ case PROGRAM_VARYING:
break;
case PROGRAM_LOCAL_PARAM:
@@ -179,6 +180,8 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
break;
case PROGRAM_STATE_VAR:
+ case PROGRAM_UNIFORM:
+ case PROGRAM_CONSTANT:
case PROGRAM_NAMED_PARAM: {
struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters;
@@ -197,6 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
break;
case PROGRAM_STATE_VAR:
+ case PROGRAM_UNIFORM:
/* These may change from run to run:
*/
ref = get_param_ref(c, &plist->ParameterValues[idx][component] );
diff --git a/i965/brw_wm_pass1.c b/i965/brw_wm_pass1.c
index d668def..f6f3a38 100644
--- a/i965/brw_wm_pass1.c
+++ b/i965/brw_wm_pass1.c
@@ -150,12 +150,17 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_FLR:
case OPCODE_FRC:
case OPCODE_MOV:
+ case OPCODE_SWZ:
read0 = writemask;
break;
case OPCODE_SUB:
case OPCODE_SLT:
+ case OPCODE_SLE:
case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SEQ:
+ case OPCODE_SNE:
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
@@ -253,11 +258,9 @@ void brw_wm_pass1( struct brw_wm_compile *c )
read0 = WRITEMASK_XYW;
break;
- case OPCODE_SWZ:
case OPCODE_DST:
case OPCODE_TXP:
default:
- assert(0);
break;
}
diff --git a/i965/brw_wm_pass2.c b/i965/brw_wm_pass2.c
index a1edbd6..c1ce6a9 100644
--- a/i965/brw_wm_pass2.c
+++ b/i965/brw_wm_pass2.c
@@ -328,7 +328,7 @@ void brw_wm_pass2( struct brw_wm_compile *c )
c->state = PASS2_DONE;
if (INTEL_DEBUG & DEBUG_WM) {
- brw_wm_print_program(c, "pass2/done");
+ brw_wm_print_program(c, "pass2/done");
}
}
diff --git a/i965/brw_wm_sampler_state.c b/i965/brw_wm_sampler_state.c
index 794c7d9..3c0952a 100644
--- a/i965/brw_wm_sampler_state.c
+++ b/i965/brw_wm_sampler_state.c
@@ -54,7 +54,7 @@ static GLuint translate_wrap_mode( GLenum wrap )
case GL_REPEAT:
return BRW_TEXCOORDMODE_WRAP;
case GL_CLAMP:
- return BRW_TEXCOORDMODE_CLAMP_BORDER; /* conform likes it this way */
+ return BRW_TEXCOORDMODE_CLAMP;
case GL_CLAMP_TO_EDGE:
return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */
case GL_CLAMP_TO_BORDER:
diff --git a/i965/brw_wm_state.c b/i965/brw_wm_state.c
index 5b4f2ab..7856da0 100644
--- a/i965/brw_wm_state.c
+++ b/i965/brw_wm_state.c
@@ -34,6 +34,7 @@
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
+#include "brw_wm.h"
#include "bufmgr.h"
/***********************************************************************
@@ -62,7 +63,7 @@ static void upload_wm_unit(struct brw_context *brw )
memset(&wm, 0, sizeof(wm));
/* CACHE_NEW_WM_PROG */
- wm.thread0.grf_reg_count = ((brw->wm.prog_data->total_grf-1) & ~15) / 16;
+ wm.thread0.grf_reg_count = ALIGN(brw->wm.prog_data->total_grf, 16) / 16 - 1;
wm.thread0.kernel_start_pointer = brw->wm.prog_gs_offset >> 6;
wm.thread3.dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
wm.thread3.urb_entry_read_length = brw->wm.prog_data->urb_read_length;
@@ -71,7 +72,7 @@ static void upload_wm_unit(struct brw_context *brw )
wm.wm5.max_threads = max_threads;
if (brw->wm.prog_data->total_scratch) {
- GLuint per_thread = (brw->wm.prog_data->total_scratch + 1023) / 1024;
+ GLuint per_thread = ALIGN(brw->wm.prog_data->total_scratch, 1024);
GLuint total = per_thread * (max_threads + 1);
/* Scratch space -- just have to make sure there is sufficient
@@ -134,9 +135,13 @@ static void upload_wm_unit(struct brw_context *brw )
if (fp->UsesKill ||
brw->attribs.Color->AlphaEnabled)
wm.wm5.program_uses_killpixel = 1;
+
+ if (brw_wm_is_glsl(fp))
+ wm.wm5.enable_8_pix = 1;
+ else
+ wm.wm5.enable_16_pix = 1;
}
- wm.wm5.enable_16_pix = 1;
wm.wm5.thread_dispatch_enable = 1; /* AKA: color_write */
wm.wm5.legacy_line_rast = 0;
wm.wm5.legacy_global_depth_bias = 0;
diff --git a/i965/brw_wm_surface_state.c b/i965/brw_wm_surface_state.c
index d24c618..12cd089 100644
--- a/i965/brw_wm_surface_state.c
+++ b/i965/brw_wm_surface_state.c
@@ -69,7 +69,7 @@ static GLuint translate_tex_target( GLenum target )
}
-static GLuint translate_tex_format( GLuint mesa_format )
+static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode )
{
switch( mesa_format ) {
case MESA_FORMAT_L8:
@@ -114,11 +114,29 @@ static GLuint translate_tex_format( GLuint mesa_format )
return BRW_SURFACEFORMAT_FXT1;
case MESA_FORMAT_Z16:
- return BRW_SURFACEFORMAT_L16_UNORM;
+ if (depth_mode == GL_INTENSITY)
+ return BRW_SURFACEFORMAT_I16_UNORM;
+ else if (depth_mode == GL_ALPHA)
+ return BRW_SURFACEFORMAT_A16_UNORM;
+ else
+ return BRW_SURFACEFORMAT_L16_UNORM;
- case MESA_FORMAT_RGBA_DXT1:
case MESA_FORMAT_RGB_DXT1:
- return BRW_SURFACEFORMAT_DXT1_RGB;
+ return BRW_SURFACEFORMAT_DXT1_RGB;
+
+ case MESA_FORMAT_RGBA_DXT1:
+ return BRW_SURFACEFORMAT_BC1_UNORM;
+
+ case MESA_FORMAT_RGBA_DXT3:
+ return BRW_SURFACEFORMAT_BC2_UNORM;
+
+ case MESA_FORMAT_RGBA_DXT5:
+ return BRW_SURFACEFORMAT_BC3_UNORM;
+
+ case MESA_FORMAT_SRGBA8:
+ return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB;
+ case MESA_FORMAT_SRGB_DXT1:
+ return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
default:
assert(0);
@@ -141,7 +159,7 @@ void brw_update_texture_surface( GLcontext *ctx,
surf->ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
surf->ss0.surface_type = translate_tex_target(tObj->Target);
- surf->ss0.surface_format = translate_tex_format(firstImage->TexFormat->MesaFormat);
+ surf->ss0.surface_format = translate_tex_format(firstImage->TexFormat->MesaFormat, tObj->DepthMode);
/* This is ok for all textures with channel width 8bit or less:
*/
@@ -181,11 +199,8 @@ static void upload_wm_surfaces(struct brw_context *brw )
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = &brw->intel;
- struct brw_surface_binding_table bind;
GLuint i;
- memcpy(&bind, &brw->wm.bind, sizeof(bind));
-
{
struct brw_surface_state surf;
struct intel_region *region = brw->state.draw_region;
diff --git a/i965/bufmgr_fake.c b/i965/bufmgr_fake.c
index fb4903d..3b7229c 100644
--- a/i965/bufmgr_fake.c
+++ b/i965/bufmgr_fake.c
@@ -169,7 +169,7 @@ static GLboolean alloc_from_pool( struct intel_context *intel,
if (!block)
return GL_FALSE;
- sz = (buf->size + align-1) & ~(align-1);
+ sz = ALIGN(buf->size, align);
block->mem = mmAllocMem(pool->heap,
sz,
diff --git a/i965/intel_batchbuffer.c b/i965/intel_batchbuffer.c
index 64885ed..ab61d07 100644
--- a/i965/intel_batchbuffer.c
+++ b/i965/intel_batchbuffer.c
@@ -36,7 +36,7 @@ static void intel_batchbuffer_reset( struct intel_batchbuffer *batch )
assert(batch->map == NULL);
batch->offset = (unsigned long)batch->ptr;
- batch->offset = (batch->offset + 63) & ~63;
+ batch->offset = ALIGN(batch->offset, 64);
batch->ptr = (unsigned char *) batch->offset;
if (BATCH_SZ - batch->offset < BATCH_REFILL) {
@@ -216,7 +216,7 @@ void intel_batchbuffer_align( struct intel_batchbuffer *batch,
GLuint sz )
{
unsigned long ptr = (unsigned long) batch->ptr;
- unsigned long aptr = (ptr + align) & ~((unsigned long)align-1);
+ unsigned long aptr = ALIGN(ptr, align);
GLuint fixup = aptr - ptr;
if (intel_batchbuffer_space(batch) < fixup + sz)
diff --git a/i965/intel_batchbuffer.h b/i965/intel_batchbuffer.h
index 25e0a65..b794772 100644
--- a/i965/intel_batchbuffer.h
+++ b/i965/intel_batchbuffer.h
@@ -84,7 +84,7 @@ void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
static inline GLuint
intel_batchbuffer_space( struct intel_batchbuffer *batch )
{
- return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - (batch->map + batch->offset));
+ return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->map);
}
diff --git a/i965/intel_blit.c b/i965/intel_blit.c
index f88cbb2..d2068aa 100644
--- a/i965/intel_blit.c
+++ b/i965/intel_blit.c
@@ -373,7 +373,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
clear_depth = 0;
if (flags & BUFFER_BIT_DEPTH) {
- clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
+ clear_depth = (GLuint)(ctx->Depth.Clear * ctx->DrawBuffer->_DepthMax);
}
if (flags & BUFFER_BIT_STENCIL) {
@@ -537,7 +537,8 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
{
struct xy_setup_blit setup;
struct xy_text_immediate_blit text;
- int dwords = ((src_size + 7) & ~7) / 4;
+ int dwords = ALIGN(src_size, 8) / 4;
+ uint32_t opcode, br13;
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
diff --git a/i965/intel_buffers.c b/i965/intel_buffers.c
index de6a867..769f75c 100644
--- a/i965/intel_buffers.c
+++ b/i965/intel_buffers.c
@@ -545,15 +545,14 @@ static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
- intelSetFrontClipRects( intel );
-
-
if (front) {
+ intelSetFrontClipRects(intel);
if (intel->draw_region != intel->front_region) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, intel->front_region);
}
} else {
+ intelSetBackClipRects(intel);
if (intel->draw_region != intel->back_region) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, intel->back_region);
diff --git a/i965/intel_context.c b/i965/intel_context.c
index 5ee5282..65b3c99 100644
--- a/i965/intel_context.c
+++ b/i965/intel_context.c
@@ -66,6 +66,7 @@
int INTEL_DEBUG = (0);
#endif
+#define need_GL_NV_point_sprite
#define need_GL_ARB_multisample
#define need_GL_ARB_point_parameters
#define need_GL_ARB_texture_compression
@@ -81,6 +82,13 @@ int INTEL_DEBUG = (0);
#define need_GL_EXT_fog_coord
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
+#define need_GL_ATI_separate_stencil
+#define need_GL_EXT_point_parameters
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_shader
+
#include "extension_helper.h"
#ifndef VERBOSE
@@ -118,9 +126,17 @@ static const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
case PCI_CHIP_I965_GM:
chipset = "Intel(R) 965GM"; break;
break;
- case PCI_CHIP_IGD_GM:
+ case PCI_CHIP_GM45_GM:
+ chipset = "Mobile IntelĀ® GM45 Express Chipset";
+ break;
+ case PCI_CHIP_IGD_E_G:
chipset = "Intel(R) Integrated Graphics Device";
break;
+ case PCI_CHIP_Q45_G:
+ chipset = "Intel(R) Q45/Q43"; break;
+ case PCI_CHIP_G45_G:
+ chipset = "Intel(R) G45/G43"; break;
+
default:
chipset = "Unknown Intel Chipset"; break;
}
@@ -146,6 +162,7 @@ const struct dri_extension card_extensions[] =
{ "GL_ARB_multisample", GL_ARB_multisample_functions },
{ "GL_ARB_multitexture", NULL },
{ "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
+ { "GL_NV_point_sprite", GL_NV_point_sprite_functions },
{ "GL_ARB_texture_border_clamp", NULL },
{ "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
{ "GL_ARB_texture_cube_map", NULL },
@@ -158,6 +175,8 @@ const struct dri_extension card_extensions[] =
{ "GL_NV_texture_rectangle", NULL },
{ "GL_EXT_texture_rectangle", NULL },
{ "GL_ARB_texture_rectangle", NULL },
+ { "GL_ARB_point_sprite", NULL},
+ { "GL_ARB_point_parameters", NULL },
{ "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
{ "GL_ARB_window_pos", GL_ARB_window_pos_functions },
@@ -171,18 +190,33 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
+ { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions },
{ "GL_EXT_stencil_wrap", NULL },
+ /* Do not enable this extension. It conflicts with GL_ATI_separate_stencil
+ * and 2.0's separate stencil, because mesa's computed _TestTwoSide will
+ * only reflect whether it's enabled through this extension, even if the
+ * application is using the other interfaces.
+ */
+/*{ "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions },*/
{ "GL_EXT_texture_edge_clamp", NULL },
{ "GL_EXT_texture_env_combine", NULL },
{ "GL_EXT_texture_env_dot3", NULL },
{ "GL_EXT_texture_filter_anisotropic", NULL },
{ "GL_EXT_texture_lod_bias", NULL },
+ { "GL_EXT_texture_sRGB", NULL },
{ "GL_3DFX_texture_compression_FXT1", NULL },
{ "GL_APPLE_client_storage", NULL },
{ "GL_MESA_pack_invert", NULL },
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
+ { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions},
+ { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions},
+ { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions},
+ { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},
+ { "GL_ARB_fragment_shader", NULL },
+ /* XXX not implement yet, to compile builtin glsl lib */
+ { "GL_ARB_draw_buffers", NULL },
{ NULL, NULL }
};
@@ -399,17 +433,10 @@ GLboolean intelInitContext( struct intel_context *intel,
switch(mesaVis->depthBits) {
case 0: /* what to do in this case? */
case 16:
- intel->depth_scale = 1.0/0xffff;
intel->polygon_offset_scale = 1.0/0xffff;
- intel->depth_clear_mask = ~0;
- intel->ClearDepth = 0xffff;
break;
case 24:
- intel->depth_scale = 1.0/0xffffff;
intel->polygon_offset_scale = 2.0/0xffffff; /* req'd to pass glean */
- intel->depth_clear_mask = 0x00ffffff;
- intel->stencil_clear_mask = 0xff000000;
- intel->ClearDepth = 0x00ffffff;
break;
default:
assert(0);
@@ -551,6 +578,8 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
#endif
/* free the Mesa context */
+ intel->ctx.VertexProgram.Current = NULL;
+ intel->ctx.FragmentProgram.Current = NULL;
_mesa_destroy_context(&intel->ctx);
}
diff --git a/i965/intel_context.h b/i965/intel_context.h
index a244757..76ee119 100644
--- a/i965/intel_context.h
+++ b/i965/intel_context.h
@@ -183,12 +183,8 @@ struct intel_context
GLubyte clear_chan[4];
GLuint ClearColor;
- GLuint ClearDepth;
- GLfloat depth_scale;
GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */
- GLuint depth_clear_mask;
- GLuint stencil_clear_mask;
GLboolean hw_stencil;
GLboolean hw_stipple;
@@ -269,6 +265,8 @@ void UNLOCK_HARDWARE( struct intel_context *intel );
#define SUBPIXEL_X 0.125
#define SUBPIXEL_Y 0.125
+#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
+
/* ================================================================
* Color packing:
*/
@@ -387,8 +385,11 @@ extern int INTEL_DEBUG;
#define PCI_CHIP_I946_GZ 0x2972
#define PCI_CHIP_I965_GM 0x2A02
-#define PCI_CHIP_IGD_GM 0x2A42
+#define PCI_CHIP_GM45_GM 0x2A42
+#define PCI_CHIP_IGD_E_G 0x2E02
+#define PCI_CHIP_Q45_G 0x2E12
+#define PCI_CHIP_G45_G 0x2E22
/* ================================================================
* intel_context.c:
diff --git a/i965/intel_mipmap_tree.c b/i965/intel_mipmap_tree.c
index 8548bc8..5177802 100644
--- a/i965/intel_mipmap_tree.c
+++ b/i965/intel_mipmap_tree.c
@@ -75,7 +75,7 @@ struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel,
mt->width0 = width0;
mt->height0 = height0;
mt->depth0 = depth0;
- mt->cpp = compressed ? 2 : cpp;
+ mt->cpp = cpp;
mt->compressed = compressed;
switch (intel->intelScreen->deviceID) {
@@ -128,7 +128,7 @@ int intel_miptree_pitch_align (struct intel_context *intel,
int pitch)
{
if (!mt->compressed)
- pitch = ((pitch * mt->cpp + 3) & ~3) / mt->cpp;
+ pitch = ALIGN(pitch * mt->cpp, 4) / mt->cpp;
return pitch;
}
@@ -234,7 +234,7 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
-
+extern GLuint intel_compressed_alignment(GLenum);
/* Upload data for a particular image.
*/
GLboolean intel_miptree_image_data(struct intel_context *intel,
@@ -249,6 +249,17 @@ GLboolean intel_miptree_image_data(struct intel_context *intel,
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level);
GLuint i;
+ GLuint width, height, alignment;
+
+ width = dst->level[level].width;
+ height = dst->level[level].height;
+
+ if (dst->compressed) {
+ alignment = intel_compressed_alignment(dst->internal_format);
+ src_row_pitch = ALIGN(src_row_pitch, alignment);
+ width = ALIGN(width, alignment);
+ height = (height + 3) / 4;
+ }
DBG("%s\n", __FUNCTION__);
for (i = 0; i < depth; i++) {
@@ -260,8 +271,8 @@ GLboolean intel_miptree_image_data(struct intel_context *intel,
src,
src_row_pitch,
0, 0, /* source x,y */
- dst->level[level].width,
- dst->level[level].height))
+ width,
+ height))
return GL_FALSE;
src += src_image_pitch;
}
diff --git a/i965/intel_pixel_bitmap.c b/i965/intel_pixel_bitmap.c
index df9d688..54a88c5 100644
--- a/i965/intel_pixel_bitmap.c
+++ b/i965/intel_pixel_bitmap.c
@@ -91,11 +91,6 @@ static void set_bit( GLubyte *dest,
dest[bit/8] |= 1 << (bit % 8);
}
-static int align(int x, int align)
-{
- return (x + align - 1) & ~(align - 1);
-}
-
/* Extract a rectangle's worth of data from the bitmap. Called
* per-cliprect.
*/
@@ -147,7 +142,7 @@ static GLuint get_bitmap_rect(GLsizei width, GLsizei height,
}
if (row_align)
- bit = (bit + row_align - 1) & ~(row_align - 1);
+ bit = ALIGN(bit, row_align);
}
return count;
@@ -169,11 +164,8 @@ do_blit_bitmap( GLcontext *ctx,
struct intel_context *intel = intel_context(ctx);
struct intel_region *dst = intel_drawbuf_region(intel);
GLfloat tmpColor[4];
-
- union {
- GLuint ui;
- GLubyte ub[4];
- } color;
+ GLubyte ubcolor[4];
+ GLuint color8888, color565;
if (!dst)
return GL_FALSE;
@@ -190,10 +182,14 @@ do_blit_bitmap( GLcontext *ctx,
ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
}
- UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], tmpColor[2]);
- UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], tmpColor[1]);
- UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], tmpColor[0]);
- UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], tmpColor[3]);
+ UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
+
+ color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]);
+ color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);
+
/* Does zoom apply to bitmaps?
*/
@@ -235,10 +231,10 @@ do_blit_bitmap( GLcontext *ctx,
dsty = dPriv->y + (dPriv->h - dsty - height);
dstx = dPriv->x + dstx;
- dest_rect.x1 = dstx;
- dest_rect.y1 = dsty;
- dest_rect.x2 = dstx + width;
- dest_rect.y2 = dsty + height;
+ dest_rect.x1 = dstx < 0 ? 0 : dstx;
+ dest_rect.y1 = dsty < 0 ? 0 : dsty;
+ dest_rect.x2 = dstx + width < 0 ? 0 : dstx + width;
+ dest_rect.y2 = dsty + height < 0 ? 0 : dsty + height;
for (i = 0; i < nbox; i++) {
drm_clip_rect_t rect;
@@ -268,7 +264,7 @@ do_blit_bitmap( GLcontext *ctx,
for (px = 0; px < box_w; px += DX) {
int h = MIN2(DY, box_h - py);
int w = MIN2(DX, box_w - px);
- GLuint sz = align(align(w,8) * h, 64)/8;
+ GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
ctx->Color.LogicOp : GL_COPY;
@@ -292,7 +288,7 @@ do_blit_bitmap( GLcontext *ctx,
dst->cpp,
(GLubyte *)stipple,
sz,
- color.ui,
+ (dst->cpp == 2) ? color565 : color8888,
dst->pitch,
dst->buffer,
0,
diff --git a/i965/intel_screen.c b/i965/intel_screen.c
index 5dac50d..b08531c 100644
--- a/i965/intel_screen.c
+++ b/i965/intel_screen.c
@@ -53,7 +53,7 @@ DRI_CONF_BEGIN
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
+ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
DRI_CONF_SECTION_END
DRI_CONF_END;
const GLuint __driNConfigOptions = 4;
diff --git a/i965/intel_tex_validate.c b/i965/intel_tex_validate.c
index cb23b9d..775b689 100644
--- a/i965/intel_tex_validate.c
+++ b/i965/intel_tex_validate.c
@@ -122,6 +122,29 @@ static void intel_texture_invalidate_cb( struct intel_context *intel,
intel_texture_invalidate( (struct intel_texture_object *) ptr );
}
+#include "texformat.h"
+static GLuint intel_compressed_num_bytes(GLenum mesaFormat)
+{
+ GLuint bytes = 0;
+
+ switch (mesaFormat) {
+ case MESA_FORMAT_RGB_FXT1:
+ case MESA_FORMAT_RGBA_FXT1:
+ case MESA_FORMAT_RGB_DXT1:
+ case MESA_FORMAT_RGBA_DXT1:
+ bytes = 2;
+ break;
+
+ case MESA_FORMAT_RGBA_DXT3:
+ case MESA_FORMAT_RGBA_DXT5:
+ bytes = 4;
+
+ default:
+ break;
+ }
+
+ return bytes;
+}
/*
*/
@@ -132,7 +155,8 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
GLuint face, i;
GLuint nr_faces = 0;
struct gl_texture_image *firstImage;
-
+ GLuint cpp = 0;
+
if( tObj == intel->frame_buffer_texobj )
return GL_FALSE;
@@ -165,6 +189,12 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
+ if (firstImage->IsCompressed) {
+ cpp = intel_compressed_num_bytes(firstImage->TexFormat->MesaFormat);
+ } else {
+ cpp = firstImage->TexFormat->TexelBytes;
+ }
+
/* Check tree can hold all active levels. Check tree matches
* target, imageFormat, etc.
*/
@@ -176,7 +206,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
intelObj->mt->width0 != firstImage->Width ||
intelObj->mt->height0 != firstImage->Height ||
intelObj->mt->depth0 != firstImage->Depth ||
- intelObj->mt->cpp != firstImage->TexFormat->TexelBytes ||
+ intelObj->mt->cpp != cpp ||
intelObj->mt->compressed != firstImage->IsCompressed))
{
intel_miptree_destroy(intel, intelObj->mt);
@@ -199,7 +229,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
firstImage->Width,
firstImage->Height,
firstImage->Depth,
- firstImage->TexFormat->TexelBytes,
+ cpp,
firstImage->IsCompressed);
/* Tell the buffer manager that we will manage the backing
diff --git a/shared/intel_tex_layout.c b/shared/intel_tex_layout.c
index 39a443c..cc73694 100644
--- a/shared/intel_tex_layout.c
+++ b/shared/intel_tex_layout.c
@@ -34,10 +34,21 @@
#include "intel_tex_layout.h"
#include "macros.h"
-
-static int align(int value, int alignment)
+GLuint intel_compressed_alignment(GLenum internalFormat)
{
- return (value + alignment - 1) & ~(alignment - 1);
+ GLuint alignment = 4;
+
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ alignment = 8;
+ break;
+
+ default:
+ break;
+ }
+
+ return alignment;
}
void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt )
@@ -51,17 +62,30 @@ void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tr
mt->pitch = mt->width0;
+ if (mt->compressed) {
+ align_w = intel_compressed_alignment(mt->internal_format);
+ mt->pitch = ALIGN(mt->width0, align_w);
+ }
+
/* May need to adjust pitch to accomodate the placement of
* the 2nd mipmap. This occurs when the alignment
* constraints of mipmap placement push the right edge of the
* 2nd mipmap out past the width of its parent.
*/
if (mt->first_level != mt->last_level) {
- GLuint mip1_width = align(minify(mt->width0), align_w)
- + minify(minify(mt->width0));
+ GLuint mip1_width;
+
+ if (mt->compressed) {
+ mip1_width = ALIGN(minify(mt->width0), align_w)
+ + ALIGN(minify(minify(mt->width0)), align_w);
+ } else {
+ mip1_width = ALIGN(minify(mt->width0), align_w)
+ + minify(minify(mt->width0));
+ }
- if (mip1_width > mt->width0)
- mt->pitch = mip1_width;
+ if (mip1_width > mt->pitch) {
+ mt->pitch = mip1_width;
+ }
}
/* Pitch must be a whole number of dwords, even though we
@@ -79,7 +103,7 @@ void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tr
if (mt->compressed)
img_height = MAX2(1, height/4);
else
- img_height = align(height, align_h);
+ img_height = ALIGN(height, align_h);
/* Because the images are packed better, the final offset
@@ -90,7 +114,7 @@ void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tr
/* Layout_below: step right after second mipmap.
*/
if (level == mt->first_level + 1) {
- x += align(width, align_w);
+ x += ALIGN(width, align_w);
}
else {
y += img_height;
diff --git a/shared/intel_tex_layout.h b/shared/intel_tex_layout.h
index 46151db..193699d 100644
--- a/shared/intel_tex_layout.h
+++ b/shared/intel_tex_layout.h
@@ -39,3 +39,4 @@ static GLuint minify( GLuint d )
}
extern void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt );
+extern GLuint intel_compressed_alignment(GLenum);