summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2014-08-24 00:56:12 +0200
committerEmil Velikov <emil.l.velikov@gmail.com>2014-09-02 12:29:58 +0100
commit6e46a1c0b3801a3360c0f69b0aa6fb46687cd648 (patch)
tree45833fac0591704efbce0d512a209e5d54ada52b /src
parent86b7073739facf2204e6fc7b49c6f6328d83cd5e (diff)
glsl_to_tgsi: allocate and enlarge arrays for temporaries on demand
This fixes crashes if the number of temporaries is greater than 4096. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66184 v2: added fail paths for realloc failures Cc: 10.2 10.3 mesa-stable@lists.freedesktop.org Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu> (cherry picked from commit 482def592fede9c4c2f1e6944df42e8319dd6b78) Conflicts: src/mesa/state_tracker/st_glsl_to_tgsi.cpp
Diffstat (limited to 'src')
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp54
1 files changed, 34 insertions, 20 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index d4cfffbc0c7..004437bfee0 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -75,14 +75,6 @@ extern "C" {
(1 << PROGRAM_UNIFORM))
/**
- * Maximum number of temporary registers.
- *
- * It is too big for stack allocated arrays -- it will cause stack overflow on
- * Windows and likely Mac OS X.
- */
-#define MAX_TEMPS 4096
-
-/**
* Maximum number of arrays
*/
#define MAX_ARRAYS 256
@@ -3261,14 +3253,10 @@ get_src_arg_mask(st_dst_reg dst, st_src_reg src)
void
glsl_to_tgsi_visitor::simplify_cmp(void)
{
- unsigned *tempWrites;
+ int tempWritesSize = 0;
+ unsigned *tempWrites = NULL;
unsigned outputWrites[MAX_PROGRAM_OUTPUTS];
- tempWrites = new unsigned[MAX_TEMPS];
- if (!tempWrites) {
- return;
- }
- memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS);
memset(outputWrites, 0, sizeof(outputWrites));
foreach_list(node, &this->instructions) {
@@ -3291,7 +3279,19 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
prevWriteMask = outputWrites[inst->dst.index];
outputWrites[inst->dst.index] |= inst->dst.writemask;
} else if (inst->dst.file == PROGRAM_TEMPORARY) {
- assert(inst->dst.index < MAX_TEMPS);
+ if (inst->dst.index >= tempWritesSize) {
+ const int inc = 4096;
+
+ tempWrites = (unsigned*)
+ realloc(tempWrites,
+ (tempWritesSize + inc) * sizeof(unsigned));
+ if (!tempWrites)
+ return;
+
+ memset(tempWrites + tempWritesSize, 0, inc * sizeof(unsigned));
+ tempWritesSize += inc;
+ }
+
prevWriteMask = tempWrites[inst->dst.index];
tempWrites[inst->dst.index] |= inst->dst.writemask;
} else
@@ -3310,7 +3310,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
}
}
- delete [] tempWrites;
+ free(tempWrites);
}
/* Replaces all references to a temporary register index with another index. */
@@ -4171,7 +4171,9 @@ struct label {
struct st_translate {
struct ureg_program *ureg;
- struct ureg_dst temps[MAX_TEMPS];
+ unsigned temps_size;
+ struct ureg_dst *temps;
+
struct ureg_dst arrays[MAX_ARRAYS];
struct ureg_src *constants;
struct ureg_src *immediates;
@@ -4304,9 +4306,20 @@ dst_register(struct st_translate *t,
return ureg_dst_undef();
case PROGRAM_TEMPORARY:
- assert(index >= 0);
- assert(index < (int) Elements(t->temps));
-
+ /* Allocate space for temporaries on demand. */
+ if (index >= t->temps_size) {
+ const int inc = 4096;
+
+ t->temps = (struct ureg_dst*)
+ realloc(t->temps,
+ (t->temps_size + inc) * sizeof(struct ureg_dst));
+ if (!t->temps)
+ return ureg_dst_undef();
+
+ memset(t->temps + t->temps_size, 0, inc * sizeof(struct ureg_dst));
+ t->temps_size += inc;
+ }
+
if (ureg_dst_is_undef(t->temps[index]))
t->temps[index] = ureg_DECL_local_temporary(t->ureg);
@@ -5129,6 +5142,7 @@ st_translate_program(
out:
if (t) {
+ free(t->temps);
free(t->insn);
free(t->labels);
free(t->constants);