[Mesa-dev] [PATCH 21/84] st/nine: Back all ff states in nine_context

Axel Davy axel.davy at ens.fr
Wed Dec 7 22:54:54 UTC 2016


Part of the refactor to move all gallium calls to
nine_state.c, and have all internal states required
for those calls in nine_context.

Signed-off-by: Axel Davy <axel.davy at ens.fr>
---
 src/gallium/state_trackers/nine/device9.c      |  60 ++++------
 src/gallium/state_trackers/nine/nine_ff.c      | 114 +++++++++---------
 src/gallium/state_trackers/nine/nine_ff.h      |   8 +-
 src/gallium/state_trackers/nine/nine_state.c   | 160 ++++++++++++++++++++++++-
 src/gallium/state_trackers/nine/nine_state.h   |  29 ++++-
 src/gallium/state_trackers/nine/pixelshader9.h |   3 +-
 6 files changed, 267 insertions(+), 107 deletions(-)

diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 4a16e09..3ad9218 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -1982,8 +1982,11 @@ NineDevice9_SetTransform( struct NineDevice9 *This,
     user_assert(M, D3DERR_INVALIDCALL);
 
     *M = *pMatrix;
-    state->ff.changed.transform[State / 32] |= 1 << (State % 32);
-    state->changed.group |= NINE_STATE_FF;
+    if (unlikely(This->is_recording)) {
+        state->ff.changed.transform[State / 32] |= 1 << (State % 32);
+        state->changed.group |= NINE_STATE_FF;
+    } else
+        nine_context_set_transform(This, State, pMatrix);
 
     return D3D_OK;
 }
@@ -2053,7 +2056,10 @@ NineDevice9_SetMaterial( struct NineDevice9 *This,
     user_assert(pMaterial, E_POINTER);
 
     state->ff.material = *pMaterial;
-    state->changed.group |= NINE_STATE_FF_MATERIAL;
+    if (unlikely(This->is_recording))
+        state->changed.group |= NINE_STATE_FF_MATERIAL;
+    else
+        nine_context_set_material(This, pMaterial);
 
     return D3D_OK;
 }
@@ -2095,7 +2101,10 @@ NineDevice9_SetLight( struct NineDevice9 *This,
         DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n");
     }
 
-    state->changed.group |= NINE_STATE_FF_LIGHTING;
+    if (unlikely(This->is_recording))
+        state->changed.group |= NINE_STATE_FF_LIGHTING;
+    else
+        nine_context_set_light(This, Index, pLight);
 
     return D3D_OK;
 }
@@ -2140,6 +2149,8 @@ NineDevice9_LightEnable( struct NineDevice9 *This,
     }
 
     nine_state_light_enable(&state->ff, &state->changed.group, Index, Enable);
+    if (likely(!This->is_recording))
+        nine_context_light_enable(This, Index, Enable);
 
     return D3D_OK;
 }
