st/nine: Fix volumetexture dtor on ctor failure
[mesa.git] / src / gallium / state_trackers / nine / stateblock9.c
index 0aa69be16b95d426b3c41ac73afe7689ab265e2f..50ed70aec3a3bae2df2710b919674b4d02829145 100644 (file)
@@ -25,6 +25,8 @@
 #include "basetexture9.h"
 #include "nine_helpers.h"
 #include "vertexdeclaration9.h"
+#include "vertexbuffer9.h"
+#include "indexbuffer9.h"
 
 #define DBG_CHANNEL DBG_STATEBLOCK
 
@@ -93,6 +95,30 @@ NineStateBlock9_dtor( struct NineStateBlock9 *This )
     NineUnknown_dtor(&This->base);
 }
 
+static void
+NineStateBlock9_BindBuffer( struct NineDevice9 *device,
+                            boolean applyToDevice,
+                            struct NineBuffer9 **slot,
+                            struct NineBuffer9 *buf )
+{
+    if (applyToDevice)
+        NineBindBufferToDevice(device, slot, buf);
+    else
+        nine_bind(slot, buf);
+}
+
+static void
+NineStateBlock9_BindTexture( struct NineDevice9 *device,
+                             boolean applyToDevice,
+                             struct NineBaseTexture9 **slot,
+                             struct NineBaseTexture9 *tex )
+{
+    if (applyToDevice)
+        NineBindTextureToDevice(device, slot, tex);
+    else
+        nine_bind(slot, tex);
+}
+
 /* Copy state marked changed in @mask from @src to @dst.
  * If @apply is false, updating dst->changed can be omitted.
  * TODO: compare ?
@@ -108,8 +134,15 @@ nine_state_copy_common(struct NineDevice9 *device,
     unsigned i, s;
 
     DBG("apply:%d changed.group: %x\n", (int)apply, (int)mask->changed.group );
-    if (apply)
-       dst->changed.group |= mask->changed.group;
+
+    /* device changed.* are unused.
+     * Instead nine_context_apply_stateblock is used and will
+     * internally set the right context->changed fields.
+     * Uncomment these only if we want to apply a stateblock onto a stateblock.
+     *
+     * if (apply)
+     *     dst->changed.group |= mask->changed.group;
+     */
 
     if (mask->changed.group & NINE_STATE_VIEWPORT)
         dst->viewport = src->viewport;
