[Mesa-dev] [PATCH v2 13/21] nir/linker: Add gl_nir_link_uniforms()

Neil Roberts nroberts at igalia.com
Thu Jun 7 13:13:37 UTC 2018


Timothy Arceri <tarceri at itsqueeze.com> writes:

> I still think you might be able to drop the tree without using a hash 
> table. Can't you just add an offset field to the state struct and use 
> this? You would increment it as you recurse down the arrays/structs via 
> nir_link_uniform() and you could  detect the first leaf-node once you 
> reach the inner most elements in a way similar to what link_uniforms() 
> does in with record_type in program_resource_visitor::recursion. When 
> moving to the next uniform you would just reset the offset back to 0.

Let’s walk through an example to demonstrate what needs to happen.

Imagine there is a uniform like this:

layout(location = 0) uniform struct {
        sampler2D foo[3];
        sampler2D bar[4];
} wibble[2];

This creates a total of 2*(3+4)=14 samplers. We want to group together
all of the indices for a single member so that they will be laid out in
the following order:

Index 0: wibble[0].foo[0]
Index 1: wibble[0].foo[1]
Index 2: wibble[0].foo[2]
Index 3: wibble[1].foo[0]
Index 4: wibble[1].foo[1]
Index 5: wibble[1].foo[2]
Index 6: wibble[0].bar[0]
Index 7: wibble[0].bar[1]
Index 8: wibble[0].bar[2]
Index 9: wibble[0].bar[3]
Index 10: wibble[1].bar[0]
Index 11: wibble[1].bar[1]
Index 12: wibble[1].bar[2]
Index 13: wibble[1].bar[3]

Ie, all of the foos are bunched together before all of the bars.

When we walk the type tree for wibble, it will recognise that the array
elements are not a simple type so it will create a separate uniform for
each element of wibble. That means it will visit each of foo and bar
twice.

With the current approach the first time we visit foo it will look at
all of the parents of the type to work out the total size needed for all
of the foos and reserve a continuous block of 6 indices. Then it will
reserve three of those for this instance of foo by incrementing its own
next_index entry by 3.

Next it will do the same thing for bar by reserving 8 indices out of the
global pool and setting its own next_index to 4.

Then when we handle wibble[1].foo it will recognise that its own
next_index is not zero so it will continue using the pool it already
allocated. It will take the next three out of its pool starting at the
previous value of its next_index, 3. And then it will do the same for
bar taking the next four out of the pool it already reserved.

This creates the following entries in UniformStorage:

0: loc=0, elems=3, storage offset=0, name=wibble[0].foo, fragment=0
1: loc=3, elems=4, storage offset=6, name=wibble[0].bar, fragment=6
2: loc=7, elems=3, storage offset=14, name=wibble[1].foo, fragment=3
3: loc=10, elems=4, storage offset=20, name=wibble[1].bar, fragment=10

‘loc’ is the location of the uniform and ‘fragment’ is the sampler index
allocated.

I understand how you could use something like record_type to recognise
whether it is the first time you visit a leaf node or not, but if it
isn’t the first time I don’t see how you can work out what index to use
if you only have a single counter in the state struct. I think you need
a way to find out what the start of the range was the first time you
encountered the leaf and how many times you have visited it so far.

Regards,
- Neil

>
>> 
>> Thanks for looking at the patch.
>> 
>> Regards,
>> - Neil
>> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180607/e59f4c4a/attachment.sig>


More information about the mesa-dev mailing list