Stefan Dösinger : wined3d: Partially revert " Get rid of the conditionals in shader_glsl".
Alexandre Julliard
julliard at winehq.org
Wed Nov 14 07:30:26 CST 2007
Module: wine
Branch: master
Commit: 9f41a359b69f78832eaf6714e106558d794be61a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9f41a359b69f78832eaf6714e106558d794be61a
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Fri Nov 9 19:53:20 2007 +0100
wined3d: Partially revert "Get rid of the conditionals in shader_glsl".
---
dlls/d3d9/tests/visual.c | 137 ++++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/glsl_shader.c | 10 +++-
2 files changed, 146 insertions(+), 1 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 5886fb8..a61a7d2 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -4303,6 +4303,142 @@ static void pshader_version_varying_test(IDirect3DDevice9 *device) {
if(texture) IDirect3DTexture9_Release(texture);
}
+void test_compare_instructions(IDirect3DDevice9 *device)
+{
+ DWORD shader_sge_vec_code[] = {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
+ 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
+ 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
+ 0x0000ffff /* end */
+ };
+ DWORD shader_slt_vec_code[] = {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
+ 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
+ 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
+ 0x0000ffff /* end */
+ };
+ DWORD shader_sge_scalar_code[] = {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
+ 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
+ 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
+ 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
+ 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
+ 0x0000ffff /* end */
+ };
+ DWORD shader_slt_scalar_code[] = {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
+ 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
+ 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
+ 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
+ 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
+ 0x0000ffff /* end */
+ };
+ IDirect3DVertexShader9 *shader_sge_vec;
+ IDirect3DVertexShader9 *shader_slt_vec;
+ IDirect3DVertexShader9 *shader_sge_scalar;
+ IDirect3DVertexShader9 *shader_slt_scalar;
+ HRESULT hr, color;
+ float quad1[] = {
+ -1.0, -1.0, 0.1,
+ 0.0, -1.0, 0.1,
+ -1.0, 0.0, 0.1,
+ 0.0, 0.0, 0.1
+ };
+ float quad2[] = {
+ 0.0, -1.0, 0.1,
+ 1.0, -1.0, 0.1,
+ 0.0, 0.0, 0.1,
+ 1.0, 0.0, 0.1
+ };
+ float quad3[] = {
+ -1.0, 0.0, 0.1,
+ 0.0, 0.0, 0.1,
+ -1.0, 1.0, 0.1,
+ 0.0, 1.0, 0.1
+ };
+ float quad4[] = {
+ 0.0, 0.0, 0.1,
+ 1.0, 0.0, 0.1,
+ 0.0, 1.0, 0.1,
+ 1.0, 1.0, 0.1
+ };
+ const float const0[4] = {0.8, 0.2, 0.2, 0.2};
+ const float const1[4] = {0.2, 0.8, 0.2, 0.2};
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
+
+ hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
+ ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
+ if(SUCCEEDED(hr))
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
+ ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
+ ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
+ ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
+ ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
+
+ color = getPixelColor(device, 160, 360);
+ ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FFn", color);
+ color = getPixelColor(device, 480, 360);
+ ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
+ color = getPixelColor(device, 160, 120);
+ ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
+ color = getPixelColor(device, 480, 160);
+ ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
+
+ IDirect3DVertexShader9_Release(shader_sge_vec);
+ IDirect3DVertexShader9_Release(shader_slt_vec);
+ IDirect3DVertexShader9_Release(shader_sge_scalar);
+ IDirect3DVertexShader9_Release(shader_slt_scalar);
+}
+
START_TEST(visual)
{
IDirect3DDevice9 *device_ptr;
@@ -4385,6 +4521,7 @@ START_TEST(visual)
if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
{
test_constant_clamp_vs(device_ptr);
+ test_compare_instructions(device_ptr);
}
else skip("No vs_1_1 support\n");
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 4a1c528..5d988e4 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1563,9 +1563,17 @@ void shader_glsl_compare(SHADER_OPCODE_ARG* arg) {
} else {
switch(arg->opcode->opcode) {
case WINED3DSIO_SLT:
- shader_addline(arg->buffer, "step(%s, %s));\n", src0_param.param_str, src1_param.param_str);
+ /* Step(src0, src1) is not suitable here because if src0 == src1 SLT is supposed,
+ * to return 0.0 but step returns 1.0 because step is not < x
+ * An alternative is a bvec compare padded with an unused secound component.
+ * step(src1 * -1.0, src0 * -1.0) is not an option because it suffers from the same
+ * issue. Playing with not() is not possible either because not() does not accept
+ * a scalar.
+ */
+ shader_addline(arg->buffer, "(%s < %s) ? 1.0 : 0.0);\n", src0_param.param_str, src1_param.param_str);
break;
case WINED3DSIO_SGE:
+ /* Here we can use the step() function and safe a conditional */
shader_addline(arg->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
break;
default:
More information about the wine-cvs
mailing list