st/nine: Move vtxbuf to nine_context

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@ens.fr>
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index ce30d26..102e5fc 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -3404,22 +3404,29 @@
     user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL);
     user_assert(Stride <= This->caps.MaxStreamStride, D3DERR_INVALIDCALL);
 
-    if (likely(!This->is_recording)) {
-        if (state->stream[i] == NineVertexBuffer9(pStreamData) &&
-            state->vtxbuf[i].stride == Stride &&
-            state->vtxbuf[i].buffer_offset == OffsetInBytes)
-            return D3D_OK;
-    }
-    nine_bind(&state->stream[i], pStreamData);
-
-    state->changed.vtxbuf |= 1 << StreamNumber;
-
-    if (pStreamData) {
+    if (unlikely(This->is_recording)) {
+        nine_bind(&state->stream[i], pStreamData);
+        state->changed.vtxbuf |= 1 << StreamNumber;
         state->vtxbuf[i].stride = Stride;
         state->vtxbuf[i].buffer_offset = OffsetInBytes;
+        return D3D_OK;
     }
-    pipe_resource_reference(&state->vtxbuf[i].buffer,
-                            pStreamData ? NineVertexBuffer9_GetResource(pVBuf9) : NULL);
+
+    if (state->stream[i] == NineVertexBuffer9(pStreamData) &&
+        state->vtxbuf[i].stride == Stride &&
+        state->vtxbuf[i].buffer_offset == OffsetInBytes)
+        return D3D_OK;
+
+    state->vtxbuf[i].stride = Stride;
+    state->vtxbuf[i].buffer_offset = OffsetInBytes;
+
+    nine_bind(&state->stream[i], pStreamData);
+
+    nine_context_set_stream_source(This,
+                                   StreamNumber,
+                                   pVBuf9,
+                                   OffsetInBytes,
+                                   Stride);
 
     return D3D_OK;
 }
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index 0733d6e..066ed7f 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -668,9 +668,9 @@
 
     if (context->dummy_vbo_bound_at != dummy_vbo_stream) {
         if (context->dummy_vbo_bound_at >= 0)
-            state->changed.vtxbuf |= 1 << context->dummy_vbo_bound_at;
+            context->changed.vtxbuf |= 1 << context->dummy_vbo_bound_at;
         if (dummy_vbo_stream >= 0) {
-            state->changed.vtxbuf |= 1 << dummy_vbo_stream;
+            context->changed.vtxbuf |= 1 << dummy_vbo_stream;
             context->vbo_bound_done = FALSE;
         }
         context->dummy_vbo_bound_at = dummy_vbo_stream;
@@ -686,9 +686,8 @@
 {
     struct pipe_context *pipe = device->pipe;
     struct nine_context *context = &device->context;
-    struct nine_state *state = &device->state;
     struct pipe_vertex_buffer dummy_vtxbuf;
-    uint32_t mask = state->changed.vtxbuf;
+    uint32_t mask = context->changed.vtxbuf;
     unsigned i;
 
     DBG("mask=%x\n", mask);
@@ -708,14 +707,14 @@
 
     for (i = 0; mask; mask >>= 1, ++i) {
         if (mask & 1) {
-            if (state->vtxbuf[i].buffer)
-                pipe->set_vertex_buffers(pipe, i, 1, &state->vtxbuf[i]);
+            if (context->vtxbuf[i].buffer)
+                pipe->set_vertex_buffers(pipe, i, 1, &context->vtxbuf[i]);
             else
                 pipe->set_vertex_buffers(pipe, i, 1, NULL);
         }
     }
 
-    state->changed.vtxbuf = 0;
+    context->changed.vtxbuf = 0;
 }
 
 static inline boolean
@@ -1064,7 +1063,7 @@
             prepare_ps_constants_userbuf(device);
     }
 
-    if (state->changed.vtxbuf)
+    if (context->changed.vtxbuf)
         update_vertex_buffers(device);
 
     if (context->commit & NINE_STATE_COMMIT_BLEND)
@@ -1241,6 +1240,26 @@
 }
 
 void
+nine_context_set_stream_source(struct NineDevice9 *device,
+                               UINT StreamNumber,
+                               struct NineVertexBuffer9 *pVBuf9,
+                               UINT OffsetInBytes,
+                               UINT Stride)
+{
+    struct nine_context *context = &device->context;
+    const unsigned i = StreamNumber;
+
+    context->changed.vtxbuf |= 1 << StreamNumber;
+
+    if (pVBuf9) {
+        context->vtxbuf[i].stride = Stride;
+        context->vtxbuf[i].buffer_offset = OffsetInBytes;
+    }
+    pipe_resource_reference(&context->vtxbuf[i].buffer,
+                            pVBuf9 ? NineVertexBuffer9_GetResource(pVBuf9) : NULL);
+}
+
+void
 nine_context_apply_stateblock(struct NineDevice9 *device,
                               const struct nine_state *src)
 {
@@ -1272,6 +1291,22 @@
             nine_bind(&context->texture[s], src->texture[s]);
         }
     }
