[Mesa-dev] [PATCH 4/5] glsl: Vectorize multiple scalar assignments
Ian Romanick
idr at freedesktop.org
Fri Jan 10 17:53:10 PST 2014
On 01/10/2014 03:27 PM, Matt Turner wrote:
> On Thu, Jan 9, 2014 at 11:28 AM, Ian Romanick <idr at freedesktop.org> wrote:
>> On 01/08/2014 12:43 PM, Matt Turner wrote:
>>> +/**
>>> + * \file opt_vectorize.cpp
>>> + *
>>> + * Combines scalar assignments of the same expression (modulo swizzle) to
>>> + * multiple channels of the same variable into a single vectorized expression
>>> + * and assignment.
>>> + *
>>> + * Many generated shaders contain scalarized code. That is, they contain
>>> + *
>>> + * r1.x = log2(v0.x);
>>> + * r1.y = log2(v0.y);
>>> + * r1.z = log2(v0.z);
>>> + *
>>> + * rather than
>>> + *
>>> + * r1.xyz = log2(v0.xyz);
>>> + *
>>> + * We look for consecutive assignments of the same expression (modulo swizzle)
>>> + * to each channel of the same variable.
>>> + *
>>> + * For instance, we want to convert these three scalar operations
>>> + *
>>> + * (assign (x) (var_ref r1) (expression float log2 (swiz x (var_ref v0))))
>>> + * (assign (y) (var_ref r1) (expression float log2 (swiz y (var_ref v0))))
>>> + * (assign (z) (var_ref r1) (expression float log2 (swiz z (var_ref v0))))
>>> + *
>>> + * into a single vector operation
>>> + *
>>> + * (assign (xyz) (var_ref r1) (expression vec3 log2 (swiz xyz (var_ref v0))))
>>
>> I think it's worth adding a note that this pass only attempts to combine
>> assignments that are sequential.
>
> That comment block already says that:
>
> + * We look for consecutive assignments of the same expression (modulo swizzle)
> + * to each channel of the same variable.
I guess I overlooked that word. :(
> I'll change the first comment to use the word consecutive.
>
>> The above example gets fully
>> vectorized, but this sequence would not:
>>
>> (assign (x) (var_ref r1) (expression float log2 (swiz x (var_ref v0))))
>> (assign (x) (var_ref r2) (expression float log2 (swiz y (var_ref v0))))
>> (assign (y) (var_ref r1) (expression float log2 (swiz z (var_ref v0))))
>> (assign (y) (var_ref r2) (expression float log2 (swiz w (var_ref v0))))
>>
>> I think this will also break on code like
>>
>> (assign (x) (var_ref r1) (expression float log2 (swiz w (var_ref r1))))
>> (assign (y) (var_ref r1) (expression float log2 (swiz z (var_ref r1))))
>> # r1.xy have different values now.
>> (assign (z) (var_ref r1) (expression float log2 (swiz y (var_ref r1))))
>> (assign (w) (var_ref r1) (expression float log2 (swiz x (var_ref r1))))
>>
>> Maybe just skip assignments where the LHS also appears in the RHS for
>> now? Or does the check write_mask_matches_swizzle take care of this?
>
> It won't break because the code rejects expressions that contain
> swizzles that don't match the LHS's write mask. See the call to
> write_mask_matches_swizzle().
>
> The good thing about this is that we can combine expressions that use
> the LHS, like
>
> (assign (x) (var_ref r1) (expression float log2 (swiz x (var_ref r1))))
> (assign (y) (var_ref r1) (expression float log2 (swiz y (var_ref r1))))
Okay... that's what I thought, but I wanted to be sure.
With the slight tweak to the header comment (that you mention above),
patches 2, 4, and 5 are
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
This means we also won't vectorize things like
(assign (x) (var_ref r1) (expression float * (swiz x (var_ref r1)) (swiz x (var_ref r2))))
(assign (y) (var_ref r1) (expression float * (swiz y (var_ref r1)) (swiz x (var_ref r2))))
(assign (z) (var_ref r1) (expression float * (swiz z (var_ref r1)) (swiz x (var_ref r2))))
(assign (w) (var_ref r1) (expression float * (swiz w (var_ref r1)) (swiz x (var_ref r2))))
Right? If there are occurances of that pattern in shaderdb, that may
be an opportunity for some follow-on work...
More information about the mesa-dev
mailing list