[PATCH 5/5] d3dcompiler: Avoid using 1-dimensional vectors as expression types.
Matteo Bruni
matteo.mystral at gmail.com
Fri Jun 26 12:54:33 CDT 2020
On Fri, Jun 26, 2020 at 7:14 PM Zebediah Figura <zfigura at codeweavers.com> wrote:
>
> On 6/26/20 11:28 AM, Matteo Bruni wrote:
> > On Fri, Jun 26, 2020 at 6:02 PM Zebediah Figura <zfigura at codeweavers.com> wrote:
> >>
> >> On 6/26/20 10:56 AM, Matteo Bruni wrote:
> >>> On Tue, Jun 23, 2020 at 12:48 AM Zebediah Figura <z.figura12 at gmail.com> wrote:
> >>>>
> >>>> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> >>>> ---
> >>>> dlls/d3dcompiler_43/hlsl.y | 19 +++++++++++++++----
> >>>> dlls/d3dcompiler_43/utils.c | 11 ++++++++---
> >>>> 2 files changed, 23 insertions(+), 7 deletions(-)
> >>>>
> >>>> diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
> >>>> index 21828337939..27aab195b25 100644
> >>>> --- a/dlls/d3dcompiler_43/hlsl.y
> >>>> +++ b/dlls/d3dcompiler_43/hlsl.y
> >>>> @@ -416,11 +416,17 @@ static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
> >>>> struct hlsl_ir_node *val, struct source_location *loc)
> >>>> {
> >>>> struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
> >>>> + struct hlsl_type *data_type;
> >>>>
> >>>> if (!swizzle)
> >>>> return NULL;
> >>>> - init_node(&swizzle->node, HLSL_IR_SWIZZLE,
> >>>> - new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc);
> >>>> +
> >>>> + if (components == 1)
> >>>> + data_type = hlsl_ctx.builtin_types.scalar[val->data_type->base_type];
> >>>> + else
> >>>> + data_type = hlsl_ctx.builtin_types.vector[val->data_type->base_type][components - 1];
> >>>> +
> >>>> + init_node(&swizzle->node, HLSL_IR_SWIZZLE, data_type, *loc);
> >>>> swizzle->val = val;
> >>>> swizzle->swizzle = s;
> >>>> return swizzle;
> >>>> @@ -2488,6 +2494,7 @@ postfix_expr: primary_expr
> >>>> for (i = 0; i < $4.args_count; ++i)
> >>>> {
> >>>> struct hlsl_ir_node *arg = $4.args[i];
> >>>> + struct hlsl_type *data_type;
> >>>> unsigned int width;
> >>>>
> >>>> if (arg->data_type->type == HLSL_CLASS_OBJECT)
> >>>> @@ -2504,8 +2511,12 @@ postfix_expr: primary_expr
> >>>> continue;
> >>>> }
> >>>>
> >>>> - if (!(arg = add_implicit_conversion($4.instrs, arg,
> >>>> - hlsl_ctx.builtin_types.vector[$2->base_type][width - 1], &arg->loc)))
> >>>> + if (width == 1)
> >>>> + data_type = hlsl_ctx.builtin_types.scalar[$2->base_type];
> >>>> + else
> >>>> + data_type = hlsl_ctx.builtin_types.vector[$2->base_type][width - 1];
> >>>> +
> >>>> + if (!(arg = add_implicit_conversion($4.instrs, arg, data_type, &arg->loc)))
> >>>> continue;
> >>>>
> >>>> if (!(assignment = new_assignment(var, NULL, arg,
> >>>> diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
> >>>> index 30aa9de1dd4..4f0556103ab 100644
> >>>> --- a/dlls/d3dcompiler_43/utils.c
> >>>> +++ b/dlls/d3dcompiler_43/utils.c
> >>>> @@ -1294,7 +1294,7 @@ static struct hlsl_type *expr_common_type(struct hlsl_type *t1, struct hlsl_type
> >>>> }
> >>>> }
> >>>>
> >>>> - if (type == HLSL_CLASS_SCALAR)
> >>>> + if (type == HLSL_CLASS_SCALAR || (type == HLSL_CLASS_VECTOR && dimx == 1))
> >>>> return hlsl_ctx.builtin_types.scalar[base];
> >>>> if (type == HLSL_CLASS_VECTOR)
> >>>> return hlsl_ctx.builtin_types.vector[base][dimx - 1];
> >>>> @@ -1496,9 +1496,14 @@ struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lh
> >>>> d3dcompiler_free(assign);
> >>>> return NULL;
> >>>> }
> >>>> - assert(swizzle_type->type == HLSL_CLASS_VECTOR);
> >>>> + assert(swizzle_type->type == HLSL_CLASS_VECTOR || swizzle_type->type == HLSL_CLASS_SCALAR);
> >>>> if (swizzle_type->dimx != width)
> >>>> - swizzle->node.data_type = hlsl_ctx.builtin_types.vector[swizzle_type->base_type][width - 1];
> >>>> + {
> >>>> + if (width == 1)
> >>>> + swizzle->node.data_type = hlsl_ctx.builtin_types.scalar[swizzle_type->base_type];
> >>>> + else
> >>>> + swizzle->node.data_type = hlsl_ctx.builtin_types.vector[swizzle_type->base_type][width - 1];
> >>>> + }
> >>>> rhs = &swizzle->node;
> >>>> }
> >>>> else
> >>>
> >>> What do we gain with this?
> >>>
> >>
> >> Not having to deal with vec1 at codegen time, basically, or along
> >> similar lines not having superfluous instructions to cast it to scalar.
> >> Granted, it still exists, but you'd have to use it intentionally...
> >
> > My main objection is that, IIRC, we need to keep the distinction
> > anyway for uniform variables (e.g. I guess it's visible in the
> > constant table). At that point we could just keep it like that all the
> > way through the compiler.
> > WRT casts, they can be avoided by figuring out at "codegen" that they
> > are actually the same type. Again, we probably need something along
> > those lines anyway since, especially in SM1, we have to map pretty
> > much everything to float eventually.
> >
> > Notice that I can still be convinced that this patch goes in the right
> > direction...
> >
>
> It gets a little tricky, I think. Uniforms are one case and pretty
> clear-cut, i.e. you declare something as "float" or "float1".
>
> Arbitrary expressions are another. The language *does* seem to care
> about these in at least one way I could find: you can index a vector
> using [0], but not a scalar. According to this criterion, both swizzles
> and expression argument coercion count as scalars rather than vectors.
> I.e. the code
>
> uniform float1 v;
> return v.x[0];
>
> and
>
> uniform float1 v;
> uniform float s;
> return (v + s)[0];
>
> will both throw an error.
Oh, that's interesting. So the relevant part of this patch is
technically required for correctness.
> The third case in the patch above, of course, can't be tested, as it
> only has internal effect.
>
> Certainly I agree that nothing after parse time should care about the
> difference between float and float1, though. I guess we want to reduce
> any such generated casts using a copy-prop pass.
Right. My feeling is that such a pass simplifying redundant casts
effectively covers all other cases but I certainly haven't thought it
through.
More information about the wine-devel
mailing list