+
+    /* Vertex buffers */
+    if (src->changed.vtxbuf | src->changed.stream_freq) {
+        uint32_t m = src->changed.vtxbuf | src->changed.stream_freq;
+        for (i = 0; m; ++i, m >>= 1) {
+            if (src->changed.vtxbuf & (1 << i)) {
+                if (src->stream[i]) {
+                    context->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
+                    pipe_resource_reference(&context->vtxbuf[i].buffer,
+                        src->stream[i] ? NineVertexBuffer9_GetResource(src->stream[i]) : NULL);
+                    context->vtxbuf[i].stride = src->vtxbuf[i].stride;
+                }
+            }
+        }
+        context->changed.vtxbuf |= src->changed.vtxbuf;
+    }
 }
 
 static void
@@ -1702,7 +1737,7 @@
     struct nine_context *context = &device->context;
 
     state->changed.group = NINE_STATE_ALL;
-    state->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
+    context->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
     state->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1;
     context->commit |= NINE_STATE_COMMIT_CONST_VS | NINE_STATE_COMMIT_CONST_PS;
 }
@@ -1749,7 +1784,7 @@
     /* Set changed flags to initialize driver.
      */
     state->changed.group = NINE_STATE_ALL;
-    state->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
+    context->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
     state->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1;
 
     state->ff.changed.transform[0] = ~0;
@@ -1780,10 +1815,9 @@
     nine_bind(&state->vs, NULL);
     nine_bind(&state->ps, NULL);
     nine_bind(&state->vdecl, NULL);
-    for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
+    for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
         nine_bind(&state->stream[i], NULL);
-        pipe_resource_reference(&state->vtxbuf[i].buffer, NULL);
-    }
+
     nine_bind(&state->idxbuf, NULL);
     for (i = 0; i < NINE_MAX_SAMPLERS; ++i) {
         if (device &&
@@ -1799,6 +1833,9 @@
 {
     unsigned i;
 
+    for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
+        pipe_resource_reference(&context->vtxbuf[i].buffer, NULL);
+
     for (i = 0; i < NINE_MAX_SAMPLERS; ++i)
         nine_bind(&context->texture[i], NULL);
 }
@@ -1922,11 +1959,12 @@
 
     for (i = 0; mask; mask >>= 1, ++i) {
         if (mask & 1) {
-            if (state->vtxbuf[i].buffer) {
+            if (state->stream[i]) {
                 struct pipe_resource *buf;
                 struct pipe_box box;
 
                 vtxbuf = state->vtxbuf[i];
+                vtxbuf.buffer = NineVertexBuffer9_GetResource(state->stream[i]);
 
                 DBG("Locking %p (offset %d, length %d)\n", vtxbuf.buffer,
                     vtxbuf.buffer_offset, num_vertices * vtxbuf.stride);
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index 7711a2b..e111f09 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -136,7 +136,7 @@
     struct {
         uint32_t group;
         uint32_t rs[(NINED3DRS_COUNT + 31) / 32]; /* stateblocks only */
-        uint32_t vtxbuf;
+        uint32_t vtxbuf; /* stateblocks only */
         uint32_t stream_freq;
         uint32_t texture; /* stateblocks only */
         uint16_t sampler[NINE_MAX_SAMPLERS];
@@ -178,7 +178,7 @@
 
     struct NineIndexBuffer9   *idxbuf;
     struct NineVertexBuffer9  *stream[PIPE_MAX_ATTRIBS];
-    struct pipe_vertex_buffer  vtxbuf[PIPE_MAX_ATTRIBS];
+    struct pipe_vertex_buffer  vtxbuf[PIPE_MAX_ATTRIBS]; /* vtxbuf.buffer unused */
     UINT stream_freq[PIPE_MAX_ATTRIBS];
     uint32_t stream_instancedata_mask; /* derived from stream_freq */
 
@@ -215,6 +215,10 @@
 };
 
 struct nine_context {
+    struct {
+        uint32_t vtxbuf;
+    } changed;
+
     uint32_t bumpmap_vars[6 * NINE_MAX_TEXTURE_STAGES];
 
     struct {
@@ -224,6 +228,7 @@
 
     uint8_t rt_mask;
 
+    struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
     uint32_t stream_usage_mask; /* derived from VS and vdecl */
 
     DWORD rs[NINED3DRS_COUNT];
@@ -281,6 +286,13 @@
                          struct NineBaseTexture9 *tex);
 
 void
+nine_context_set_stream_source(struct NineDevice9 *device,
+                               UINT StreamNumber,
+                               struct NineVertexBuffer9 *pVBuf9,
+                               UINT OffsetInBytes,
+                               UINT Stride);
+
+void
 nine_context_apply_stateblock(struct NineDevice9 *device,
                               const struct nine_state *src);
 
diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c
index d0063ed..3ebee84 100644
--- a/src/gallium/state_trackers/nine/stateblock9.c
+++ b/src/gallium/state_trackers/nine/stateblock9.c
@@ -276,7 +276,6 @@
                 nine_bind(&dst->stream[i], src->stream[i]);
                 if (src->stream[i]) {
                     dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
-                    pipe_resource_reference(&dst->vtxbuf[i].buffer, src->vtxbuf[i].buffer);
                     dst->vtxbuf[i].stride = src->vtxbuf[i].stride;
                 }
             }
@@ -463,7 +462,6 @@
             nine_bind(&dst->stream[i], src->stream[i]);
             if (src->stream[i]) {
                 dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
-                pipe_resource_reference(&dst->vtxbuf[i].buffer, src->vtxbuf[i].buffer);
                 dst->vtxbuf[i].stride = src->vtxbuf[i].stride;
             }
             dst->stream_freq[i] = src->stream_freq[i];