Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

precision qualifier bug in pre_decrement tests #3525

Open
anholt opened this issue Mar 3, 2023 · 1 comment
Open

precision qualifier bug in pre_decrement tests #3525

anholt opened this issue Mar 3, 2023 · 1 comment

Comments

@anholt
Copy link

anholt commented Mar 3, 2023

Mesa got a bug report for webgl conformance on chromium on llvmpipe on the class of tests like shaderop.unary_operator.pre_decrement_effect.lowp_uint_vertex. The test expects a gradient of vertical stripdes going from red to black as you move left to right, then one bright stripe on the right side. llvmpipe, with mediump half-floats enabled, instead gets black for that rightmost stripe. Looking at the shader source:

#version 300 es
in highp vec4 a_position;
in highp vec4 a_in0;
out mediump vec4 v_color;

void main()
{
 gl_Position = a_position;
	lowp uint in0 = uint(a_in0.z);
	lowp uint res = uint(0.0);

	res = in0;
	--res;

	highp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
	color.x = float(res);
	color = color * vec4(0.1, 1.0, 1.0, 1.0);
 v_color = color;
}

I think in the failing stripe, res ends up as -1 (0xffff). The precision of the float(res) operation is lowp, according to the ES specification, since float() is a constructor and:

For this paragraph, “operation” includes operators, built-in functions, and constructors, and “operand”
includes function arguments and constructor arguments. The precision used to internally evaluate an
operation, and the precision qualification subsequently associated with any resulting intermediate values,
must be at least as high as the highest precision qualification of the operands consumed by the operation.

In cases where operands do not have a precision qualifier, the precision qualification will come from the
other operands. [...]

So, Mesa proceeds to do the type conversion of res to float for the constructor at 16 bits, since that's the precision on res, then later upconverts to 32 to store to color.x. If res is 0xffff, then the u2f16 on it gives us an INF, and then the f2f32 is also INF, rather than (float)0xffff, throwing off the rest of the computation.

I think the conformance tests doing conversion from low/mediump uints to floats where the uints may be negative need to first store the lowp uint to a highp uint, before calling the float() constructor to convert them.

mesa bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8124

@kdashg
Copy link
Contributor

kdashg commented Apr 3, 2024

Yes, your diagnosis sounds right to me if we give this inputs such that uint(a_in0.z) -> 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants