【问题标题】:Have I found an AMD GPU integer division bug?我是否发现了 AMD GPU 整数除法错误?
【发布时间】:2020-11-09 11:31:36
【问题描述】:

我已将我的案例缩小到这个简单的 GLSL 代码:

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;

当我将它放入着色器并使用 RenderDoc 检查着色器时,它显示 c 是 1443361!但它应该是 1443360。到底发生了什么?在十六进制中,8660165 是 0x8424C5,因此在符号位可以改变计算之前有一个完整的字节空闲。我错过了什么还是这是一个 GPU 错误?

OpenGL 4.6 内核,在 AMD RX 5700 XT 上测试。我也尝试过使用 uint 而不是 int,它可以正常工作。

【问题讨论】:

  • 有趣的问题。另一种可能性(虽然不太可能)是您的驱动程序使用舍入函数而不是预期的 floor 函数实现浮点到整数截断?
  • @jackw11111:这段代码中不应该有 float -> int 转换。
  • @BDL 我的错误,我的意思是从将浮点数分配给 int 的截断可能是 ceil() 而不是 floor()。
  • 当前计算为int = (int + int) / int;。不涉及浮点数。正确实施时,永远不应该有 float -> int 赋值。
  • 这可能是一个驱动错误,AMD Navi 没有内置整数除法,所以它是在软件中模拟的。您可以检查实际发生的情况

标签: opengl glsl gpu amd-gpu


【解决方案1】:

你的除法结果是 1443360.833333333

本规范https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf

在“12.33 整数除法的舍入”部分的第 144 页上,它询问整数除法是否应舍入,答案是“解决方案:此版本的规范未定义舍入模式。”

因此,考虑到该规范,即使不是最有用的,您看到的结果肯定是有效的。

该规范适用于 GLSL ES 3.00,它可能不是您正在使用的,但我现在找不到另一个规范提到这一点,但它似乎至少表明您的结果在给定规范的情况下是有效的,即使如果不是你所希望的

【讨论】:

  • Non-ES spec 没有说,但也没有说别的,它跳过了整个主题
  • 是的,我也无法在其他任何地方找到它,这对我来说似乎意味着这 可能 是预期的行为,而不是这样的错误。虽然我不确定这对你有什么实际的影响。也许我的回复应该是评论,因为它比答案更有证据。
  • 好吧,我正在使用整数除法从 gl_VertexID 中找出四边形 ID 和四边形局部顶点 ID(在 GL_TRIANGLES 绘制模式下)。
  • 好吧,如果这是真的,那就太不幸了。这基本上意味着您不能依赖 GLSL 整数除法和模运算...
猜你喜欢
  • 2012-08-20
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
相关资源
最近更新 更多