1

When I execute

int temp2 = temp1 * 65536;

in my vertex shader on my old Xperia J smart phone (about 8 or so years old), I get a shader compilation error - unfortunately the API does not display the reason for the error.

But when I run the same code on my modern smart phone I get no compilation error.

A work around on the old phone is to use

int temp2 = temp1 * int(65536.0);

instead.

I am using precision highp float; and I have tried precision highp int; but that didn't solve the problem.

Any info on why this is the case? Maybe it's just a bug from the earlier GLSL implementations?

Another workaround I have thought about but not yet tried is just uploading 65536 as an integer uniform.

  • Xperia J uses the ARM Cortex-A5, which is a 32-bit CPU. Please try to decrease the number 65536.0 to 1.0, just to see if it compiles – YoshiJaeger Aug 23 '19 at 11:48
  • @YoshiJaeger It compiles with 65536 replaced by 65535, no problem.65536 would represent bit 16 which is well within 0-31. The multiplicand is at most 65535, so it should compile. Seems to err when i try to multiply by a number built from bits 16-31. But i can multiply by numbers built from only bits 0-15. –  Aug 23 '19 at 12:46
  • ... which would result in a value of 33 bits. – YoshiJaeger Aug 23 '19 at 12:49
  • @YoshiJaeger No, 65535*65536=4294901760=0b1111 1111 1111 1111 0000 0000 0000 0000=32 bits. It's like bit shifting left by 16 bits. –  Aug 23 '19 at 12:52
  • Yeah sure, I was trying to give a hint. We don't know what the compiler is doing with those literals internally. ```2^16 * 2^17 = 2^33``` just sounds reasonable – YoshiJaeger Aug 23 '19 at 13:20
  • @YoshiJaeger so prob best to upload a uniform then to avoid the casts/recast method and avoid compiler lieral handling. –  Aug 23 '19 at 13:35
  • 1
    Exactly. I can’t think of an alternative – YoshiJaeger Aug 23 '19 at 13:42
  • @YoshiJaeger the `uniform` approach worked. Still not sure why it won't compile though. Like you say it must be how the compiler is handling literals. Thanks. –  Aug 23 '19 at 13:48
  • You are welcome :) – YoshiJaeger Aug 23 '19 at 16:46

1 Answers1

0

I thought I'd post my findings in the comments as an answer, as I found another "bug" in the older GLSL compilers.

First for my OP... seems that the older GLSL compiler can read in literal values incorrectly, which I fixed by sending them up as uniform

The second weird behaviour I've found concerns the following code, which is from a vertex shader dealing with sprite data sent in as a texture. All the data is read correctly except the v_Color information. But if you move the line marked (*) to the very end of the code shown, the colour info arrives correctly. It also arrives correctly if you move the v_Color line higher up and change the offset orders accordingly. I guess this must be an old GLSL shader compiler bug too.

spriteId = int(a_vertexId) / 6;
offset = float(spriteId) * 6.0;
vertexId = int(a_vertexId) - spriteId * 6;                  (*)

tx = getFloat(texture2D(u_texSpriteData, uv(offset, u_SpriteDataSize)));
ty = getFloat(texture2D(u_texSpriteData, uv(offset + 1.0, u_SpriteDataSize)));
angle = getFloat(texture2D(u_texSpriteData, uv(offset + 2.0, u_SpriteDataSize)));
scale = getFloat(texture2D(u_texSpriteData, uv(offset + 3.0, u_SpriteDataSize)));
texId = getFloat(texture2D(u_texSpriteData, uv(offset + 4.0, u_SpriteDataSize)));
v_Color = texture2D(u_texSpriteData, uv(offset + 5.0, u_SpriteDataSize));
  • In general I found the older phone implementations of ES2 to be way too unstable for any one-for-all low level optimizations. Moreover, simple per vertex shaders just work faster overall. I learned that optimizations are only worth doing for ES3 onwards where Khronos imposed mandatory requirements on ES implementations and the GLSL language had evolved sufficiently. Don't waste time on ES2 low level optimization, just stick with per vertex. For ES3 though, go to town on it ! –  Oct 06 '19 at 20:42