summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-07-30 00:03:21 -0700
committerEric Anholt <eric@anholt.net>2009-10-01 14:31:03 -0700
commit96a3c69d48bb7c021181e061d010cca08198ae4c (patch)
tree68e029121fa270fbcb787006f906131804d557a3
parent61b512c47c9888f3ff117faf3aceccfb52d59c3a (diff)
i915: Increase maximum program size to the hardware limits.
This fixes potential heap trashing if the program of choice exceeds limits, and fixes the native instructions limit being lower than what can be used by valid programs.
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h15
-rw-r--r--src/mesa/drivers/dri/i915/i915_program.c8
2 files changed, 16 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 8de4a9d0d3..082d614442 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -121,10 +121,14 @@ enum {
#define I915_MAX_CONSTANT 32
#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT))
+#define I915_MAX_INSN (I915_MAX_DECL_INSN + \
+ I915_MAX_TEX_INSN + \
+ I915_MAX_ALU_INSN)
-#define I915_PROGRAM_SIZE 192
-
-#define I915_MAX_INSN (I915_MAX_TEX_INSN+I915_MAX_ALU_INSN)
+/* Maximum size of the program packet, which matches the limits on
+ * decl, tex, and ALU instructions.
+ */
+#define I915_PROGRAM_SIZE (I915_MAX_INSN * 3 + 1)
/* Hardware version of a parsed fragment program. "Derived" from the
* mesa fragment_program struct.
@@ -154,8 +158,9 @@ struct i915_fragment_program
*/
GLcontext *ctx;
- GLuint declarations[I915_PROGRAM_SIZE];
- GLuint program[I915_PROGRAM_SIZE];
+ /* declarations contains the packet header. */
+ GLuint declarations[I915_MAX_DECL_INSN * 3 + 1];
+ GLuint program[(I915_MAX_TEX_INSN + I915_MAX_ALU_INSN) * 3];
GLfloat constant[I915_MAX_CONSTANT][4];
GLuint constant_flags[I915_MAX_CONSTANT];
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index fd3019b234..e7908bd48f 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -130,6 +130,7 @@ i915_emit_decl(struct i915_fragment_program *p,
*(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
*(p->decl++) = D1_MBZ;
*(p->decl++) = D2_MBZ;
+ assert(p->decl <= p->declarations + ARRAY_SIZE(p->declarations));
p->nr_decl_insn++;
return reg;
@@ -186,7 +187,7 @@ i915_emit_arith(struct i915_fragment_program * p,
p->utemp_flag = old_utemp_flag; /* restore */
}
- if (p->csr >= p->program + I915_PROGRAM_SIZE) {
+ if (p->csr >= p->program + ARRAY_SIZE(p->program)) {
i915_program_error(p, "Program contains too many instructions");
return UREG_BAD;
}
@@ -275,7 +276,7 @@ GLuint i915_emit_texld( struct i915_fragment_program *p,
p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
p->nr_tex_indirect++;
- if (p->csr >= p->program + I915_PROGRAM_SIZE) {
+ if (p->csr >= p->program + ARRAY_SIZE(p->program)) {
i915_program_error(p, "Program contains too many instructions");
return UREG_BAD;
}
@@ -530,6 +531,9 @@ i915_upload_program(struct i915_context *i915,
GLuint program_size = p->csr - p->program;
GLuint decl_size = p->decl - p->declarations;
+ if (p->error)
+ return;
+
/* Could just go straight to the batchbuffer from here:
*/
if (i915->state.ProgramSize != (program_size + decl_size) ||