@@ -2492,8 +2503,6 @@ NineDevice9_SetTextureStageState( struct NineDevice9 *This,
                                   DWORD Value )
 {
     struct nine_state *state = This->update;
-    struct nine_context *context = &This->context;
-    int bumpmap_index = -1;
 
     DBG("Stage=%u Type=%u Value=%08x\n", Stage, Type, Value);
     nine_dump_D3DTSS_value(DBG_FF, Type, Value);
@@ -2502,39 +2511,14 @@ NineDevice9_SetTextureStageState( struct NineDevice9 *This,
     user_assert(Type < ARRAY_SIZE(state->ff.tex_stage[0]), D3DERR_INVALIDCALL);
 
     state->ff.tex_stage[Stage][Type] = Value;
-    switch (Type) {
-    case D3DTSS_BUMPENVMAT00:
-        bumpmap_index = 4 * Stage;
-        break;
-    case D3DTSS_BUMPENVMAT01:
-        bumpmap_index = 4 * Stage + 1;
-        break;
-    case D3DTSS_BUMPENVMAT10:
-        bumpmap_index = 4 * Stage + 2;
-        break;
-    case D3DTSS_BUMPENVMAT11:
-        bumpmap_index = 4 * Stage + 3;
-        break;
-    case D3DTSS_BUMPENVLSCALE:
-        bumpmap_index = 4 * 8 + 2 * Stage;
-        break;
-    case D3DTSS_BUMPENVLOFFSET:
-        bumpmap_index = 4 * 8 + 2 * Stage + 1;
-        break;
-    case D3DTSS_TEXTURETRANSFORMFLAGS:
-        state->changed.group |= NINE_STATE_PS1X_SHADER;
-        break;
-    default:
-        break;
-    }
 
-    if (bumpmap_index >= 0 && !This->is_recording) {
-        context->bumpmap_vars[bumpmap_index] = Value;
-        state->changed.group |= NINE_STATE_PS_CONST;
-    }
-
-    state->changed.group |= NINE_STATE_FF_PSSTAGES;
-    state->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
+    if (unlikely(This->is_recording)) {
+        if (Type == D3DTSS_TEXTURETRANSFORMFLAGS)
+            state->changed.group |= NINE_STATE_PS1X_SHADER;
+        state->changed.group |= NINE_STATE_FF_PSSTAGES;
+        state->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
+    } else
+        nine_context_set_texture_stage_state(This, Stage, Type, Value);
 
     return D3D_OK;
 }
diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c
index 0c92bd1..65f09ea 100644
--- a/src/gallium/state_trackers/nine/nine_ff.c
+++ b/src/gallium/state_trackers/nine/nine_ff.c
@@ -1558,7 +1558,6 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key)
 static struct NineVertexShader9 *
 nine_ff_get_vs(struct NineDevice9 *device)
 {
-    const struct nine_state *state = &device->state;
     const struct nine_context *context = &device->context;
     struct NineVertexShader9 *vs;
     enum pipe_error err;
@@ -1619,8 +1618,8 @@ nine_ff_get_vs(struct NineDevice9 *device)
         key.passthrough = 0;
     key.pointscale = !!context->rs[D3DRS_POINTSCALEENABLE];
 
-    key.lighting = !!context->rs[D3DRS_LIGHTING] &&  state->ff.num_lights_active;
-    key.darkness = !!context->rs[D3DRS_LIGHTING] && !state->ff.num_lights_active;
+    key.lighting = !!context->rs[D3DRS_LIGHTING] &&  context->ff.num_lights_active;
+    key.darkness = !!context->rs[D3DRS_LIGHTING] && !context->ff.num_lights_active;
     if (key.position_t) {
         key.darkness = 0; /* |= key.lighting; */ /* XXX ? */
         key.lighting = 0;
@@ -1659,8 +1658,8 @@ nine_ff_get_vs(struct NineDevice9 *device)
     }
 
     for (s = 0; s < 8; ++s) {
-        unsigned gen = (state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
-        unsigned idx = state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] & 7;
+        unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
+        unsigned idx = context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] & 7;
         unsigned dim;
 
         if (key.position_t && gen > NINED3DTSS_TCI_PASSTHRU)
@@ -1673,7 +1672,7 @@ nine_ff_get_vs(struct NineDevice9 *device)
         key.tc_idx |= idx << (s * 3);
         key.tc_dim_input |= ((input_texture_coord[idx]-1) & 0x3) << (s * 2);
 
-        dim = state->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
+        dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
         if (dim > 4)
             dim = input_texture_coord[idx];
         if (dim == 1) /* NV behaviour */
@@ -1708,13 +1707,12 @@ nine_ff_get_vs(struct NineDevice9 *device)
     return vs;
 }
 
-#define GET_D3DTS(n) nine_state_access_transform(&state->ff, D3DTS_##n, FALSE)
+#define GET_D3DTS(n) nine_state_access_transform(&context->ff, D3DTS_##n, FALSE)
 #define IS_D3DTS_DIRTY(s,n) ((s)->ff.changed.transform[(D3DTS_##n) / 32] & (1 << ((D3DTS_##n) % 32)))
 
 static struct NinePixelShader9 *
 nine_ff_get_ps(struct NineDevice9 *device)
 {
-    struct nine_state *state = &device->state;
     struct nine_context *context = &device->context;
     D3DMATRIX *projection_matrix = GET_D3DTS(PROJECTION);
     struct NinePixelShader9 *ps;
@@ -1727,8 +1725,8 @@ nine_ff_get_ps(struct NineDevice9 *device)
 
     memset(&key, 0, sizeof(key));
     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];
