diff options
author | Brice Goglin <bgoglin@debian.org> | 2008-06-11 18:58:59 +0200 |
---|---|---|
committer | Brice Goglin <bgoglin@debian.org> | 2008-06-11 18:58:59 +0200 |
commit | e32aaf5da8a6e40f9beb2801f160392de3644a69 (patch) | |
tree | be260228e1ac94f89d4e422e8778a1ac3387c439 | |
parent | 9676f0cffc30b5414e7cc5bd2119d5bb396596c3 (diff) | |
parent | 03447de338158cca962880fd04d7d3ecf4bd9c5b (diff) | |
download | mesa-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.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_fragprog.c | 56 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_program.c | 38 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_program.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_texprog.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_tex.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_screen.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/program.c | 2 |
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), |