diff options
author | Ian Romanick <[email protected]> | 2011-11-07 10:58:00 -0800 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2011-11-09 10:50:35 -0800 |
commit | 6f5c73797087c6e7842665f84e41caedea59bb65 (patch) | |
tree | 7aa3e7015a88183c887fe95cb561a7c4cdea4eff /src/glsl | |
parent | 1d1c0fa2f31de5190909c869452ae9a2e23bba00 (diff) |
glsl: Clamp vector indices when lowering to swizzles
This prevents other code from seeing a swizzle of the 16th component
of a vector, for example.
NOTE: This is a candidate for the 7.11 branch.
Signed-off-by: Ian Romanick <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42517
Reviewed-by: Kenneth Graunke <[email protected]>
Reviewed-by: Paul Berry <[email protected]>
Tested-by: Christian Holler <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/lower_vec_index_to_swizzle.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/glsl/lower_vec_index_to_swizzle.cpp b/src/glsl/lower_vec_index_to_swizzle.cpp index c7630c28a83..46fd6ace1b6 100644 --- a/src/glsl/lower_vec_index_to_swizzle.cpp +++ b/src/glsl/lower_vec_index_to_swizzle.cpp @@ -33,6 +33,7 @@ #include "ir_visitor.h" #include "ir_optimization.h" #include "glsl_types.h" +#include "main/macros.h" /** * Visitor class for replacing expressions with ir_constant values. @@ -76,8 +77,25 @@ ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir) void *ctx = ralloc_parent(ir); this->progress = true; - return new(ctx) ir_swizzle(deref->array, - ir_constant->value.i[0], 0, 0, 0, 1); + + /* Page 40 of the GLSL 1.20 spec says: + * + * "When indexing with non-constant expressions, behavior is undefined + * if the index is negative, or greater than or equal to the size of + * the vector." + * + * The quoted spec text mentions non-constant expressions, but this code + * operates on constants. These constants are the result of non-constant + * expressions that have been optimized to constants. The common case here + * is a loop counter from an unrolled loop that is used to index a vector. + * + * The ir_swizzle constructor gets angry if the index is negative or too + * large. For simplicity sake, just clamp the index to [0, size-1]. + */ + const int i = MIN2(MAX2(ir_constant->value.i[0], 0), + (deref->array->type->vector_elements - 1)); + + return new(ctx) ir_swizzle(deref->array, i, 0, 0, 0, 1); } ir_visitor_status |