+        key.ts[s].colorop = context->ff.tex_stage[s][D3DTSS_COLOROP];
+        key.ts[s].alphaop = context->ff.tex_stage[s][D3DTSS_ALPHAOP];
         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.
@@ -1740,11 +1738,11 @@ nine_ff_get_ps(struct NineDevice9 *device)
         }
 
         if (!context->texture[s] &&
-            ((state->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE &&
+            ((context->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE &&
               used_c & 0x1) ||
-             (state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE &&
+             (context->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE &&
               used_c & 0x2) ||
-             (state->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE &&
+             (context->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,
@@ -1755,34 +1753,34 @@ nine_ff_get_ps(struct NineDevice9 *device)
             break;
         }
 
-        if (state->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE ||
-            state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE ||
-            state->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE ||
-            state->ff.tex_stage[s][D3DTSS_ALPHAARG0] == D3DTA_TEXTURE ||
-            state->ff.tex_stage[s][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE ||
-            state->ff.tex_stage[s][D3DTSS_ALPHAARG2] == D3DTA_TEXTURE)
+        if (context->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE ||
+            context->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE ||
+            context->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE ||
+            context->ff.tex_stage[s][D3DTSS_ALPHAARG0] == D3DTA_TEXTURE ||
+            context->ff.tex_stage[s][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE ||
+            context->ff.tex_stage[s][D3DTSS_ALPHAARG2] == D3DTA_TEXTURE)
             sampler_mask |= (1 << s);
 
         if (key.ts[s].colorop != D3DTOP_DISABLE) {
-            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];
-            if (used_c & 0x1) key.colorarg_b4[0] |= (state->ff.tex_stage[s][D3DTSS_COLORARG0] >> 4) << s;
-            if (used_c & 0x1) key.colorarg_b5[0] |= (state->ff.tex_stage[s][D3DTSS_COLORARG0] >> 5) << s;
-            if (used_c & 0x2) key.colorarg_b4[1] |= (state->ff.tex_stage[s][D3DTSS_COLORARG1] >> 4) << s;
-            if (used_c & 0x2) key.colorarg_b5[1] |= (state->ff.tex_stage[s][D3DTSS_COLORARG1] >> 5) << s;
-            if (used_c & 0x4) key.colorarg_b4[2] |= (state->ff.tex_stage[s][D3DTSS_COLORARG2] >> 4) << s;
-            if (used_c & 0x4) key.colorarg_b5[2] |= (state->ff.tex_stage[s][D3DTSS_COLORARG2] >> 5) << s;
+            if (used_c & 0x1) key.ts[s].colorarg0 = context->ff.tex_stage[s][D3DTSS_COLORARG0];
+            if (used_c & 0x2) key.ts[s].colorarg1 = context->ff.tex_stage[s][D3DTSS_COLORARG1];
+            if (used_c & 0x4) key.ts[s].colorarg2 = context->ff.tex_stage[s][D3DTSS_COLORARG2];
+            if (used_c & 0x1) key.colorarg_b4[0] |= (context->ff.tex_stage[s][D3DTSS_COLORARG0] >> 4) << s;
+            if (used_c & 0x1) key.colorarg_b5[0] |= (context->ff.tex_stage[s][D3DTSS_COLORARG0] >> 5) << s;
+            if (used_c & 0x2) key.colorarg_b4[1] |= (context->ff.tex_stage[s][D3DTSS_COLORARG1] >> 4) << s;
+            if (used_c & 0x2) key.colorarg_b5[1] |= (context->ff.tex_stage[s][D3DTSS_COLORARG1] >> 5) << s;
+            if (used_c & 0x4) key.colorarg_b4[2] |= (context->ff.tex_stage[s][D3DTSS_COLORARG2] >> 4) << s;
+            if (used_c & 0x4) key.colorarg_b5[2] |= (context->ff.tex_stage[s][D3DTSS_COLORARG2] >> 5) << s;
         }
         if (key.ts[s].alphaop != D3DTOP_DISABLE) {
-            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];
-            if (used_a & 0x1) key.alphaarg_b4[0] |= (state->ff.tex_stage[s][D3DTSS_ALPHAARG0] >> 4) << s;
-            if (used_a & 0x2) key.alphaarg_b4[1] |= (state->ff.tex_stage[s][D3DTSS_ALPHAARG1] >> 4) << s;
-            if (used_a & 0x4) key.alphaarg_b4[2] |= (state->ff.tex_stage[s][D3DTSS_ALPHAARG2] >> 4) << s;
+            if (used_a & 0x1) key.ts[s].alphaarg0 = context->ff.tex_stage[s][D3DTSS_ALPHAARG0];
+            if (used_a & 0x2) key.ts[s].alphaarg1 = context->ff.tex_stage[s][D3DTSS_ALPHAARG1];
+            if (used_a & 0x4) key.ts[s].alphaarg2 = context->ff.tex_stage[s][D3DTSS_ALPHAARG2];
+            if (used_a & 0x1) key.alphaarg_b4[0] |= (context->ff.tex_stage[s][D3DTSS_ALPHAARG0] >> 4) << s;
+            if (used_a & 0x2) key.alphaarg_b4[1] |= (context->ff.tex_stage[s][D3DTSS_ALPHAARG1] >> 4) << s;
+            if (used_a & 0x4) key.alphaarg_b4[2] |= (context->ff.tex_stage[s][D3DTSS_ALPHAARG2] >> 4) << s;
         }
-        key.ts[s].resultarg = state->ff.tex_stage[s][D3DTSS_RESULTARG] == D3DTA_TEMP;
+        key.ts[s].resultarg = context->ff.tex_stage[s][D3DTSS_RESULTARG] == D3DTA_TEMP;
 
         if (context->texture[s]) {
             switch (context->texture[s]->base.type) {
@@ -1818,7 +1816,7 @@ nine_ff_get_ps(struct NineDevice9 *device)
     if (s >= 1)
         key.ts[s-1].resultarg = 0;
 
-    key.projected = nine_ff_get_projected_key(state, context);
+    key.projected = nine_ff_get_projected_key(context);
     key.specular = !!context->rs[D3DRS_SPECULARENABLE];
 
     for (; s < 8; ++s)
@@ -1860,7 +1858,6 @@ nine_ff_get_ps(struct NineDevice9 *device)
 static void
 nine_ff_load_vs_transforms(struct NineDevice9 *device)
 {
-    struct nine_state *state = &device->state;
     struct nine_context *context = &device->context;
     D3DMATRIX T;
     D3DMATRIX *M = (D3DMATRIX *)device->ff.vs_const;
@@ -1869,9 +1866,9 @@ nine_ff_load_vs_transforms(struct NineDevice9 *device)
     /* TODO: make this nicer, and only upload the ones we need */
     /* TODO: use ff.vs_const as storage of W, V, P matrices */
 
-    if (IS_D3DTS_DIRTY(state, WORLD) ||
-        IS_D3DTS_DIRTY(state, VIEW) ||
-        IS_D3DTS_DIRTY(state, PROJECTION)) {
+    if (IS_D3DTS_DIRTY(context, WORLD) ||
+        IS_D3DTS_DIRTY(context, VIEW) ||
+        IS_D3DTS_DIRTY(context, PROJECTION)) {
         /* WVP, WV matrices */
         nine_d3d_matrix_matrix_mul(&M[1], GET_D3DTS(WORLD), GET_D3DTS(VIEW));
         nine_d3d_matrix_matrix_mul(&M[0], &M[1], GET_D3DTS(PROJECTION));
@@ -1907,7 +1904,7 @@ nine_ff_load_lights(struct NineDevice9 *device)
     unsigned l;
 
     if (state->changed.group & NINE_STATE_FF_MATERIAL) {
-        const D3DMATERIAL9 *mtl = &state->ff.material;
+        const D3DMATERIAL9 *mtl = &context->ff.material;
 
         memcpy(&dst[20], &mtl->Diffuse, 4 * sizeof(float));
         memcpy(&dst[21], &mtl->Ambient, 4 * sizeof(float));
@@ -1923,8 +1920,8 @@ nine_ff_load_lights(struct NineDevice9 *device)
     if (!(state->changed.group & NINE_STATE_FF_LIGHTING))
         return;
 
-    for (l = 0; l < state->ff.num_lights_active; ++l) {
-        const D3DLIGHT9 *light = &state->ff.light[state->ff.active_light[l]];
+    for (l = 0; l < context->ff.num_lights_active; ++l) {
+        const D3DLIGHT9 *light = &context->ff.light[context->ff.active_light[l]];
 
         dst[32 + l * 8].x = light->Type;
         dst[32 + l * 8].y = light->Attenuation0;
@@ -1940,7 +1937,7 @@ nine_ff_load_lights(struct NineDevice9 *device)
         dst[38 + l * 8].x = cosf(light->Theta * 0.5f);
         dst[38 + l * 8].y = cosf(light->Phi * 0.5f);
         dst[38 + l * 8].z = 1.0f / (dst[38 + l * 8].x - dst[38 + l * 8].y);
-        dst[39 + l * 8].w = (l + 1) == state->ff.num_lights_active;
+        dst[39 + l * 8].w = (l + 1) == context->ff.num_lights_active;
     }
 }
 
@@ -1969,15 +1966,15 @@ nine_ff_load_point_and_fog_params(struct NineDevice9 *device)
 static void
 nine_ff_load_tex_matrices(struct NineDevice9 *device)
 {
-    struct nine_state *state = &device->state;
+    struct nine_context *context = &device->context;
     D3DMATRIX *M = (D3DMATRIX *)device->ff.vs_const;
     unsigned s;
 
-    if (!(state->ff.changed.transform[0] & 0xff0000))
+    if (!(context->ff.changed.transform[0] & 0xff0000))
         return;
     for (s = 0; s < 8; ++s) {
-        if (IS_D3DTS_DIRTY(state, TEXTURE0 + s))
-            nine_d3d_matrix_transpose(&M[32 + s], nine_state_access_transform(&state->ff, D3DTS_TEXTURE0 + s, FALSE));
+        if (IS_D3DTS_DIRTY(context, TEXTURE0 + s))
+            nine_d3d_matrix_transpose(&M[32 + s], nine_state_access_transform(&context->ff, D3DTS_TEXTURE0 + s, FALSE));
     }
 }
 
@@ -1993,19 +1990,19 @@ nine_ff_load_ps_params(struct NineDevice9 *device)
         return;
 
     for (s = 0; s < 8; ++s)
-        d3dcolor_to_rgba(&dst[s].x, state->ff.tex_stage[s][D3DTSS_CONSTANT]);
+        d3dcolor_to_rgba(&dst[s].x, context->ff.tex_stage[s][D3DTSS_CONSTANT]);
 
     for (s = 0; s < 8; ++s) {
-        dst[8 + s].x = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT00]);
-        dst[8 + s].y = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT01]);
-        dst[8 + s].z = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT10]);
-        dst[8 + s].w = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT11]);
+        dst[8 + s].x = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT00]);
+        dst[8 + s].y = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT01]);
+        dst[8 + s].z = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT10]);
+        dst[8 + s].w = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT11]);
         if (s & 1) {
-            dst[16 + s / 2].z = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
-            dst[16 + s / 2].w = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
+            dst[16 + s / 2].z = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
+            dst[16 + s / 2].w = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
         } else {
-            dst[16 + s / 2].x = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
-            dst[16 + s / 2].y = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
+            dst[16 + s / 2].x = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
+            dst[16 + s / 2].y = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
         }
     }
 