@@ -176,10 +209,10 @@ nine_state_copy_common(struct NineDevice9 *device,
     /* Render states.
      * TODO: Maybe build a list ?
      */
-    for (i = 0; i < ARRAY_SIZE(dst->changed.rs); ++i) {
+    for (i = 0; i < ARRAY_SIZE(mask->changed.rs); ++i) {
         uint32_t m = mask->changed.rs[i];
-        if (apply)
-            dst->changed.rs[i] |= m;
+        /* if (apply)
+         *     dst->changed.rs[i] |= m; */
         while (m) {
             const int r = ffs(m) - 1;
             m &= ~(1 << r);
@@ -196,8 +229,8 @@ nine_state_copy_common(struct NineDevice9 *device,
             if (mask->changed.ucp & (1 << i))
                 memcpy(dst->clip.ucp[i],
                        src->clip.ucp[i], sizeof(src->clip.ucp[0]));
-        if (apply)
-           dst->changed.ucp |= mask->changed.ucp;
+        /* if (apply)
+         *    dst->changed.ucp |= mask->changed.ucp;*/
     }
 
     /* Sampler state. */
@@ -214,14 +247,17 @@ nine_state_copy_common(struct NineDevice9 *device,
                     dst->samp_advertised[s][i] = src->samp_advertised[s][i];
                 }
             }
-            if (apply)
-                dst->changed.sampler[s] |= mask->changed.sampler[s];
+            /* if (apply)
+             *     dst->changed.sampler[s] |= mask->changed.sampler[s];*/
         }
     }
 
     /* Index buffer. */
     if (mask->changed.group & NINE_STATE_IDXBUF)
-        nine_bind(&dst->idxbuf, src->idxbuf);
+        NineStateBlock9_BindBuffer(device,
+                                   apply,
+                                   (struct NineBuffer9 **)&dst->idxbuf,
+                                   (struct NineBuffer9 *)src->idxbuf);
 
     /* Vertex streams. */
     if (mask->changed.vtxbuf | mask->changed.stream_freq) {
@@ -229,7 +265,10 @@ nine_state_copy_common(struct NineDevice9 *device,
         uint32_t m = mask->changed.vtxbuf | mask->changed.stream_freq;
         for (i = 0; m; ++i, m >>= 1) {
             if (mask->changed.vtxbuf & (1 << i)) {
-                nine_bind(&dst->stream[i], src->stream[i]);
+                NineStateBlock9_BindBuffer(device,
+                                           apply,
+                                           (struct NineBuffer9 **)&dst->stream[i],
+                                           (struct NineBuffer9 *)src->stream[i]);
                 if (src->stream[i]) {
                     dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
                     dst->vtxbuf[i].stride = src->vtxbuf[i].stride;
@@ -238,10 +277,19 @@ nine_state_copy_common(struct NineDevice9 *device,
             if (mask->changed.stream_freq & (1 << i))
                 dst->stream_freq[i] = src->stream_freq[i];
         }
-        if (apply) {
-            dst->changed.vtxbuf |= mask->changed.vtxbuf;
-            dst->changed.stream_freq |= mask->changed.stream_freq;
-        }
+        /*
+         * if (apply) {
+         *     dst->changed.vtxbuf |= mask->changed.vtxbuf;
+         *     dst->changed.stream_freq |= mask->changed.stream_freq;
+         * }*/
+    }
+
+    /* Textures */
+    if (mask->changed.texture) {
+        uint32_t m = mask->changed.texture;
+        for (s = 0; m; ++s, m >>= 1)
+            if (m & 1)
+                NineStateBlock9_BindTexture(device, apply, &dst->texture[s], src->texture[s]);
     }
 
     if (!(mask->changed.group & NINE_STATE_FF))
@@ -253,18 +301,19 @@ nine_state_copy_common(struct NineDevice9 *device,
     if (mask->changed.group & NINE_STATE_FF_MATERIAL)
         dst->ff.material = src->ff.material;
 
-    if (mask->changed.group & NINE_STATE_FF_PSSTAGES) {
+    if (mask->changed.group & NINE_STATE_FF_PS_CONSTS) {
         for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) {
             for (i = 0; i < NINED3DTSS_COUNT; ++i)
                 if (mask->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32)))
                     dst->ff.tex_stage[s][i] = src->ff.tex_stage[s][i];
-            if (apply) {
-                /* TODO: it's 32 exactly, just offset by 1 as 0 is unused */
-                dst->ff.changed.tex_stage[s][0] |=
-                    mask->ff.changed.tex_stage[s][0];
-                dst->ff.changed.tex_stage[s][1] |=
-                    mask->ff.changed.tex_stage[s][1];
-            }
+            /*
+             * if (apply) {
+             *    TODO: it's 32 exactly, just offset by 1 as 0 is unused
+             *    dst->ff.changed.tex_stage[s][0] |=
+             *        mask->ff.changed.tex_stage[s][0];
+             *    dst->ff.changed.tex_stage[s][1] |=
+             *        mask->ff.changed.tex_stage[s][1];
+             * }*/
         }
     }
     if (mask->changed.group & NINE_STATE_FF_LIGHTING) {
@@ -316,12 +365,11 @@ nine_state_copy_common(struct NineDevice9 *device,
             for (s = i * 32; s < (i * 32 + 32); ++s) {
                 if (!(mask->ff.changed.transform[i] & (1 << (s % 32))))
                     continue;
-                *nine_state_access_transform(dst, s, TRUE) =
-                    *nine_state_access_transform( /* const because !alloc */
-                        (struct nine_state *)src, s, FALSE);
+                *nine_state_access_transform(&dst->ff, s, TRUE) =
+                    *nine_state_access_transform(&src->ff, s, FALSE);
             }
-            if (apply)
-                dst->ff.changed.transform[i] |= mask->ff.changed.transform[i];
+            /* if (apply)
+             *     dst->ff.changed.transform[i] |= mask->ff.changed.transform[i];*/
         }
     }
 }
@@ -329,7 +377,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,
@@ -337,8 +385,9 @@ nine_state_copy_common_all(struct NineDevice9 *device,
 {
     unsigned i;
 
-    if (apply)
-       dst->changed.group |= src->changed.group;
+    /* if (apply)
+     *     dst->changed.group |= src->changed.group;
+     */
 
     dst->viewport = src->viewport;
     dst->scissor = src->scissor;
@@ -372,38 +421,50 @@ nine_state_copy_common_all(struct NineDevice9 *device,
 
     /* Render states. */
     memcpy(dst->rs_advertised, src->rs_advertised, sizeof(dst->rs_advertised));
-    if (apply)
-        memcpy(dst->changed.rs, src->changed.rs, sizeof(dst->changed.rs));
+    /* if (apply)
+     *     memcpy(dst->changed.rs, src->changed.rs, sizeof(dst->changed.rs));*/
 
 
     /* Clip planes. */
     memcpy(&dst->clip, &src->clip, sizeof(dst->clip));
-    if (apply)
-        dst->changed.ucp = src->changed.ucp;
+    /* if (apply)
+     *     dst->changed.ucp = src->changed.ucp;*/
 
     /* Sampler state. */
     memcpy(dst->samp_advertised, src->samp_advertised, sizeof(dst->samp_advertised));
-    if (apply)
-        memcpy(dst->changed.sampler,
-               src->changed.sampler, sizeof(dst->changed.sampler));
+    /* if (apply)
+     *     memcpy(dst->changed.sampler,
+     *            src->changed.sampler, sizeof(dst->changed.sampler));*/
 
     /* Index buffer. */
-    nine_bind(&dst->idxbuf, src->idxbuf);
+    NineStateBlock9_BindBuffer(device,
+                               apply,
+                               (struct NineBuffer9 **)&dst->idxbuf,
+                               (struct NineBuffer9 *)src->idxbuf);
 
     /* Vertex streams. */
     if (1) {
         for (i = 0; i < ARRAY_SIZE(dst->stream); ++i) {
-            nine_bind(&dst->stream[i], src->stream[i]);
+            NineStateBlock9_BindBuffer(device,
+                                       apply,
+                                       (struct NineBuffer9 **)&dst->stream[i],
+                                       (struct NineBuffer9 *)src->stream[i]);
             if (src->stream[i]) {
                 dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
                 dst->vtxbuf[i].stride = src->vtxbuf[i].stride;
             }
             dst->stream_freq[i] = src->stream_freq[i];
         }
-        if (apply) {
-            dst->changed.vtxbuf = (1ULL << MaxStreams) - 1;
-            dst->changed.stream_freq = (1ULL << MaxStreams) - 1;
-        }
+        /* if (apply) {
+         *     dst->changed.vtxbuf = (1ULL << MaxStreams) - 1;
+         *     dst->changed.stream_freq = (1ULL << MaxStreams) - 1;
+         *  }*/
+    }
+
+    /* Textures */
+    if (1) {
+        for (i = 0; i < NINE_MAX_SAMPLERS; i++)
+            NineStateBlock9_BindTexture(device, apply, &dst->texture[i], src->texture[i]);
     }
 
     /* keep this check in case we want to disable FF */
@@ -415,9 +476,9 @@ nine_state_copy_common_all(struct NineDevice9 *device,
     dst->ff.material = src->ff.material;
 
     memcpy(dst->ff.tex_stage, src->ff.tex_stage, sizeof(dst->ff.tex_stage));
-    if (apply) /* TODO: memset */
-        memcpy(dst->ff.changed.tex_stage,
-               src->ff.changed.tex_stage, sizeof(dst->ff.changed.tex_stage));
+    /* if (apply) TODO: memset
+     *     memcpy(dst->ff.changed.tex_stage,
+     *            src->ff.changed.tex_stage, sizeof(dst->ff.changed.tex_stage));*/
 
     /* Lights. */
     if (1) {
@@ -436,17 +497,23 @@ 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 */
-            memcpy(dst->ff.changed.transform,
-                   src->ff.changed.transform, sizeof(dst->ff.changed.transform));
+               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));*/
     }
 }
 
@@ -460,7 +527,6 @@ NineStateBlock9_Capture( struct NineStateBlock9 *This )
     struct nine_state *dst = &This->state;
     struct nine_state *src = &device->state;
     const int MaxStreams = device->caps.MaxStreams;
-    unsigned s;
 
     DBG("This=%p\n", This);
 
@@ -472,14 +538,6 @@ NineStateBlock9_Capture( struct NineStateBlock9 *This )
     if (dst->changed.group & NINE_STATE_VDECL)
         nine_bind(&dst->vdecl, src->vdecl);
 
-    /* Textures */
-    if (dst->changed.texture) {
-        uint32_t m = dst->changed.texture;
-        for (s = 0; m; ++s, m >>= 1)
-            if (m & 1)
-                nine_bind(&dst->texture[s], src->texture[s]);
-    }
-
     return D3D_OK;
 }
 
@@ -492,7 +550,6 @@ NineStateBlock9_Apply( struct NineStateBlock9 *This )
     struct nine_state *src = &This->state;
     struct nine_range_pool *pool = &device->range_pool;
     const int MaxStreams = device->caps.MaxStreams;
-    unsigned s;
 
     DBG("This=%p\n", This);
 
@@ -506,25 +563,6 @@ NineStateBlock9_Apply( struct NineStateBlock9 *This )
     if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
         nine_bind(&dst->vdecl, src->vdecl);
 
-    /* Textures */
-    if (src->changed.texture) {
-        uint32_t m = src->changed.texture;
-
-        for (s = 0; m; ++s, m >>= 1) {
-            struct NineBaseTexture9 *tex = src->texture[s];
-            if (!(m & 1))
-                continue;
-            if (tex) {
-                tex->bind_count++;
-                if ((tex->managed.dirty | tex->dirty_mip) && LIST_IS_EMPTY(&tex->list))
-                    list_add(&tex->list, &This->base.device->update_textures);
-            }
-            if (src->texture[s])
-                src->texture[s]->bind_count--;
-            nine_bind(&dst->texture[s], src->texture[s]);
-        }
-    }
-
     return D3D_OK;
 }