st/nine: Capture also default matrices for D3DSBT_ALL
authorAxel Davy <davyaxel0@gmail.com>
Sun, 23 Sep 2018 14:22:01 +0000 (16:22 +0200)
committerAxel Davy <davyaxel0@gmail.com>
Fri, 26 Oct 2018 20:16:16 +0000 (22:16 +0200)
We avoid allocating space for never unused matrices.
However we must do as if we had captured them.
Thus when a D3DSBT_ALL stateblock apply has fewer matrices
than device state, allocate the default matrices for the stateblock
before applying.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
src/gallium/state_trackers/nine/nine_state.c
src/gallium/state_trackers/nine/nine_state.h
src/gallium/state_trackers/nine/stateblock9.c

index f4d9b4235103bb590f3ad30268e9d24da1eea826..569a1b472924842fe552cc90158c6ea6d04f6fd9 100644 (file)
@@ -3398,14 +3398,31 @@ const uint32_t nine_render_state_group[NINED3DRS_LAST + 1] =
 
 /* Misc */
 
+static D3DMATRIX nine_state_identity = { .m[0] = { 1, 0, 0, 0 },
+                                         .m[1] = { 0, 1, 0, 0 },
+                                         .m[2] = { 0, 0, 1, 0 },
+                                         .m[3] = { 0, 0, 0, 1 } };
+
+void
+nine_state_resize_transform(struct nine_ff_state *ff_state, unsigned N)
+{
+    unsigned n = ff_state->num_transforms;
+
+    if (N <= n)
+        return;
+
+    ff_state->transform = REALLOC(ff_state->transform,
+                                  n * sizeof(D3DMATRIX),
+                                  N * sizeof(D3DMATRIX));
+    for (; n < N; ++n)
+        ff_state->transform[n] = nine_state_identity;
+    ff_state->num_transforms = N;
+}
+
 D3DMATRIX *
 nine_state_access_transform(struct nine_ff_state *ff_state, D3DTRANSFORMSTATETYPE t,
                             boolean alloc)
 {
-    static D3DMATRIX Identity = { .m[0] = { 1, 0, 0, 0 },
-                                  .m[1] = { 0, 1, 0, 0 },
-                                  .m[2] = { 0, 0, 1, 0 },
-                                  .m[3] = { 0, 0, 0, 1 } };
     unsigned index;
 
     switch (t) {
@@ -3427,17 +3444,9 @@ nine_state_access_transform(struct nine_ff_state *ff_state, D3DTRANSFORMSTATETYP
     }
 
     if (index >= ff_state->num_transforms) {
-        unsigned N = index + 1;
-        unsigned n = ff_state->num_transforms;
-
         if (!alloc)
-            return &Identity;
-        ff_state->transform = REALLOC(ff_state->transform,
-                                      n * sizeof(D3DMATRIX),
-                                      N * sizeof(D3DMATRIX));
-        for (; n < N; ++n)
-            ff_state->transform[n] = Identity;
-        ff_state->num_transforms = N;
+            return &nine_state_identity;
+        nine_state_resize_transform(ff_state, index + 1);
     }
     return &ff_state->transform[index];
 }
index 7c4517b3fefaf8be0584640482a8b12abe13be11..55ccfd0f519f1f07229de0fbdc69978a3f2f798a 100644 (file)
@@ -609,6 +609,9 @@ void nine_state_prepare_draw_sw(struct NineDevice9 *device,
 void nine_state_after_draw_sw(struct NineDevice9 *device);
 void nine_state_destroy_sw(struct NineDevice9 *device);
 
+void
+nine_state_resize_transform(struct nine_ff_state *ff_state, unsigned N);
+
 /* If @alloc is FALSE, the return value may be a const identity matrix.
  * Therefore, do not modify if you set alloc to FALSE !
  */
index ebfd622ff916204576a83ed9277dcf9fac0d88a6..7b2deae7f9bcd319d66e3595d01b1c8f7f39e5e0 100644 (file)
@@ -357,8 +357,7 @@ nine_state_copy_common(struct NineDevice9 *device,
                 if (!(mask->ff.changed.transform[i] & (1 << (s % 32))))
                     continue;
                 *nine_state_access_transform(&dst->ff, s, TRUE) =
-                    *nine_state_access_transform( /* const because !alloc */
-                        (struct nine_ff_state *)&src->ff, s, FALSE);
+                    *nine_state_access_transform(&src->ff, s, FALSE);
             }
             if (apply)
                 dst->ff.changed.transform[i] |= mask->ff.changed.transform[i];
@@ -369,7 +368,7 @@ nine_state_copy_common(struct NineDevice9 *device,
 static void
 nine_state_copy_common_all(struct NineDevice9 *device,
                            struct nine_state *dst,
-                           const struct nine_state *src,
+                           struct nine_state *src,
                            struct nine_state *help,
                            const boolean apply,
                            struct nine_range_pool *pool,
@@ -488,15 +487,21 @@ nine_state_copy_common_all(struct NineDevice9 *device,
 
     /* Transforms. */
     if (1) {
-        if (dst->ff.num_transforms < src->ff.num_transforms) {
-            dst->ff.transform = REALLOC(dst->ff.transform,
-                dst->ff.num_transforms * sizeof(dst->ff.transform[0]),
-                src->ff.num_transforms * sizeof(src->ff.transform[0]));
-            dst->ff.num_transforms = src->ff.num_transforms;
+        /* Increase dst size if required (to copy the new states).
+         * Increase src size if required (to initialize missing transforms).
+         */
+        if (dst->ff.num_transforms != src->ff.num_transforms) {
+            int num_transforms = MAX2(src->ff.num_transforms, dst->ff.num_transforms);
+            nine_state_resize_transform(&src->ff, num_transforms);
+            nine_state_resize_transform(&dst->ff, num_transforms);
         }
         memcpy(dst->ff.transform,
-               src->ff.transform, src->ff.num_transforms * sizeof(D3DMATRIX));
-        if (apply) /* TODO: memset */
+               src->ff.transform, dst->ff.num_transforms * sizeof(D3DMATRIX));
+        /* Apply is always used on device state.
+         * src is then the D3DSBT_ALL stateblock which
+         * ff.changed.transform indicates all matrices are dirty.
+         */
+        if (apply)
             memcpy(dst->ff.changed.transform,
                    src->ff.changed.transform, sizeof(dst->ff.changed.transform));
     }