From 7afea63d4fc2077c0f18604c0b68adb13435eabc Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Sat, 26 Nov 2016 21:58:29 +0100 Subject: [PATCH] st/nine: Fix ff cases when stages should be disabled When a texture is read by a stage for colorop, it should be disabled, and disable following stages. When a texture is read for alphaop, 1.0f is read for the input, which is the behaviour for a dummy texture. Signed-off-by: Axel Davy --- src/gallium/state_trackers/nine/nine_ff.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c index b3183005186..7a099864da0 100644 --- a/src/gallium/state_trackers/nine/nine_ff.c +++ b/src/gallium/state_trackers/nine/nine_ff.c @@ -1709,16 +1709,28 @@ nine_ff_get_ps(struct NineDevice9 *device) for (s = 0; s < 8; ++s) { key.ts[s].colorop = state->ff.tex_stage[s][D3DTSS_COLOROP]; key.ts[s].alphaop = state->ff.tex_stage[s][D3DTSS_ALPHAOP]; - /* MSDN says D3DTOP_DISABLE disables this and all subsequent stages. */ - /* ALPHAOP cannot be disabled if COLOROP is enabled. */ + const uint8_t used_c = ps_d3dtop_args_mask(key.ts[s].colorop); + const uint8_t used_a = ps_d3dtop_args_mask(key.ts[s].alphaop); + /* MSDN says D3DTOP_DISABLE disables this and all subsequent stages. + * ALPHAOP cannot be enabled if COLOROP is disabled. + * Verified on Windows. */ if (key.ts[s].colorop == D3DTOP_DISABLE) { key.ts[s].alphaop = D3DTOP_DISABLE; /* DISABLE == 1, avoid degenerate keys */ break; } if (!state->texture[s] && - state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE) { - /* This should also disable the stage. */ + ((state->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE && + used_c & 0x1) || + (state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE && + used_c & 0x2) || + (state->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE && + used_c & 0x4))) { + /* Tested on Windows: Invalid texture read disables the stage + * and the subsequent ones, but only for colorop. For alpha, + * it's as if the texture had alpha of 1.0, which is what + * has our dummy texture in that case. Invalid color also + * disabled the following alpha stages. */ key.ts[s].colorop = key.ts[s].alphaop = D3DTOP_DISABLE; break; } @@ -1732,7 +1744,6 @@ nine_ff_get_ps(struct NineDevice9 *device) sampler_mask |= (1 << s); if (key.ts[s].colorop != D3DTOP_DISABLE) { - uint8_t used_c = ps_d3dtop_args_mask(key.ts[s].colorop); if (used_c & 0x1) key.ts[s].colorarg0 = state->ff.tex_stage[s][D3DTSS_COLORARG0]; if (used_c & 0x2) key.ts[s].colorarg1 = state->ff.tex_stage[s][D3DTSS_COLORARG1]; if (used_c & 0x4) key.ts[s].colorarg2 = state->ff.tex_stage[s][D3DTSS_COLORARG2]; @@ -1744,7 +1755,6 @@ nine_ff_get_ps(struct NineDevice9 *device) if (used_c & 0x4) key.colorarg_b5[2] |= (state->ff.tex_stage[s][D3DTSS_COLORARG2] >> 5) << s; } if (key.ts[s].alphaop != D3DTOP_DISABLE) { - uint8_t used_a = ps_d3dtop_args_mask(key.ts[s].alphaop); if (used_a & 0x1) key.ts[s].alphaarg0 = state->ff.tex_stage[s][D3DTSS_ALPHAARG0]; if (used_a & 0x2) key.ts[s].alphaarg1 = state->ff.tex_stage[s][D3DTSS_ALPHAARG1]; if (used_a & 0x4) key.ts[s].alphaarg2 = state->ff.tex_stage[s][D3DTSS_ALPHAARG2]; -- 2.30.2