[Mesa-dev] glsl2: problem (crash) with ir_vec_index_to_cond_assign

Aras Pranckevicius aras at unity3d.com
Thu Aug 19 02:37:49 PDT 2010


Hi,

I'm investigating a crash on some weird GLSL inputs. E.g. a fragment shader
like this:

vec2 nonInlinedFunction (vec2 a) {
  if (a.x < 0.0)
    return -a;
  return a*2.0;
}
void main() {
  vec2 c = vec2(0.0);
  for (int j = 0; j < 2; ++j) {
    c += nonInlinedFunction (vec2(vec2(0.0)[j])); // <- weird, but legit
  }
  gl_FragColor = vec4(c,0.0,0.0);
}

It seems that ir_vec_index_to_cond_assign can take a single instruction and
turn that into a series of instructions. Which somehow messes up the number of
arguments that seem to be coming in for ir_call later.

Caveat emptor: so far I can't repro this on Linux via piglit, but then I'm a
Linux n00b (installed VM just today, and with all the mesa/piglit/etc. things
I'm not even sure my piglit tests are using the right mesa build... it does
not help that instructions on how to build mesa seem to be outdated or
contradicting. But I digress). That is, I can only repro the crash in MSVC
build of my GLSL2 fork.

What happens is:

* After some tree grafting pass, the "weird" part becomes
  (call nonInlinedFunction (
    (swiz xx
      (array_ref (constant vec2 (0.0 0.0)) (var_ref j))
    )
  ))
  So far so good.

* Later on, ir_vec_index_to_cond_assign turns it into this:
  (call nonInlinedFunction (
      (declare (temp) int vec_index_tmp_i)
      (assign (1) (x)
        (var_ref vec_index_tmp_i)
        (var_ref j)
      )
      (declare (temp) float vec_index_tmp_v)
      (assign (expression bool == (var_ref vec_index_tmp_i) (0)) (x)
        (var_ref vec_index_tmp_v)
        (swiz x (constant vec2 (0.0 0.0)))
      )
      (assign (expression bool == (var_ref vec_index_tmp_i) (1))  (x)
        (var_ref vec_index_tmp_v)
        (swiz y (constant vec2 (0.0 0.0)))
      )
      (swiz xx (var_ref vec_index_tmp_v))
  ))

  So at this point, it looks like a call has 6 actual arguments.

* Later on, ir_copy_propagation_visitor::visit_enter (ir_call) goes
  over actual parameters and function signature parameters, and one
  iterator reaches the end while another does not. Boom!


--
Aras Pranckevicius
work: http://unity3d.com
home: http://aras-p.info


More information about the mesa-dev mailing list