1

I just wrote a demo from https://www.khronos.org/registry/webgl/sdk/tests/conformance2/glsl3/matrix-row-major.html?webglVersion=2&dumpShaders=undefined&quiet=0:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Row-major matrix test</title>
  <link rel="stylesheet" href="https://www.khronos.org/registry/webgl/sdk/tests/resources/js-test-style.css" />
  <script src="https://www.khronos.org/registry/webgl/sdk/tests/js/js-test-pre.js"></script>
  <script src="https://www.khronos.org/registry/webgl/sdk/tests/js/webgl-test-utils.js"></script>
  <script src="https://www.khronos.org/registry/webgl/sdk/tests/js/glsl-conformance-test.js"></script>
</head>

<body>
  <div id="description"></div>
  <div id="console"></div>
  <script id="vshaderUniformMatrixRowMajor" type="x-shader/x-vertex">#version 300 es
out vec2 pos;
in vec4 vPosition;
in vec2 texCoord0;
void main()
{
  pos = texCoord0;
  pos.y = 1.0 - pos.y;
  gl_Position = vPosition;
}
</script>
  <script id="fshaderUniformMatrixRowMajor" type="x-shader/x-fragment">#version 300 es
precision mediump float;
in highp vec2 pos;
layout (location = 0) out vec4 my_FragColor;
uniform vec4 m[4];
layout(std140, row_major) uniform type_m2 {
  mat4 mat;
} m2;
void main()
{
  my_FragColor = vec4(m2.mat[int(floor(pos.x * 4.0))][int(floor(pos.y * 4.0))], 0.0, 0.0, 1.0);
}
</script>
  <script type="application/javascript">
    "use strict";
    description("Row-major matrix layouts should work.");

    GLSLConformanceTester.runRenderTests([
      {
        vShaderId: 'vshaderUniformMatrixRowMajor',
        vShaderSuccess: true,
        fShaderId: 'fshaderUniformMatrixRowMajor',
        fShaderSuccess: true,
        linkSuccess: true,
        passMsg: '',
        uniformBlocks: [{
          name: "type_m2", value: new Float32Array([
            0, 0.2, 0.4, 0.6,
            1, 0.1, 0.3, 0.5,
            0, 0, 0, 0,
            1, 1, 1, 1,
          ])
        }]
      }
    ], 2);
  </script>
</body>

</html>

On win10 Chrome 81.0.4044.129

I got the result: Shader with row_major qualifier

Shader with row_major qualifier

I cannot figure out why it looks like this.

When I remove the row_major qualifier, I got another result:

Shader without row_major qualifier ( Do not care about the html wording in the image below, this is column_major )

Shader without row_major qualifier

And this is expected result.


UPDATE

To make things clear: My question is that two result should be transposed from each other since they use the same matrix data. The shader tries to paint each float number in matrix which ranges from 0 to 1 to the red channel. However shader with row_major (the first result) shows that the element in matrix is either 0 or 1, but this is not the fact. And the second result exactly do what is expected.

Jian Wang
  • 41
  • 4

1 Answers1

1

Sorry I about my previous answer. I didn't look close enough.

This looks like a bug in various drivers.

I tried this

const vs = `#version 300 es
layout(location = 0) in vec4 position;
void main () {
  gl_Position = position;
  gl_PointSize = 128.0;
}
`;
function getFS(mode) {
  return `#version 300 es
precision mediump float;
layout (location = 0) out vec4 my_FragColor;
layout(std140${mode}) uniform type_m2 {
  mat4 mat;
} m2;
void main()
{
  vec2 pos = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);
  int major = int(pos.x * 4.0);
  int minor = int(pos.y * 4.0);
  my_FragColor = vec4(m2.mat[major][minor], m2.mat[0][0], 0, 1.0);
}
`;
}

const gl = document.querySelector('canvas').getContext('webgl2');

test(-0.5, '');
test( 0.5, ', row_major');

function test(x, mode) {
  const prgInfo = twgl.createProgramInfo(gl, [vs, getFS(mode)]);

  gl.vertexAttrib1f(0, x);
  const uboInfo = twgl.createUniformBlockInfo(gl, prgInfo, "type_m2");

  gl.useProgram(prgInfo.program);
  twgl.setBlockUniforms(uboInfo, {
    mat: [
      0, 0, 0, 0,
      1, 1, 0, 0,
      0, 0, 0, 0,
      1, 1, 1, 1,
    ],
  });
  twgl.setUniformBlock(gl, prgInfo, uboInfo);
  gl.drawArrays(gl.POINTS, 0, 1);
}
canvas { background: #EEE; }
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

on a Macbook Pro (NVidia) I get these wrong results

enter image description here

on Windows 10 PC (NVidia) I get these correct results

enter image description here

on my Android Pixel 2 XL I get these wrong results

enter image description here

On a Macbook Air (Intel) I get these wrong results

enter image description here

Maybe this is not supposed to work. According to the spec

12.30 Dynamic Indexing

For GLSL ES 1.00, support of dynamic indexing of arrays, vectors and matrices was not mandated because it was not directly supported by some implementations. Software solutions (via program transforms) exist for a subset of cases but lead to poor performance.

Should support for dynamic indexing be mandated for GLSL ES 3.00?

RESOLUTION: Mandate support for dynamic indexing of arrays except for sampler arrays, fragment output arrays and uniform block arrays.

Should support for dynamic indexing of vectors and matrices be mandated in GLSL ES 3.00?

RESOLUTION: Yes.

My reading is that it should work but IANALL

gman
  • 100,619
  • 31
  • 269
  • 393