st/nine: Fix two special cases in ff ps
authorAxel Davy <axel.davy@ens.fr>
Sun, 27 Nov 2016 12:13:13 +0000 (13:13 +0100)
committerAxel Davy <axel.davy@ens.fr>
Tue, 20 Dec 2016 22:44:21 +0000 (23:44 +0100)
if first alpha stage is disabled and writes to temp,
diffuse alpha is written to temp.
Last stage always writes to current.

Behaviour was deduced by tests with a test app.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/nine_ff.c

index c3245a3..294fbc8 100644 (file)
@@ -1773,6 +1773,26 @@ nine_ff_get_ps(struct NineDevice9 *device)
         }
     }
 
+    /* Note: If colorop is D3DTOP_DISABLE for the first stage
+     * (which implies alphaop is too), nothing particular happens,
+     * that is, current is equal to diffuse (which is the case anyway,
+     * because it is how it is initialized).
+     * Special case seems if alphaop is D3DTOP_DISABLE and not colorop,
+     * because then if the resultarg is TEMP, then diffuse alpha is written
+     * to it. */
+    if (key.ts[0].colorop != D3DTOP_DISABLE &&
+        key.ts[0].alphaop == D3DTOP_DISABLE &&
+        key.ts[0].resultarg != 0) {
+        key.ts[0].alphaop = D3DTOP_SELECTARG1;
+        key.ts[0].alphaarg1 = D3DTA_DIFFUSE;
+    }
+    /* When no alpha stage writes to current, diffuse alpha is taken.
+     * Since we initialize current to diffuse, we have the behaviour. */
+
+    /* Last stage always writes to Current */
+    if (s >= 1)
+        key.ts[s-1].resultarg = 0;
+
     key.projected = nine_ff_get_projected_key(state);
     key.specular = !!state->rs[D3DRS_SPECULARENABLE];