wined3d: gl_FragCoord isn't exact.
This commit is contained in:
parent
c00c89eb51
commit
8a3ef776f4
|
@ -6907,7 +6907,16 @@ static void vpos_register_test(IDirect3DDevice9 *device)
|
|||
0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
IDirect3DPixelShader9 *shader;
|
||||
const DWORD shader_frac_code[] = {
|
||||
0xffff0300, /* ps_3_0 */
|
||||
0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
|
||||
0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
|
||||
0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
|
||||
0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
|
||||
0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
IDirect3DPixelShader9 *shader, *shader_frac;
|
||||
IDirect3DSurface9 *surface = NULL, *backbuffer;
|
||||
const float quad[] = {
|
||||
-1.0, -1.0, 0.1, 0.0, 0.0,
|
||||
|
@ -6923,6 +6932,8 @@ static void vpos_register_test(IDirect3DDevice9 *device)
|
|||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, shader);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
|
||||
|
@ -6967,8 +6978,6 @@ static void vpos_register_test(IDirect3DDevice9 *device)
|
|||
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
}
|
||||
hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
|
||||
ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
|
@ -6989,7 +6998,38 @@ static void vpos_register_test(IDirect3DDevice9 *device)
|
|||
hr = IDirect3DSurface9_UnlockRect(surface);
|
||||
ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
|
||||
/* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
|
||||
* have full control over the multisampling setting inside this test
|
||||
*/
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
|
||||
if(SUCCEEDED(hr)) {
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
|
||||
}
|
||||
hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
|
||||
ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
|
||||
pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
|
||||
color = *pos & 0x00ffffff;
|
||||
ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
|
||||
|
||||
hr = IDirect3DSurface9_UnlockRect(surface);
|
||||
ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, NULL);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
|
||||
IDirect3DPixelShader9_Release(shader);
|
||||
IDirect3DPixelShader9_Release(shader_frac);
|
||||
if(surface) IDirect3DSurface9_Release(surface);
|
||||
IDirect3DSurface9_Release(backbuffer);
|
||||
}
|
||||
|
|
|
@ -706,7 +706,21 @@ void shader_generate_glsl_declarations(
|
|||
/* Start the main program */
|
||||
shader_addline(buffer, "void main() {\n");
|
||||
if(pshader && reg_maps->vpos) {
|
||||
shader_addline(buffer, "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1) - 0.5;\n");
|
||||
/* DirectX apps expect integer values, while OpenGL drivers add approximately 0.5. This causes
|
||||
* off-by-one problems as spotted by the vPos d3d9 visual test. Unfortunately the ATI cards do
|
||||
* not add exactly 0.5, but rather something like 0.49999999 or 0.50000001, which still causes
|
||||
* precision troubles when we just substract 0.5.
|
||||
*
|
||||
* To deal with that just floor() the position. This will eliminate the fraction on all cards.
|
||||
*
|
||||
* TODO: Test how that behaves with multisampling once we can enable multisampling in winex11.
|
||||
*
|
||||
* An advantage of floor is that it works even if the driver doesn't add 1/2. It is somewhat
|
||||
* questionable if 1.5, 2.5, ... are the proper values to return in gl_FragCoord, even though
|
||||
* coordinates specify the pixel centers instead of the pixel corners. This code will behave
|
||||
* correctly on drivers that returns integer values.
|
||||
*/
|
||||
shader_addline(buffer, "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue