i965: Fix variable indexing of sampler arrays under non-uniform control flow.

ARB_gpu_shader5 requires sampler 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 test cases:
  arb_gpu_shader5/execution/sampler_array_indexing/fs-nonuniform-control-flow.shader_test
  arb_gpu_shader5/execution/sampler_array_indexing/vs-nonuniform-control-flow.shader_test

part of the series:
  http://lists.freedesktop.org/archives/piglit/2015-February/014615.html

Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
Francisco Jerez
2015-02-19 14:49:10 +02:00
parent b234537cc3
commit e1ae0c3bc3
3 changed files with 8 additions and 6 deletions
+2 -2
View File
@@ -1707,8 +1707,8 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
/* Emit code to evaluate the actual indexing expression */
sampler_reg = vgrf(glsl_type::uint_type);
emit(ADD(sampler_reg, src, fs_reg(sampler)))
->force_writemask_all = true;
emit(ADD(sampler_reg, src, fs_reg(sampler)));
emit_uniformize(sampler_reg, sampler_reg);
break;
}
+3 -2
View File
@@ -2317,8 +2317,9 @@ fs_visitor::visit(ir_texture *ir)
/* Emit code to evaluate the actual indexing expression */
nonconst_sampler_index->accept(this);
fs_reg temp = vgrf(glsl_type::uint_type);
emit(ADD(temp, this->result, fs_reg(sampler)))
->force_writemask_all = true;
emit(ADD(temp, this->result, fs_reg(sampler)));
emit_uniformize(temp, temp);
sampler_reg = temp;
} else {
/* Single sampler, or constant array index; the indexing expression
@@ -2518,8 +2518,9 @@ vec4_visitor::visit(ir_texture *ir)
/* Emit code to evaluate the actual indexing expression */
nonconst_sampler_index->accept(this);
dst_reg temp(this, glsl_type::uint_type);
emit(ADD(temp, this->result, src_reg(sampler)))
->force_writemask_all = true;
emit(ADD(temp, this->result, src_reg(sampler)));
emit_uniformize(temp, src_reg(temp));
sampler_reg = src_reg(temp);
} else {
/* Single sampler, or constant array index; the indexing expression