[Mesa-dev] [PATCH 19/26] nir/linker: use only the array element type for array of ssbo/ubo
Alejandro Piñeiro
apinheiro at igalia.com
Tue Sep 25 14:48:36 UTC 2018
On 20/09/18 00:22, Timothy Arceri wrote:
>
>
> On 19/9/18 11:10 pm, Alejandro Piñeiro wrote:
>>
>> On 19/09/18 14:09, Timothy Arceri wrote:
>>> On 19/9/18 7:59 pm, Alejandro Piñeiro wrote:
>>>> On 19/09/18 07:20, Timothy Arceri wrote:
>>>>> On 16/9/18 2:18 am, Alejandro Piñeiro wrote:
>>>>>> For this interfaces, the inner members are added only once as
>>>>>> uniforms
>>>>>> or resources, in opposite to other cases, like a uniform array of
>>>>>> structs.
>>>>>> ---
>>>>>> src/compiler/glsl/gl_nir_link_uniforms.c | 26
>>>>>> ++++++++++++++++++++++++--
>>>>>> 1 file changed, 24 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c
>>>>>> b/src/compiler/glsl/gl_nir_link_uniforms.c
>>>>>> index 00995fb3f76..c692cd0171f 100644
>>>>>> --- a/src/compiler/glsl/gl_nir_link_uniforms.c
>>>>>> +++ b/src/compiler/glsl/gl_nir_link_uniforms.c
>>>>>> @@ -498,11 +498,33 @@ gl_nir_link_uniforms(struct gl_context *ctx,
>>>>>> state.current_var = var;
>>>>>> + /*
>>>>>> + * From OpenGL 4.6 spec, section 7.3.1.1, "Naming Active
>>>>>> Resources":
>>>>>> + *
>>>>>> + * "* For an active shader storage block member declared
>>>>>> as an
>>>>>> + * array of an aggregate type, an entry will be
>>>>>> generated only
>>>>>> + * for the first array element, regardless of its
>>>>>> type. Such
>>>>>> + * block members are referred to as top-level arrays.
>>>>>> If the
>>>>>> + * block member is an aggregate type, the enumeration
>>>>>> rules are
>>>>>> + * then applied recursively.
>>>>>> + * * For an active interface block not declared as an
>>>>>> array of
>>>>>> + * block instances, a single entry will be generated,
>>>>>> using the
>>>>>> + * block name from the shader source."
>>>>>> + *
>>>>>> + * So for the UBO and SSBO case, we expand only the array
>>>>>> element
>>>>>> + * type.
>>>>>> + */
>>>>>> + const struct glsl_type *type = var->type;
>>>>>> + if (nir_variable_is_in_block(var) &&
>>>>>> + glsl_type_is_array(type)) {
>>>>>> + type = glsl_get_array_element(type);
>>>>>
>>>>> This also strips away vector and matrix type information while
>>>>> leaving
>>>>> arrays for anything but a single dimension array.
>>>>
>>>> Well, but the idea behind this patch is getting a single dimension
>>>> array.
>>>
>>> I think you mean getting a single element of an array?
>>
>> Perhaps.
>>
>>>
>>>> We are using the type to populate the uniforms, and as mentioned
>>>> on the spec quote, for ubo/ssbo and recursively for his entries, it is
>>>> done just once, no matter the dimension of the ubo/ssbo array.
>>>>
>>>> Also not sure why do you mean that we would lose matrix and vector
>>>> type
>>>> information. Could you give an example.
>>>
>>> The code for glsl_get_array_element() is:
>>>
>>> const glsl_type *
>>> glsl_get_array_element(const glsl_type* type)
>>> {
>>> if (type->is_matrix())
>>> return type->column_type();
>>> else if (type->is_vector())
>>> return type->get_scalar_type();
>>> return type->fields.array;
>>> }
>>>
>>> I was thinking you might end up stripping away the vec and matrix type
>>> but as you have glsl_type_is_array(type) in the if condition it is
>>> fine.
>>
>> Ok.
>>
>>>
>>>>
>>>> FWIW, this patch is needed to get this test working:
>>>> https://github.com/Igalia/piglit/blob/arb_gl_spirv-series5-ubo-ssbo-v1/tests/spec/arb_gl_spirv/execution/ubo/array-complex.shader_test
>>>>
>>>>
>>>>
>>>> and just in case, I have just writing a similar test, slightly more
>>>> complex, but with array members and array of matrices members:
>>>>
>>>> https://github.com/Igalia/piglit/blob/arb_gl_spirv-series5-ubo-ssbo-v1/tests/spec/arb_gl_spirv/execution/ubo/array-complex-2.shader_test
>>>>
>>>>
>>>>
>>>> And the uniform and variable count is the same on both GLSL and
>>>> SPIR-V.
>>>>
>>>>>
>>>>> Are you sure you don't want the following instead?
>>>>>
>>>>> type = glsl_get_array_element(type);
>>>>
>>>> Sorry, but isn't that what we are already doing? Or do you mean
>>>> that we
>>>> should made the call always, without the is_in_block and is_array
>>>> checks?
>>>
>>> Apologizes I pasted the wrong thing I meant:
>>>
>>> type = glsl_without_array(type);
>>
>> Ok, later today, or tomorrow, I will try with this one.
>
> As I said below on closer look I don't actually think this is what you
> want.
>
>>
>>>
>>> However looking more closely at the code and the spec I see that's not
>>> what you want.
>>>
>>> However I'm starting to think the quote from the spec and this code
>>> have nothing to do with each other.
>>
>> Yes, probably the spec quote is not the best one. We know what the
>> behaviour should be (based on comments at the GLSL linker, how
>> uniformstorage is populated on GLSL, and the program interface queries),
>> so I thought that was the spec quote justifying it. Now that you mention
>> it, and re-reading, it is true that's not perhaps the best quote
>> justifying it.
>>
>>>
>>> The spec is taking about top level block member arrays. For example:
>>>
>>> layout (std140, binding = 5, row_major) uniform ComponentsBlock
>>> {
>>> float c1[3];
>>> } components;
>>>
>>> However neither of the examples you gave have top level arrays:
>>>
>>> layout (std140, binding = 5, row_major) uniform ComponentsBlock
>>> {
>>> float c1;
>>> vec2 c2;
>>> S s;
>>> } components[2];
>>>
>>> My guess is you are using this to remove the array from the block
>>> itself which is applied when the block is split into separate vars.
>>> However the logic in this patch will fail when you have arrays of
>>> arrays for example:
>>
>> Thanks for mentioning AOA. I have just sent an email replying the first
>> patch of the series. AOA is not supported with this series. And the
>> first step is adding the support on the spirv to nir pass, so right now
>> an aoa of ubos test will not run this code.
>>
>>>
>>> layout (std140, binding = 5, row_major) uniform ComponentsBlock
>>> {
>>> float c1;
>>> vec2 c2;
>>> S s;
>>> } components[2][2];
>>>
>>> Or even something like:
>>>
>>> layout (std140, binding = 5, row_major) uniform ComponentsBlock
>>> {
>>> float c1[3];
>>> vec2 c2[3];
>>> S s[3];
>>> } components[2];
>>>
>>> It's late here and I've only skimmed over other patches in the series
>>> so if I'm missing something please correct me.
>>
>> See my previous comment. I forgot to mention that AOA of ubos/ssbos are
>> not supported yet. Sorry for that.
Finally was able to check this. Sorry for needing so much time, XDC
about to happen.
>
> This last one is not technically an array of arrays and should be
> handled by this series IMO.
I have updated the test which included a more complex array of ubo, that
includes something similar to the last one. That is working too, both
with get_array_element and without_array. The issue is that although on
the spec quote I used talk about members of the ssbo/block, those
methods were not removing it recursively. And as you say below, what we
just want it to remove the array of the block.
So in the end I think that the problem is with the spec quote I used,
and not with the code itself. Sorry for all the noise. In any case, as I
need to update the patch to include new spec quotes, I will use
glsl_without_array, as it looks more natural for that case.
>
> This patch just doesn't feel right to me. I can understand removing
> the array from the block. But removing the array from the member is
> not what we do in the GLSL linker as far as I can tell.
Yes, you are right. We don't want, and as I said, we were not even
removing, the array from the member.
BR
More information about the mesa-dev
mailing list