wined3d: D3DTOP_DOTPRODUCT3 colorop overrides the alphaop.

Note that the fix is only implemented in the arbfp and atifs fragment
pipeline. Unfortunately nvrc doesn't support dot3 as alpha operation.
This commit is contained in:
Stefan Dösinger 2008-08-26 14:11:47 -05:00 committed by Alexandre Julliard
parent 97b57931d0
commit b294e43206
2 changed files with 91 additions and 3 deletions

View file

@ -9576,6 +9576,82 @@ static void alphareplicate_test(IDirect3DDevice9 *device) {
}
static void dp3_alpha_test(IDirect3DDevice9 *device) {
HRESULT hr;
D3DCAPS9 caps;
DWORD color;
struct vertex quad[] = {
{ -1.0, -1.0, 0.1, 0x408080c0 },
{ 1.0, -1.0, 0.1, 0x408080c0 },
{ -1.0, 1.0, 0.1, 0x408080c0 },
{ 1.0, 1.0, 0.1, 0x408080c0 },
};
memset(&caps, 0, sizeof(caps));
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
skip("D3DTOP_DOTPRODUCT3 not supported\n");
return;
}
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
/* dp3_x4 r0, diffuse_bias, tfactor_bias
* mov r0.a, diffuse.a
* mov r0, r0.a
*
* It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
* thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
* (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
*/
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
if(SUCCEEDED(hr)) {
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
}
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
color = getPixelColor(device, 320, 240);
ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
color);
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
}
START_TEST(visual)
{
IDirect3DDevice9 *device_ptr;
@ -9732,9 +9808,11 @@ START_TEST(visual)
}
}
else skip("No ps_1_1 support\n");
texop_test(device_ptr);
texop_range_test(device_ptr);
alphareplicate_test(device_ptr);
dp3_alpha_test(device_ptr);
cleanup:
if(device_ptr) {

View file

@ -1871,9 +1871,19 @@ void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct ffp_settings *setting
cop = WINED3DTOP_SELECTARG1;
}
aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
if(cop == WINED3DTOP_DOTPRODUCT3) {
/* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
* the color result to the alpha component of the destination
*/
aop = cop;
aarg1 = carg1;
aarg2 = carg2;
aarg0 = carg0;
} else {
aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
}
if(i == 0 && stateblock->textures[0] &&
stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&