I'm pulling my hair off with one specific hardware. This is an Acer Iconia w3-810 tablet, with Windows 8, Intel Atom Z2760, and GMA "GPU".
Newest driver pack has been installed.
I'm developing with DirectX9 and HLSL. Some objects I render with DirectX 9 pipeline but some objects requiring advanced coloring render with HLSL vertex and pixel shaders. The problem is coordinate conversion in the HLSL, from object space to screen coords. I suspect this must be some kind of floating point accuracy thing.
In vertex shader, this works with all other computers:
vout.Pos_ps = mul(position, WorldViewProjection); //WorldViewProjection has all transformations
[attachment=18188:amd.jpg]
It's taken with AMD GPU, this is all OK.
But compare it to Atom's screenshot:
[attachment=18189:spectrogram_iconia.jpg]
All other objects are in place, but not the one I render with HLSL, the colorful spectrogram surface.
If I convert the coordinates in CPU side with WorldViewProjection matrix, and don't convert it all in GPU side, it renders OK with Atom too. But the matrix multiplication has to be done as follows:
Vector3 TransformCoordinate( Vector3 coord, Matrix transform )
{
Vector4 vector;
vector.X = (((coord.X * transform.M11) + (coord.Y * transform.M21)) + (coord.Z * transform.M31)) + transform.M41;
vector.Y = (((coord.X * transform.M12) + (coord.Y * transform.M22)) + (coord.Z * transform.M32)) + transform.M42;
vector.Z = (((coord.X * transform.M13) + (coord.Y * transform.M23)) + (coord.Z * transform.M33)) + transform.M43;
vector.W = 1.0f / ((((coord.X * transform.M14) + (coord.Y * transform.M24)) + (coord.Z * transform.M34)) + transform.M44);
Vector3 v3 = new Vector3(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W );
return v3;
}
Then I tried to implement the similar coordinate conversion in HLSL:
vout.Pos_ps = TransformCoord(position);
float4 TransformCoord(float4 pos)
{
float4 tr;
tr.x = (((pos.x * WorldViewProjection._11) + (pos.y * WorldViewProjection._21)) + (pos.z * WorldViewProjection._31)) + WorldViewProjection._41;
tr.y = (((pos.x * WorldViewProjection._12) + (pos.y * WorldViewProjection._22)) + (pos.z * WorldViewProjection._32)) + WorldViewProjection._42;
tr.z = (((pos.x * WorldViewProjection._13) + (pos.y * WorldViewProjection._23)) + (pos.z * WorldViewProjection._33)) + WorldViewProjection._43;
tr.w = 1.0f / ((((pos.x * WorldViewProjection._14) + (pos.y * WorldViewProjection._24)) + (pos.z * WorldViewProjection._34)) + WorldViewProjection._44);
return float4 (tr.x * tr.w, tr.y * tr.w, tr.z * tr.w, 1.0f);
}
Well, it works fine with other computers, but with Atom it doesn't. The result is even worse than mul(vector, matrix) I used originally, the transformed coordinates are typically in the center of the screen in tip of the needle size, but badly warped.
I really don't want to move all coordinate conversions to CPU side, that would be a massive task as we have so many different data visualization stuff implemented.
What am I missing? Is there any way to improve floating point accuracy on this this machine? Should I forward resolving of this case to Intel?