summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-09-06 22:32:33 -0700
committerEric Anholt <[email protected]>2011-09-08 21:34:03 -0700
commitdf35d691807656d3627b6fa6f51a08674bdc043e (patch)
tree781aa6f55eabe21de406ea558178452cba80945c /src
parentf3ed973f53d2a621d915de2cdc8e09c0755db016 (diff)
i965/vs: Add support for overflowing the number of available push constants.
Fixes glsl-vs-uniform-array-4. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33742 Reviewed-by: Ian Romanick <[email protected]> Acked-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp85
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_emit.cpp1
3 files changed, 87 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 9d64a4009d1..e3562d29238 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -277,4 +277,89 @@ vec4_visitor::pack_uniform_registers()
}
}
+/**
+ * Only a limited number of hardware registers may be used for push
+ * constants, so this turns access to the overflowed constants into
+ * pull constants.
+ */
+void
+vec4_visitor::move_push_constants_to_pull_constants()
+{
+ int pull_constant_loc[this->uniforms];
+
+ /* Only allow 32 registers (256 uniform components) as push constants,
+ * which is the limit on gen6.
+ */
+ int max_uniform_components = 32 * 8;
+ if (this->uniforms * 4 <= max_uniform_components)
+ return;
+
+ /* Make some sort of choice as to which uniforms get sent to pull
+ * constants. We could potentially do something clever here like
+ * look for the most infrequently used uniform vec4s, but leave
+ * that for later.
+ */
+ for (int i = 0; i < this->uniforms * 4; i += 4) {
+ pull_constant_loc[i / 4] = -1;
+
+ if (i >= max_uniform_components) {
+ const float **values = &prog_data->param[i];
+
+ /* Try to find an existing copy of this uniform in the pull
+ * constants if it was part of an array access already.
+ */
+ for (unsigned int j = 0; j < prog_data->nr_pull_params; j += 4) {
+ int matches;
+
+ for (matches = 0; matches < 4; matches++) {
+ if (prog_data->pull_param[j + matches] != values[matches])
+ break;
+ }
+
+ if (matches == 4) {
+ pull_constant_loc[i / 4] = j / 4;
+ break;
+ }
+ }
+
+ if (pull_constant_loc[i / 4] == -1) {
+ assert(prog_data->nr_pull_params % 4 == 0);
+ pull_constant_loc[i / 4] = prog_data->nr_pull_params / 4;
+
+ for (int j = 0; j < 4; j++) {
+ prog_data->pull_param[prog_data->nr_pull_params++] = values[j];
+ }
+ }
+ }
+ }
+
+ /* Now actually rewrite usage of the things we've moved to pull
+ * constants.
+ */
+ foreach_list_safe(node, &this->instructions) {
+ vec4_instruction *inst = (vec4_instruction *)node;
+
+ for (int i = 0 ; i < 3; i++) {
+ if (inst->src[i].file != UNIFORM ||
+ pull_constant_loc[inst->src[i].reg] == -1)
+ continue;
+
+ int uniform = inst->src[i].reg;
+
+ dst_reg temp = dst_reg(this, glsl_type::vec4_type);
+
+ emit_pull_constant_load(inst, temp, inst->src[i],
+ pull_constant_loc[uniform]);
+
+ inst->src[i].file = temp.file;
+ inst->src[i].reg = temp.reg;
+ inst->src[i].reg_offset = temp.reg_offset;
+ inst->src[i].reladdr = NULL;
+ }
+ }
+
+ /* Repack push constants to remove the now-unused ones. */
+ pack_uniform_registers();
+}
+
} /* namespace brw */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 0bfd88b25d3..1597f983f2f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -381,6 +381,7 @@ public:
void reg_allocate();
void move_grf_array_access_to_scratch();
void move_uniform_array_access_to_pull_constants();
+ void move_push_constants_to_pull_constants();
void split_uniform_registers();
void pack_uniform_registers();
void calculate_live_intervals();
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index 3567949b811..78ffbd7b6ab 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -608,6 +608,7 @@ vec4_visitor::run()
move_grf_array_access_to_scratch();
move_uniform_array_access_to_pull_constants();
pack_uniform_registers();
+ move_push_constants_to_pull_constants();
bool progress;
do {