[v4 PATCH] d3d10/effect: Add initial support for indexing expressions.

Matteo Bruni matteo.mystral at gmail.com
Mon Nov 15 13:04:39 CST 2021


On Tue, Nov 9, 2021 at 12:40 PM Nikolay Sivov <nsivov at codeweavers.com> wrote:
>
> Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
> ---
>  dlls/d3d10/effect.c       | 595 +++++++++++++++++++++++++++++++++++++-
>  dlls/d3d10/tests/effect.c | 147 ++++++++++
>  2 files changed, 734 insertions(+), 8 deletions(-)
>
> diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
> index 78a3d0c386a..3f35e9cc28a 100644
> --- a/dlls/d3d10/effect.c
> +++ b/dlls/d3d10/effect.c

> +static HRESULT d3d10_effect_preshader_eval(struct d3d10_effect_preshader *p)
> +{
> +    unsigned int i, j, regt, offset, instr_count, input_count;
> +    const DWORD *ip = ID3D10Blob_GetBufferPointer(p->code);
> +    float *dst, *args[4], *retval;
> +    struct preshader_instr ins;
> +
> +    dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_RESULT, 0);
> +    memset(dst, 0, sizeof(float) * p->reg_tables[D3D10_REG_TABLE_RESULT].count);
> +
> +    /* Update constant buffer */
> +    dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_CB, 0);
> +    for (i = 0; i < p->vars_count; ++i)
> +    {
> +        struct d3d10_ctab_var *v = &p->vars[i];
> +        memcpy(dst + v->offset, v->v->buffer->u.buffer.local_buffer + v->v->buffer_offset,
> +                v->length * sizeof(*dst));
> +    }
> +
> +    instr_count = *ip++;
> +
> +    for (i = 0; i < instr_count; ++i)
> +    {
> +        *(DWORD *)&ins = *ip++;
> +        input_count = *ip++;
> +
> +        if (input_count > ARRAY_SIZE(args))
> +        {
> +            FIXME("Unexpected argument count %u.\n", input_count);
> +            return E_FAIL;
> +        }
> +
> +        /* Arguments */
> +        for (j = 0; j < input_count; ++j)
> +        {
> +            ip++; /* TODO: argument register flags are currently ignored */
> +            regt = *ip++;
> +            offset = *ip++;
> +
> +            args[j] = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
> +        }
> +
> +        ip++; /* TODO: result register flags are currently ignored */
> +        regt = *ip++;
> +        offset = *ip++;
> +        retval = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
> +
> +        *retval = d3d10_effect_get_op_info(ins.opcode)->func(args, input_count);

Making sure I get this right: in d3d10 FXLVM all instructions /
operands are scalar, correct?

> @@ -528,24 +727,58 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende
>          property_info = &property_infos[d->id];
>
>          dst = (char *)container + property_info->offset;
> +        dst_index = (unsigned int *)((char *)container + property_info->index_offset);
>
>          switch (d->operation)
>          {
>              case D3D10_EOO_VAR:
>              case D3D10_EOO_CONST_INDEX:
>
> -                v = d->u.var.v;
> +                v = d->var.v;
>
>                  count = v->type->type_class == D3D10_SVC_VECTOR ? 4 : 1;
>
>                  for (j = 0; j < count; ++j)
>                  {
> -                    d3d10_effect_variable_get_raw_value(v, &value, d->u.var.offset + j * sizeof(value), sizeof(value));
> +                    d3d10_effect_variable_get_raw_value(v, &value, d->var.offset + j * sizeof(value), sizeof(value));
>                      d3d10_effect_read_numeric_value(value, v->type->basetype, property_info->type, dst, j);
>                  }
>
>                  break;
>
> +            case D3D10_EOO_INDEX_EXPRESSION:
> +
> +                v = d->index_expr.v;
> +
> +                if (FAILED(hr = d3d10_effect_preshader_eval(&d->index_expr.index)))
> +                {
> +                    WARN("Failed to evaluate index expression, hr %#x.\n", hr);
> +                    return;
> +                }
> +
> +                variable_idx = *d->index_expr.index.reg_tables[D3D10_REG_TABLE_RESULT].dword;
> +
> +                if (variable_idx >= v->type->element_count)
> +                {
> +                    WARN("Expression evaluated to invalid index value %u, array %s of size %u.\n",
> +                            variable_idx, debugstr_a(v->name), v->type->element_count);
> +                    return;
> +                }
> +
> +                /* Ignoring destination index here, there are no object typed array properties. */
> +                switch (property_info->type)
> +                {
> +                    case D3D10_SVT_VERTEXSHADER:
> +                    case D3D10_SVT_PIXELSHADER:
> +                    case D3D10_SVT_GEOMETRYSHADER:
> +                        *(void **)dst = v;
> +                        *dst_index = variable_idx;
> +                        break;
> +                    default:
> +                        *(void **)dst = &v->elements[variable_idx];

I guess we could have explicit D3D10_SVT_BLEND and such cases in the
switch and print a WARN for those, to be super safe.



More information about the wine-devel mailing list