summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrice Goglin <bgoglin@debian.org>2008-06-11 18:58:59 +0200
committerBrice Goglin <bgoglin@debian.org>2008-06-11 18:58:59 +0200
commite32aaf5da8a6e40f9beb2801f160392de3644a69 (patch)
treebe260228e1ac94f89d4e422e8778a1ac3387c439
parent9676f0cffc30b5414e7cc5bd2119d5bb396596c3 (diff)
parent03447de338158cca962880fd04d7d3ecf4bd9c5b (diff)
downloadmesa-e32aaf5da8a6e40f9beb2801f160392de3644a69.tar.gz
Merge branch 'mesa_7_0_branch' of git://git.freedesktop.org/git/mesa/mesa into debian-unstable
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h6
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c56
-rw-r--r--src/mesa/drivers/dri/i915/i915_program.c38
-rw-r--r--src/mesa/drivers/dri/i915/i915_program.h1
-rw-r--r--src/mesa/drivers/dri/i915/i915_texprog.c2
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c2
-rw-r--r--src/mesa/shader/program.c2
8 files changed, 87 insertions, 22 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index ec1550126a6..7b51d77db83 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index ffb6b31af32..c46ef24e082 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -224,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, \
@@ -247,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:
*
@@ -280,6 +317,15 @@ 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, consts0 = 0, consts1 = 0;
@@ -447,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:
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index 68491124449..31be4b527c6 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_program.h b/src/mesa/drivers/dri/i915/i915_program.h
index 8891a177855..d9760f9a510 100644
--- a/src/mesa/drivers/dri/i915/i915_program.h
+++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_texprog.c b/src/mesa/drivers/dri/i915/i915_texprog.c
index f6a8b0205a6..c467fe19038 100644
--- a/src/mesa/drivers/dri/i915/i915_texprog.c
+++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 5bd280652af..8460134caa8 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 0c86b223a42..fd6b59d06a4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -188,7 +188,7 @@ DRI_CONF_BEGIN
DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(8, 2, 8)
DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
- DRI_CONF_DISABLE_FALLBACK(false)
+ DRI_CONF_DISABLE_FALLBACK(true)
DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(false)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 12fcb675c3d..a8983703fa2 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -241,8 +241,6 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
struct gl_program *
_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
{
- if (ctx->Driver.NewProgram)
- return ctx->Driver.NewProgram(ctx, target, id);
switch (target) {
case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),