@@ -2038,7 +2035,6 @@ nine_ff_load_viewport_info(struct NineDevice9 *device)
 void
 nine_ff_update(struct NineDevice9 *device)
 {
-    struct nine_state *state = &device->state;
     struct nine_context *context = &device->context;
     struct pipe_constant_buffer cb;
 
@@ -2061,7 +2057,7 @@ nine_ff_update(struct NineDevice9 *device)
         nine_ff_load_point_and_fog_params(device);
         nine_ff_load_viewport_info(device);
 
-        memset(state->ff.changed.transform, 0, sizeof(state->ff.changed.transform));
+        memset(context->ff.changed.transform, 0, sizeof(context->ff.changed.transform));
 
         cb.buffer_offset = 0;
         cb.buffer = NULL;
diff --git a/src/gallium/state_trackers/nine/nine_ff.h b/src/gallium/state_trackers/nine/nine_ff.h
index ec79959..4d51c3d 100644
--- a/src/gallium/state_trackers/nine/nine_ff.h
+++ b/src/gallium/state_trackers/nine/nine_ff.h
@@ -62,7 +62,7 @@ nine_decltype_get_dim(BYTE type)
 }
 
 static inline uint16_t
-nine_ff_get_projected_key(struct nine_state *state, struct nine_context *context)
+nine_ff_get_projected_key(struct nine_context *context)
 {
     unsigned s, i;
     uint16_t projected = 0;
@@ -81,9 +81,9 @@ nine_ff_get_projected_key(struct nine_state *state, struct nine_context *context
     }
 
     for (s = 0; s < 8; ++s) {
-        unsigned gen = (state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
-        unsigned dim = state->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
-        unsigned proj = !!(state->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
+        unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
+        unsigned dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
+        unsigned proj = !!(context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
 
         if (!context->vs) {
             if (dim > 4)
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index f95a66c..737d621 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -390,7 +390,7 @@ prepare_ps(struct NineDevice9 *device, uint8_t shader_changed)
     int has_key_changed = 0;
 
     if (likely(ps))
-        has_key_changed = NinePixelShader9_UpdateKey(ps, state, context);
+        has_key_changed = NinePixelShader9_UpdateKey(ps, context);
 
     if (!shader_changed && !has_key_changed)
         return 0;
@@ -1490,6 +1490,100 @@ nine_context_set_scissor(struct NineDevice9 *device,
 }
 
 void
+nine_context_set_transform(struct NineDevice9 *device,
+                           D3DTRANSFORMSTATETYPE State,
+                           const D3DMATRIX *pMatrix)
+{
+    struct nine_state *state = &device->state;
+    struct nine_context *context = &device->context;
+    D3DMATRIX *M = nine_state_access_transform(&context->ff, State, TRUE);
+
+    *M = *pMatrix;
+    context->ff.changed.transform[State / 32] |= 1 << (State % 32);
+    state->changed.group |= NINE_STATE_FF;
+}
+
+void
+nine_context_set_material(struct NineDevice9 *device,
+                          const D3DMATERIAL9 *pMaterial)
+{
+    struct nine_state *state = &device->state;
+    struct nine_context *context = &device->context;
+
+    context->ff.material = *pMaterial;
+    state->changed.group |= NINE_STATE_FF_MATERIAL;
+}
+
+void
+nine_context_set_light(struct NineDevice9 *device,
+                       DWORD Index,
+                       const D3DLIGHT9 *pLight)
+{
+    struct nine_state *state = &device->state;
+    struct nine_context *context = &device->context;
+
+    (void)nine_state_set_light(&context->ff, Index, pLight);
+    state->changed.group |= NINE_STATE_FF_LIGHTING;
+}
+
+void
+nine_context_light_enable(struct NineDevice9 *device,
+                          DWORD Index,
+                          BOOL Enable)
+{
+    struct nine_state *state = &device->state;
+    struct nine_context *context = &device->context;
+
+    nine_state_light_enable(&context->ff, &state->changed.group, Index, Enable);
+}
+
+void
+nine_context_set_texture_stage_state(struct NineDevice9 *device,
+                                     DWORD Stage,
+                                     D3DTEXTURESTAGESTATETYPE Type,
+                                     DWORD Value)
+{
+    struct nine_state *state = &device->state;
+    struct nine_context *context = &device->context;
+    int bumpmap_index = -1;
+
+    context->ff.tex_stage[Stage][Type] = Value;
+    switch (Type) {
+    case D3DTSS_BUMPENVMAT00:
+        bumpmap_index = 4 * Stage;
+        break;
+    case D3DTSS_BUMPENVMAT01:
+        bumpmap_index = 4 * Stage + 1;
+        break;
+    case D3DTSS_BUMPENVMAT10:
+        bumpmap_index = 4 * Stage + 2;
+        break;
+    case D3DTSS_BUMPENVMAT11:
+        bumpmap_index = 4 * Stage + 3;
+        break;
+    case D3DTSS_BUMPENVLSCALE:
+        bumpmap_index = 4 * 8 + 2 * Stage;
+        break;
+    case D3DTSS_BUMPENVLOFFSET:
+        bumpmap_index = 4 * 8 + 2 * Stage + 1;
+        break;
+    case D3DTSS_TEXTURETRANSFORMFLAGS:
+        state->changed.group |= NINE_STATE_PS1X_SHADER;
+        break;
+    default:
+        break;
+    }
+
+    if (bumpmap_index >= 0) {
+        context->bumpmap_vars[bumpmap_index] = Value;
+        state->changed.group |= NINE_STATE_PS_CONST;
+    }
+
+    state->changed.group |= NINE_STATE_FF_PSSTAGES;
+    context->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
+}
+
+void
 nine_context_apply_stateblock(struct NineDevice9 *device,
                               const struct nine_state *src)
 {
@@ -1646,6 +1740,61 @@ nine_context_apply_stateblock(struct NineDevice9 *device,
     /* Scissor */
     if (src->changed.group & NINE_STATE_SCISSOR)
         context->scissor = src->scissor;
+
+    if (!(src->changed.group & NINE_STATE_FF))
+        return;
+
+    /* Fixed function state. */
+
+    if (src->changed.group & NINE_STATE_FF_MATERIAL)
+        context->ff.material = src->ff.material;
+
+    if (src->changed.group & NINE_STATE_FF_PSSTAGES) {
+        unsigned s;
+        for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) {
+            for (i = 0; i < NINED3DTSS_COUNT; ++i)
+                if (src->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32)))
+                    context->ff.tex_stage[s][i] = src->ff.tex_stage[s][i];
+        }
+    }
+    if (src->changed.group & NINE_STATE_FF_LIGHTING) {
+        unsigned num_lights = MAX2(context->ff.num_lights, src->ff.num_lights);
+        /* Can happen if the stateblock had recorded the creation of
+         * new lights. */
+        if (context->ff.num_lights < num_lights) {
+            context->ff.light = REALLOC(context->ff.light,
+                                    context->ff.num_lights * sizeof(D3DLIGHT9),
+                                    num_lights * sizeof(D3DLIGHT9));
+            memset(&context->ff.light[context->ff.num_lights], 0, (num_lights - context->ff.num_lights) * sizeof(D3DLIGHT9));
+            for (i = context->ff.num_lights; i < num_lights; ++i)
+                context->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID;
+            context->ff.num_lights = num_lights;
+        }
+        /* src->ff.num_lights < num_lights has been handled before */
+        assert (src->ff.num_lights == num_lights);
+
+        for (i = 0; i < num_lights; ++i)
+            if (src->ff.light[i].Type != NINED3DLIGHT_INVALID)
+                context->ff.light[i] = src->ff.light[i];
+
+        memcpy(context->ff.active_light, src->ff.active_light, sizeof(src->ff.active_light) );
+        context->ff.num_lights_active = src->ff.num_lights_active;
+    }
+    if (src->changed.group & NINE_STATE_FF_VSTRANSF) {
+        for (i = 0; i < ARRAY_SIZE(src->ff.changed.transform); ++i) {
+            unsigned s;
+            if (!src->ff.changed.transform[i])
+                continue;
+            for (s = i * 32; s < (i * 32 + 32); ++s) {
+                if (!(src->ff.changed.transform[i] & (1 << (s % 32))))
+                    continue;
+                *nine_state_access_transform(&context->ff, s, TRUE) =
+                    *nine_state_access_transform( /* const because !alloc */
+                        (struct nine_ff_state *)&src->ff, s, FALSE);
+            }
+            context->ff.changed.transform[i] |= src->ff.changed.transform[i];
+        }
+    }
 }
 
 static void
@@ -2106,6 +2255,11 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
     }
     state->ff.tex_stage[0][D3DTSS_COLOROP] = D3DTOP_MODULATE;
     state->ff.tex_stage[0][D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
+
+    for (s = 0; s < ARRAY_SIZE(state->ff.tex_stage); ++s)
+        memcpy(&context->ff.tex_stage[s], state->ff.tex_stage[s],
+               sizeof(state->ff.tex_stage[s]));
+
     memset(&context->bumpmap_vars, 0, sizeof(context->bumpmap_vars));
 
     for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
@@ -2142,8 +2296,8 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
     context->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
     state->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1;
 
-    state->ff.changed.transform[0] = ~0;
-    state->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32);
+    context->ff.changed.transform[0] = ~0;
+    context->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32);
 
     if (!is_reset) {
         state->viewport.MinZ = context->viewport.MinZ = 0.0f;
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index 4d1e8a4..754a3de 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -139,7 +139,7 @@
 
 struct nine_ff_state {
     struct {
-        uint32_t tex_stage[NINE_MAX_TEXTURE_STAGES][(NINED3DTSS_COUNT + 31) / 32];
+        uint32_t tex_stage[NINE_MAX_TEXTURE_STAGES][(NINED3DTSS_COUNT + 31) / 32]; /* stateblocks only */
         uint32_t transform[(NINED3DTS_COUNT + 31) / 32];
     } changed;
 
@@ -280,6 +280,8 @@ struct nine_context {
     int dummy_vbo_bound_at; /* -1 = not bound , >= 0 = bound index */
     boolean vbo_bound_done;
 
+    struct nine_ff_state ff;
+
     uint32_t commit;
     struct {
         struct pipe_framebuffer_state fb;
@@ -397,6 +399,31 @@ nine_context_set_scissor(struct NineDevice9 *device,
                          const struct pipe_scissor_state *scissor);
 
 void
+nine_context_set_transform(struct NineDevice9 *device,
+                           D3DTRANSFORMSTATETYPE State,
+                           const D3DMATRIX *pMatrix);
+
+void
+nine_context_set_material(struct NineDevice9 *device,
+                          const D3DMATERIAL9 *pMaterial);
+
+void
+nine_context_set_light(struct NineDevice9 *device,
+                       DWORD Index,
+                       const D3DLIGHT9 *pLight);
+
+void
+nine_context_light_enable(struct NineDevice9 *device,
+                          DWORD Index,
+                          BOOL Enable);
+
+void
+nine_context_set_texture_stage_state(struct NineDevice9 *device,
+                                     DWORD Stage,
+                                     D3DTEXTURESTAGESTATETYPE Type,
+                                     DWORD Value);
+
+void
 nine_context_set_render_target(struct NineDevice9 *device,
                                DWORD RenderTargetIndex,
                                struct NineSurface9 *rt);
diff --git a/src/gallium/state_trackers/nine/pixelshader9.h b/src/gallium/state_trackers/nine/pixelshader9.h
index 38874dc..67a18f2 100644
--- a/src/gallium/state_trackers/nine/pixelshader9.h
+++ b/src/gallium/state_trackers/nine/pixelshader9.h
@@ -65,7 +65,6 @@ NinePixelShader9( void *data )
 
 static inline BOOL
 NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
-                            struct nine_state *state,
                             struct nine_context *context )
 {
     uint16_t samplers_shadow;
@@ -99,7 +98,7 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
         key |= ((uint64_t)1) << 34;
 
     if (unlikely(ps->byte_code.version < 0x14)) {
-        projected = nine_ff_get_projected_key(state, context);
+        projected = nine_ff_get_projected_key(context);
         key |= ((uint64_t) projected) << 48;
     }
 
-- 
2.10.2



More information about the mesa-dev mailing list