Timothy Arceri <tarc...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
signature.asc
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev