summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2015-02-19 14:48:29 +0200
committerFrancisco Jerez <[email protected]>2015-05-04 17:44:17 +0300
commitb234537cc3e513ded9b5385d876e4c531f72af94 (patch)
tree9c65b436af131ceadd0e8f4ecb040764d3dfecfd /src
parent046abc998c6951ea8a4aee0a2c1b832f6c877b73 (diff)
i965: Fix variable indexing of UBO arrays under non-uniform control flow.
ARB_gpu_shader5 requires UBO array indexing expressions to be dynamically uniform, this however doesn't have any implications on the control flow that leads to the evaluation of that expression being uniform. Use emit_uniformize() to obtain an arbitrary live value from the binding table index calculation instead of assuming that the first channel is always live. Fixes the following Piglit tests: arb_gpu_shader5/execution/ubo_array_indexing/fs-nonuniform-control-flow.shader_test arb_gpu_shader5/execution/ubo_array_indexing/vs-nonuniform-control-flow.shader_test part of the series: http://lists.freedesktop.org/archives/piglit/2015-February/014616.html Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp8
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp8
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp5
3 files changed, 11 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 523e56db627..4c968f050f2 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -1407,13 +1407,13 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
const_index->u[0]);
} else {
/* The block index is not a constant. Evaluate the index expression
- * per-channel and add the base UBO index; the generator will select
- * a value from any live channel.
+ * per-channel and add the base UBO index; we have to select a value
+ * from any live channel.
*/
surf_index = vgrf(glsl_type::uint_type);
emit(ADD(surf_index, get_nir_src(instr->src[0]),
- fs_reg(stage_prog_data->binding_table.ubo_start)))
- ->force_writemask_all = true;
+ fs_reg(stage_prog_data->binding_table.ubo_start)));
+ emit_uniformize(surf_index, surf_index);
/* Assume this may touch any UBO. It would be nice to provide
* a tighter bound, but the array information is already lowered away.
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index fc05e77d32b..2128795c7dd 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1207,13 +1207,13 @@ fs_visitor::visit(ir_expression *ir)
const_uniform_block->value.u[0]);
} else {
/* The block index is not a constant. Evaluate the index expression
- * per-channel and add the base UBO index; the generator will select
- * a value from any live channel.
+ * per-channel and add the base UBO index; we have to select a value
+ * from any live channel.
*/
surf_index = vgrf(glsl_type::uint_type);
emit(ADD(surf_index, op[0],
- fs_reg(stage_prog_data->binding_table.ubo_start)))
- ->force_writemask_all = true;
+ fs_reg(stage_prog_data->binding_table.ubo_start)));
+ emit_uniformize(surf_index, surf_index);
/* Assume this may touch any UBO. It would be nice to provide
* a tighter bound, but the array information is already lowered away.
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 7e405ab6d62..f0416be3d53 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1831,12 +1831,13 @@ vec4_visitor::visit(ir_expression *ir)
const_uniform_block->value.u[0]);
} else {
/* The block index is not a constant. Evaluate the index expression
- * per-channel and add the base UBO index; the generator will select
- * a value from any live channel.
+ * per-channel and add the base UBO index; we have to select a value
+ * from any live channel.
*/
surf_index = src_reg(this, glsl_type::uint_type);
emit(ADD(dst_reg(surf_index), op[0],
src_reg(prog_data->base.binding_table.ubo_start)));
+ emit_uniformize(dst_reg(surf_index), surf_index);
/* Assume this may touch any UBO. It would be nice to provide
* a tighter bound, but the array information is already lowered away.