st/nine: Track bindings for buffers

Similar code than for textures.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
diff --git a/src/gallium/state_trackers/nine/buffer9.h b/src/gallium/state_trackers/nine/buffer9.h
index df368b6..0dd2fc6 100644
--- a/src/gallium/state_trackers/nine/buffer9.h
+++ b/src/gallium/state_trackers/nine/buffer9.h
@@ -43,6 +43,8 @@
     int nmaps, maxmaps;
     UINT size;
 
+    int16_t bind_count; /* to Device9->state.stream */
+
     /* Specific to managed buffers */
     struct {
         void *data;
@@ -95,6 +97,22 @@
     This->managed.dirty = FALSE;
 }
 
+static void inline
+NineBindBufferToDevice( struct NineDevice9 *device,
+                        struct NineBuffer9 **slot,
+                        struct NineBuffer9 *buf )
+{
+    struct NineBuffer9 *old = *slot;
+
+    (void)device;
+    if (buf)
+        buf->bind_count++;
+    if (old)
+        old->bind_count--;
+
+    nine_bind(slot, buf);
+}
+
 void
 NineBuffer9_SetDirty( struct NineBuffer9 *This );
 
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 101761f..2b60280 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -3471,7 +3471,9 @@
     state->vtxbuf[i].stride = Stride;
     state->vtxbuf[i].buffer_offset = OffsetInBytes;
 
-    nine_bind(&state->stream[i], pStreamData);
+    NineBindBufferToDevice(This,
+                           (struct NineBuffer9 **)&state->stream[i],
+                           (struct NineBuffer9 *)pVBuf9);
 
     nine_context_set_stream_source(This,
                                    StreamNumber,
@@ -3564,7 +3566,10 @@
 
     if (state->idxbuf == idxbuf)
         return D3D_OK;
-    nine_bind(&state->idxbuf, idxbuf);
+
+    NineBindBufferToDevice(This,
+                           (struct NineBuffer9 **)&state->idxbuf,
+                           (struct NineBuffer9 *)idxbuf);
 
     nine_context_set_indices(This, idxbuf);
 
diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c
index 02ffa8c..4b7166f 100644
--- a/src/gallium/state_trackers/nine/stateblock9.c
+++ b/src/gallium/state_trackers/nine/stateblock9.c
@@ -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
 
@@ -94,6 +96,18 @@
 }
 
 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,
@@ -233,7 +247,10 @@
 
     /* 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) {
@@ -241,7 +258,10 @@
         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;
@@ -408,12 +428,18 @@
                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;