mirror of
https://github.com/reactos/wine.git
synced 2025-01-23 12:25:17 +00:00
wined3d: The D3DSI_COISSUE flag changes the behavior of cnd.
This commit is contained in:
parent
8273cfdf01
commit
02114ac21f
@ -3231,6 +3231,7 @@ static void constant_clamp_ps_test(IDirect3DDevice9 *device)
|
||||
static void cnd_test(IDirect3DDevice9 *device)
|
||||
{
|
||||
IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
|
||||
IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
|
||||
HRESULT hr;
|
||||
DWORD color;
|
||||
/* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
|
||||
@ -3247,7 +3248,6 @@ static void cnd_test(IDirect3DDevice9 *device)
|
||||
0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
|
||||
DWORD shader_code_12[] = {
|
||||
0xffff0102, /* ps_1_2 */
|
||||
0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
|
||||
@ -3258,7 +3258,6 @@ static void cnd_test(IDirect3DDevice9 *device)
|
||||
0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
|
||||
DWORD shader_code_13[] = {
|
||||
0xffff0103, /* ps_1_3 */
|
||||
0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
|
||||
@ -3277,6 +3276,72 @@ static void cnd_test(IDirect3DDevice9 *device)
|
||||
0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
|
||||
/* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
|
||||
* as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
|
||||
* set by the compiler, it was added manually after compilation. It isn't always allowed,
|
||||
* only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
|
||||
* native CreatePixelShader returns an error.
|
||||
*
|
||||
* The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
|
||||
* The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
|
||||
* constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
|
||||
* then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
|
||||
*/
|
||||
DWORD shader_code_11_coissue[] = {
|
||||
0xffff0101, /* ps_1_1 */
|
||||
0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
|
||||
0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
|
||||
0x00000040, 0xb00f0000, /* texcoord t0 */
|
||||
0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
|
||||
0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
|
||||
0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
|
||||
0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
|
||||
0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
|
||||
/* 0x40000000 = D3DSI_COISSUE */
|
||||
0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
DWORD shader_code_12_coissue[] = {
|
||||
0xffff0102, /* ps_1_2 */
|
||||
0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
|
||||
0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
|
||||
0x00000040, 0xb00f0000, /* texcoord t0 */
|
||||
0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
|
||||
0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
|
||||
0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
|
||||
0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
|
||||
0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
|
||||
/* 0x40000000 = D3DSI_COISSUE */
|
||||
0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
DWORD shader_code_13_coissue[] = {
|
||||
0xffff0103, /* ps_1_3 */
|
||||
0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
|
||||
0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
|
||||
0x00000040, 0xb00f0000, /* texcoord t0 */
|
||||
0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
|
||||
0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
|
||||
0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
|
||||
0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
|
||||
0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
|
||||
/* 0x40000000 = D3DSI_COISSUE */
|
||||
0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
/* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
|
||||
* compare against 0.5
|
||||
*/
|
||||
DWORD shader_code_14_coissue[] = {
|
||||
0xffff0104, /* ps_1_4 */
|
||||
0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
|
||||
0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
|
||||
0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
|
||||
/* 0x40000000 = D3DSI_COISSUE */
|
||||
0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
|
||||
0x0000ffff /* end */
|
||||
};
|
||||
float quad1[] = {
|
||||
-1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
|
||||
0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
|
||||
@ -3303,6 +3368,8 @@ static void cnd_test(IDirect3DDevice9 *device)
|
||||
};
|
||||
float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
|
||||
float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
|
||||
float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
|
||||
float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
|
||||
@ -3315,6 +3382,14 @@ static void cnd_test(IDirect3DDevice9 *device)
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
|
||||
@ -3396,6 +3471,89 @@ static void cnd_test(IDirect3DDevice9 *device)
|
||||
color = getPixelColor(device, 482, 122);
|
||||
ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
|
||||
ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
|
||||
ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
|
||||
ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
|
||||
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));
|
||||
|
||||
/* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
|
||||
* that we swapped the values in c1 and c2 to make the other tests return some color
|
||||
*/
|
||||
color = getPixelColor(device, 158, 118);
|
||||
ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
|
||||
color = getPixelColor(device, 162, 118);
|
||||
ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
|
||||
color = getPixelColor(device, 158, 122);
|
||||
ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
|
||||
color = getPixelColor(device, 162, 122);
|
||||
ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
|
||||
|
||||
/* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
|
||||
color = getPixelColor(device, 158, 358);
|
||||
ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 162, 358);
|
||||
ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 158, 362);
|
||||
ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 162, 362);
|
||||
ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
|
||||
|
||||
/* 1.2 shader */
|
||||
color = getPixelColor(device, 478, 358);
|
||||
ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 482, 358);
|
||||
ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 478, 362);
|
||||
ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 482, 362);
|
||||
ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
|
||||
|
||||
/* 1.3 shader */
|
||||
color = getPixelColor(device, 478, 118);
|
||||
ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 482, 118);
|
||||
ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 478, 122);
|
||||
ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
|
||||
color = getPixelColor(device, 482, 122);
|
||||
ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
|
||||
|
||||
IDirect3DPixelShader9_Release(shader_14_coissue);
|
||||
IDirect3DPixelShader9_Release(shader_13_coissue);
|
||||
IDirect3DPixelShader9_Release(shader_12_coissue);
|
||||
IDirect3DPixelShader9_Release(shader_11_coissue);
|
||||
IDirect3DPixelShader9_Release(shader_14);
|
||||
IDirect3DPixelShader9_Release(shader_13);
|
||||
IDirect3DPixelShader9_Release(shader_12);
|
||||
|
@ -572,6 +572,7 @@ void pshader_hw_bem(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
char dst_wmask[20];
|
||||
char dst_name[50];
|
||||
@ -589,8 +590,14 @@ void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1]);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2]);
|
||||
|
||||
shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
|
||||
shader_addline(buffer, "CMP %s, TMP, %s, %s;\n", dst_name, src_name[1], src_name[2]);
|
||||
/* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
|
||||
if (shader->baseShader.hex_version <= WINED3DPS_VERSION(1, 3) &&
|
||||
arg->opcode_token & WINED3DSI_COISSUE) {
|
||||
shader_addline(buffer, "MOV %s, %s;\n", dst_name, src_name[1]);
|
||||
} else {
|
||||
shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
|
||||
shader_addline(buffer, "CMP %s, TMP, %s, %s;\n", dst_name, src_name[1], src_name[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) {
|
||||
|
@ -949,6 +949,10 @@ void shader_trace_init(
|
||||
shader_dump_param(iface, *(pToken + 2), 0, 1);
|
||||
TRACE(") ");
|
||||
}
|
||||
if (opcode_token & WINED3DSI_COISSUE) {
|
||||
/* PixWin marks instructions with the coissue flag with a '+' */
|
||||
TRACE("+");
|
||||
}
|
||||
|
||||
TRACE("%s", curOpcode->name);
|
||||
|
||||
|
@ -1303,8 +1303,14 @@ void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) {
|
||||
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
|
||||
shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], write_mask, &src1_param);
|
||||
shader_glsl_add_src_param(arg, arg->src[2], arg->src_addr[2], write_mask, &src2_param);
|
||||
shader_addline(arg->buffer, "%s > 0.5 ? %s : %s);\n",
|
||||
src0_param.param_str, src1_param.param_str, src2_param.param_str);
|
||||
|
||||
/* Fun: The D3DSI_COISSUE flag changes the semantic of the cnd instruction for < 1.4 shaders */
|
||||
if(arg->opcode_token & WINED3DSI_COISSUE) {
|
||||
shader_addline(arg->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
|
||||
} else {
|
||||
shader_addline(arg->buffer, "%s > 0.5 ? %s : %s);\n",
|
||||
src0_param.param_str, src1_param.param_str, src2_param.param_str);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Cycle through all source0 channels */
|
||||
|
Loading…
x
Reference in New Issue
Block a user