summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Forbes <chrisf@ijw.co.nz>2013-09-15 22:25:45 +1200
committerChris Forbes <chrisf@ijw.co.nz>2013-09-26 18:24:22 +1200
commitfe2528c0b69d5719b15d926ada9424cac7569b9c (patch)
tree68db9405f6eebadab83caa0f5e2e2f1c24c7063b
parentd83ef680e2c6d11c446aae16a65445f12984fb85 (diff)
i965: Fix cube array coordinate normalization
Hardware requires the magnitude of the largest component to not exceed 1; brw_cubemap_normalize ensures that this is the case. Unfortunately, we would previously multiply the array index for cube arrays by the normalization factor. The incorrect array index would then cause the sampler to attempt to access either the wrong cube, or memory outside the cube surface entirely, resulting in garbage rendering or in the worst case, hangs. Alter the normalization pass to only multiply the .xyz components. Fixes broken rendering in the arb_texture_cube_map_array-cubemap piglit, which was recently adjusted to provoke this behavior. V2: Fix indent. Signed-off-by: Chris Forbes <chrisf@ijw.co.nz> Cc: "9.2" mesa-stable@lists.freedesktop.org Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/mesa/drivers/dri/i965/brw_cubemap_normalize.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_cubemap_normalize.cpp b/src/mesa/drivers/dri/i965/brw_cubemap_normalize.cpp
index 9e149f96f53..46155fb43af 100644
--- a/src/mesa/drivers/dri/i965/brw_cubemap_normalize.cpp
+++ b/src/mesa/drivers/dri/i965/brw_cubemap_normalize.cpp
@@ -32,6 +32,7 @@
#include "glsl/glsl_types.h"
#include "glsl/ir.h"
+#include "program/prog_instruction.h" /* For WRITEMASK_* */
class brw_cubemap_normalize_visitor : public ir_hierarchical_visitor {
public:
@@ -88,11 +89,16 @@ brw_cubemap_normalize_visitor::visit_leave(ir_texture *ir)
glsl_type::float_type,
expr, NULL);
- deref = new(mem_ctx) ir_dereference_variable(var);
- ir->coordinate = new(mem_ctx) ir_expression(ir_binop_mul,
- ir->coordinate->type,
- deref,
- expr);
+ /* coordinate.xyz *= expr */
+ assign = new(mem_ctx) ir_assignment(
+ new(mem_ctx) ir_dereference_variable(var),
+ new(mem_ctx) ir_expression(ir_binop_mul,
+ ir->coordinate->type,
+ new(mem_ctx) ir_dereference_variable(var),
+ expr));
+ assign->write_mask = WRITEMASK_XYZ;
+ base_ir->insert_before(assign);
+ ir->coordinate = new(mem_ctx) ir_dereference_variable(var);
progress = true;
return visit_continue;