3

I've narrowed my case down to this simple GLSL code:

uniform int zeroUniform; // Always set to zero, it is there so that the code is not optimized out
out int c;

int a = 8660165;
int b = 6;
c = (a + zeroUniform) / b;

When I put this in a shader and inspect the shader with RenderDoc, it says that c is 1443361! But it should be 1443360. What the hell is happening? In hex, 8660165 is 0x8424C5, so there's a whole one byte free before the sign bit could alter the calculations. Am I missing something or is this a GPU bug?

OpenGL 4.6 core, Tested on AMD RX 5700 XT. I've also tried using uint instead of int, which works correctly.

10
  • Interesting question. Another possibility, although quite unlikely, is that your driver implements float to integer truncation with a rounding function other than the expected floor function?
    – jackw11111
    Commented Jul 20, 2020 at 9:20
  • @jackw11111: There shouldn't be an float -> int conversion in this code.
    – BDL
    Commented Jul 20, 2020 at 9:25
  • @BDL My mistake, I meant truncation from assigning a float to an int could be ceil() instead of floor().
    – jackw11111
    Commented Jul 20, 2020 at 9:36
  • The current calculation is int = (int + int) / int;. There is no floating point number involved. When implemented correctly, there should never be a float -> int assignment.
    – BDL
    Commented Jul 20, 2020 at 9:44
  • It would be a driver bug, AMD Navi doesn't have a built-in integer division, so it's emulated in software. You could check what actually happens
    – user555045
    Commented Jul 20, 2020 at 10:41

1 Answer 1

2

The result of your division is 1443360.833333333

This spec https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf

On page 144 in the section "12.33 Rounding of Integer Division" it asks if integer division should round and the answer is "RESOLUTION: The rounding mode is undefined for this version of the specification."

So the results you are seeing certainly seems valid given that spec even if not the most useful.

That spec is for GLSL ES 3.00 which likely isn't what you are using but I can't find another spec right now that mentions this, but it seems an indication at least that your results are valid given the spec, even if not what you'd hope for

4
  • 2
    Non-ES spec doesn't say that, but it doesn't say anything else either, it skips the whole subject
    – user555045
    Commented Jul 20, 2020 at 10:51
  • Yes I couldn't find it anywhere else either, which seems to imply to me that this might be expected behaviour rather than a bug as such. Although I'm not sure what practical difference that makes to you sadly. Perhaps my reply should have been a comment as it's more evidence than answer.
    – jcoder
    Commented Jul 20, 2020 at 13:19
  • Well I am using the integer division to find out quad ID and quad-local vertex ID from gl_VertexID (in GL_TRIANGLES draw mode).
    – Danol
    Commented Jul 20, 2020 at 16:17
  • Well if this is true, that is very unfortunate. That basically means you can't rely on GLSL integer division and modulo operations...
    – Danol
    Commented Jul 21, 2020 at 10:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.