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

Henri Verbeet hverbeet at gmail.com
Tue Feb 11 10:33:05 CST 2020


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.



More information about the wine-devel mailing list