[PATCH 3/5] wined3d: Optimize scanning changed shader constants in wined3d_device_apply_stateblock().

Matteo Bruni matteo.mystral at gmail.com
Tue Feb 11 11:43:17 CST 2020


On Tue, Feb 11, 2020 at 5:33 PM Henri Verbeet <hverbeet at gmail.com> wrote:
>
> On Mon, 10 Feb 2020 at 23:06, Matteo Bruni <mbruni at codeweavers.com> wrote:
> > +typedef HRESULT (CDECL *wined3d_device_shader_constant_setter)(struct wined3d_device *device,
> > +        unsigned int start_idx, unsigned int count, const void *constants);
> > +
> > +static void device_apply_shader_constants(struct wined3d_device *device,
> > +        const struct wined3d_stateblock_state *state,
> > +        DWORD *bitmap, unsigned int bit_count, const void *data, unsigned int stride,
> > +        wined3d_device_shader_constant_setter shader_constant_setter)
> > +{
> > +    const unsigned int word_bit_count = sizeof(DWORD) * CHAR_BIT;
> > +    unsigned int i, j, idx, start, last;
> > +    const BYTE *byte_data = data;
> > +    DWORD map;
> > +
> > +    start = last = ~0u;
> > +    for (i = 0; i < (bit_count + word_bit_count - 1) / word_bit_count; ++i)
> > +    {
> > +        map = bitmap[i];
> > +
> > +        if (map == ~0u)
> > +        {
> > +            if (last != ~0u && last != i * word_bit_count - 1)
> > +            {
> > +                shader_constant_setter(device, start, last - start + 1, &byte_data[start * stride]);
> > +                start = i * word_bit_count;
> > +            }
> > +            if (start == ~0u)
> > +                start = i * word_bit_count;
> > +            last = i * word_bit_count + word_bit_count - 1;
> > +            continue;
> > +        }
> > +        while (map)
> > +        {
> > +            j = wined3d_bit_scan(&map);
> > +            idx = i * word_bit_count + j;
> > +
> > +            if (start == ~0u)
> > +            {
> > +                start = last = idx;
> > +            }
> > +            else if (last != idx - 1)
> > +            {
> > +                shader_constant_setter(device, start, last - start + 1, &byte_data[start * stride]);
> > +                start = last = idx;
> > +            }
> > +            else
> > +            {
> > +                last = idx;
> > +            }
> > +        }
> > +    }
> > +    if (start != ~0u)
> > +        shader_constant_setter(device, start, last - start + 1, &byte_data[start * stride]);
> > +}
> > +
> This looks like it's a fair bit more complicated than it needs to be.
> I think the primitives you want are something like the following:
>
>     unsigned int wined3d_bitmap_ffs(uint32_t *bitmap, unsigned int
> start, unsigned int count);
>     unsigned int wined3d_bitmap_ffz(uint32_t *bitmap, unsigned int
> start, unsigned int count);
>
> and then you can extract the ranges relatively trivially.

Oh, interesting. I'll update the patch along those lines and see what
the end result looks like.



More information about the wine-devel mailing list