[PATCH 1/5] wined3d: Use a bitmask for the {v, p}s_const_f fields in struct wined3d_saved_states.

Henri Verbeet hverbeet at gmail.com
Tue Feb 11 14:49:00 CST 2020


On Tue, 11 Feb 2020 at 21:12, Matteo Bruni <matteo.mystral at gmail.com> wrote:
> 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:
> > > +static void wined3d_bitmask_set_bits(DWORD *bitmask, unsigned int offset, unsigned int count)
> > > +{
> > > +    const unsigned int word_bit_count = sizeof(*bitmask) * CHAR_BIT;
> > > +    const unsigned int shift = offset % word_bit_count;
> > > +
> > > +    bitmask += offset / word_bit_count;
> > > +    *bitmask |= ~0u >> (word_bit_count - min(count, word_bit_count)) << shift;
> > > +    ++bitmask;
> > > +    count -= min(count, word_bit_count - shift);
> > > +    if (!count)
> > > +        return;
> > > +    if (count >= word_bit_count)
> > > +    {
> > > +        memset(bitmask, 0xffu, count / CHAR_BIT);
> > > +        bitmask += count / word_bit_count;
> > > +        count = count % word_bit_count;
> > > +        if (!count)
> > > +            return;
> > > +    }
> > > +    *bitmask |= (1u << count) - 1;
> > > +}
> > Does this intentionally not handle 0 count? I also suspect this has
> > some room for simplification.
>
> I wrote this patch a long time ago and looked through it so many times
> that it's hard for me to see problems. That's where review helps I
> guess :)
> I think I intentionally don't handle 0 count, I guess I could add an
> assert() at least. WRT simplification, this was originally written
> when I was looking into a game that sets most (or all) the float
> constants in one go so it somewhat reflects that (e.g. I think I
> started from the memset() part and then tacked the rest around it
> afterwards). I'll try to simplify it but I might ask for more specific
> suggestions if I can't find anything substantial...

I was mostly thinking you could get rid of the min() bits at the start
by doing something like the following:

    mask = ~0u << shift;
    mask_size = word_bit_count - shift;
    last_mask = (1u << ((start + count) & (word_bit_count - 1))) - 1;
    if (mask_size < count)
    {
        *bitmap |= mask;
        ++bitmap;
        count -= mask_size;
        mask = ~0u;
    }
...
    if (count)
        *bitmap |= (mask & last_mask);

It probably ends up being a little longer, but seems more
straightforward and happens to handle 0 count as well.



More information about the wine-devel mailing list