i965/vs: Fix unit mismatch in scratch base_offset parameter.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 1 Oct 2012 22:28:55 +0000 (15:28 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 10 Oct 2012 20:22:55 +0000 (13:22 -0700)
move_grf_array_access_to_scratch() calculates scratch buffer offsets in
bytes.  However, emit_scratch_read/write() expects the base_offset
parameter to be measured in OWords.

As a result, a shader using a scratch read/write offset greater than
zero (in practice, a shader containing more than one variable in
scratch) would use too large an offset, frequently exceeding the
available scratch space.

This patch corrects the mismatch by removing spurious conversion from
OWords to bytes in move_grf_array_access_to_scratch().

This is based on a patch by Paul Berry.

NOTE: This is a candidate for stable release branches.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h

index 682837ffa6a3eb8ba33998e1a6e1f826139288c9..59428a192102f3d003333bbada06513baed46ac7 100644 (file)
@@ -2443,6 +2443,8 @@ vec4_visitor::get_pull_constant_offset(vec4_instruction *inst,
 /**
  * Emits an instruction before @inst to load the value named by @orig_src
  * from scratch space at @base_offset to @temp.
+ *
+ * @base_offset is measured in 32-byte units (the size of a register).
  */
 void
 vec4_visitor::emit_scratch_read(vec4_instruction *inst,
@@ -2458,6 +2460,8 @@ vec4_visitor::emit_scratch_read(vec4_instruction *inst,
 /**
  * Emits an instruction after @inst to store the value to be written
  * to @orig_dst to scratch space at @base_offset, from @temp.
+ *
+ * @base_offset is measured in 32-byte units (the size of a register).
  */
 void
 vec4_visitor::emit_scratch_write(vec4_instruction *inst,
@@ -2501,7 +2505,7 @@ vec4_visitor::move_grf_array_access_to_scratch()
       if (inst->dst.file == GRF && inst->dst.reladdr &&
          scratch_loc[inst->dst.reg] == -1) {
         scratch_loc[inst->dst.reg] = c->last_scratch;
-        c->last_scratch += this->virtual_grf_sizes[inst->dst.reg] * 8 * 4;
+        c->last_scratch += this->virtual_grf_sizes[inst->dst.reg];
       }
 
       for (int i = 0 ; i < 3; i++) {
@@ -2510,7 +2514,7 @@ vec4_visitor::move_grf_array_access_to_scratch()
         if (src->file == GRF && src->reladdr &&
             scratch_loc[src->reg] == -1) {
            scratch_loc[src->reg] = c->last_scratch;
-           c->last_scratch += this->virtual_grf_sizes[src->reg] * 8 * 4;
+           c->last_scratch += this->virtual_grf_sizes[src->reg];
         }
       }
    }
index 4507f6c1c4c521ad18f63df9287f2de6d24ff686..4e9507420999dae67295e8208e02b34a74b15c59 100644 (file)
@@ -306,7 +306,7 @@ do_vs_prog(struct brw_context *brw,
                  "Try reducing the number of live vec4 values to "
                  "improve performance.\n");
 
-      c.prog_data.total_scratch = brw_get_scratch_size(c.last_scratch);
+      c.prog_data.total_scratch = brw_get_scratch_size(c.last_scratch*REG_SIZE);
 
       brw_get_scratch_bo(intel, &brw->vs.scratch_bo,
                         c.prog_data.total_scratch * brw->max_vs_threads);
index e04247f3035c477497a8a2aa134169e8b163f816..adeff7ff6dec684c091971788982d63cf4342577 100644 (file)
@@ -93,7 +93,7 @@ struct brw_vs_compile {
    GLuint nr_inputs;
 
    GLuint first_output;
-   GLuint last_scratch;
+   GLuint last_scratch; /**< measured in 32-byte (register size) units */
 
    GLuint first_tmp;
    GLuint last_tmp;