Skip to content

Values for certain types of uniforms within UBOs are shown incorrectly #277

Description

@mixtur

I was using Spector.js Chrome extension to debug our migration to UBOs and stumbled upon this.

We have the following uniform block:

layout(std140) uniform DirectLightShadowCastersUBO {
    float frustumSplits[3];
    int directShadowCastersMask[1];
    mat4 directShadowCastersTransforms[3];
};

And spector shows the following for frustumSplits
image

The displayed value is 0.1683, 0, 0 which is wrong. The last two values shouldn't be zeroes.
I think Spector is ignoring arrayStride here, because when I put some numbers into the buffer one after another I can actually see them in Spector.

Activity

  1. mixtur commented on Aug 23, 2023

    @mixtur
    Author

    Note layout(std140) in the shader code - it should make the layout implementation independent, but if you want, you can try it yourself https://cib3.webgears.app/3D-Engine/228e665dc1d4cd9fd12ab71a4dbcf5abd64e26e3/shadows.html (look for draw calls with PBR_MESH_SHADER in shader names) The link is only going to be alive for a few days maximum.

    Though judging by the implementation of getUboValue it is expected that there are zeroes.

    public getUboValue(bindingPoint: number, offset: number, size: number, type: number): any {
    const uboType = DrawCallUboInputState.uboTypes[type];
    if (!uboType) {
    return undefined;
    }
    const destination = new uboType.arrayBufferView(size * uboType.lengthMultiplier);
    const context2 = this.context as WebGL2RenderingContext;
    const ownerbuffer = context2.getIndexedParameter(WebGlConstants.UNIFORM_BUFFER_BINDING.value, bindingPoint);
    if (ownerbuffer) {
    const startOffset = context2.getIndexedParameter(WebGlConstants.UNIFORM_BUFFER_START.value, bindingPoint);
    const boundBuffer = context2.getParameter(WebGlConstants.UNIFORM_BUFFER_BINDING.value);
    try {
    context2.bindBuffer(WebGlConstants.UNIFORM_BUFFER.value, ownerbuffer);
    context2.getBufferSubData(WebGlConstants.UNIFORM_BUFFER.value, startOffset + offset, destination);
    }
    catch (e) {
    // Prevent back fromats to break the capture.
    return undefined;
    }
    if (boundBuffer) {
    context2.bindBuffer(WebGlConstants.UNIFORM_BUFFER.value, boundBuffer);
    }
    }
    return Array.prototype.slice.call(destination);

    In case of float x[3] the layout is the following:

    [ 4 bytes x[0], 12 bytes to satisfy alignment,
      4 bytes x[1], 12 bytes to satisfy alignment,
      4 bytes x[2], 12 bytes padding,
      ]
    

    The implementation simply does getBufferSubdata and then seems to do nothing with it. Assuming uboType.lengthMultiplier is 1 and size is 3. It should indeed read the first float and two zero-paddings immediately following it.

  2. mixtur commented on Aug 23, 2023

    @mixtur
    Author

    According to the spec https://registry.khronos.org/OpenGL/extensions/ARB/ARB_uniform_buffer_object.txt column-major matrices are treated as arrays of columns regardless of the dimensions. And array elements are vec4-aligned. So mat4x2 is taking as much space as mat4.

    Row-major matrices are the same except they should be treated as arrays of rows.

    Although today I discovered that when on NVidia GPUs + Chrome row-major case does something else. As well as Android on Mali G68. So yeah. It seems that this stuff is still implementation-defined to some extent. Or maybe I am using the wrong spec :)

  3. sebavan commented on Aug 30, 2023

    @sebavan
    Member

    This is a really interesting one indeed :-)

    @JannikGM, thanks a lot for your proposal here, this is going in the right direction and yes it was a complete oversight on my side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions