On Mon, 10 Feb 2020 at 23:06, Matteo Bruni mbruni@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.