[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