From 3f7a369ba516a2ebe970a5160293d190f806f65e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Sun, 7 Apr 2013 17:53:43 +0200
Subject: wined3d: Send primitive type updates through the command stream

---
 dlls/wined3d/cs.c              | 39 ++++++++++++++++++++++++++++++++++-----
 dlls/wined3d/device.c          |  5 ++---
 dlls/wined3d/stateblock.c      |  4 ++--
 dlls/wined3d/wined3d_private.h |  2 ++
 4 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index f385449..8a28c40 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -68,6 +68,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_SET_PS_CONSTS_F,
     WINED3D_CS_OP_GLFINISH,
     WINED3D_CS_OP_SET_BASE_VERTEX_INDEX,
+    WINED3D_CS_OP_SET_PRIMITIVE_TYPE,
     WINED3D_CS_OP_STOP,
 };
 
@@ -307,6 +308,12 @@ struct wined3d_cs_set_base_vertex_index
     UINT base_vertex_index;
 };
 
+struct wined3d_cs_set_primitive_type
+{
+    enum wined3d_cs_op opcode;
+    GLenum gl_primitive_type;
+};
+
 /* FIXME: The list synchronization probably isn't particularly fast. */
 static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block)
 {
@@ -977,9 +984,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi
 
     /* Don't memcpy the entire struct, we'll remove single items as we add dedicated
      * ops for setting states */
-
-    cs->state.gl_primitive_type = op->state.gl_primitive_type;
-
     memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b));
     memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i));
 
@@ -1000,8 +1004,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win
 
     /* Don't memcpy the entire struct, we'll remove single items as we add dedicated
      * ops for setting states */
-    op->state.gl_primitive_type = state->gl_primitive_type;
-
     memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b));
     memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i));
 
@@ -1434,6 +1436,32 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs,
     cs->ops->submit(cs);
 }
 
+static UINT wined3d_cs_exec_set_primitive_type(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_set_primitive_type *op = data;
+    GLenum prev;
+
+    prev = cs->state.gl_primitive_type;
+
+    if (op->gl_primitive_type == GL_POINTS || prev == GL_POINTS)
+        device_invalidate_state(cs->device, STATE_POINT_ENABLE);
+
+    cs->state.gl_primitive_type = op->gl_primitive_type;
+
+    return sizeof(*op);
+}
+
+void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_type)
+{
+    struct wined3d_cs_set_primitive_type *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_SET_PRIMITIVE_TYPE;
+    op->gl_primitive_type = primitive_type;
+
+    cs->ops->submit(cs);
+}
+
 static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
 {
     /* WINED3D_CS_OP_FENCE                      */ wined3d_cs_exec_fence,
@@ -1468,6 +1496,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_PS_CONSTS_F            */ wined3d_cs_exec_set_ps_consts_f,
     /* WINED3D_CS_OP_GLFINISH                   */ wined3d_cs_exec_glfinish,
     /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX      */ wined3d_cs_exec_set_base_vertex_index,
+    /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE         */ wined3d_cs_exec_set_primitive_type,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 939d525..49ec1dc 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3377,7 +3377,6 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
         enum wined3d_primitive_type primitive_type)
 {
     GLenum gl_primitive_type, prev;
-
     TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type));
 
     gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
@@ -3385,8 +3384,8 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
     device->update_state->gl_primitive_type = gl_primitive_type;
     if (device->recording)
         device->recording->changed.primitive_type = TRUE;
-    else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
-        device_invalidate_state(device, STATE_POINT_ENABLE);
+    else if (gl_primitive_type != prev)
+        wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type);
 }
 
 void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device,
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 790d769..cd07055 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -1075,8 +1075,8 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
         gl_primitive_type = stateblock->state.gl_primitive_type;
         prev = device->update_state->gl_primitive_type;
         device->update_state->gl_primitive_type = gl_primitive_type;
-        if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
-            device_invalidate_state(device, STATE_POINT_ENABLE);
+        if (gl_primitive_type != prev)
+            wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type);
     }
 
     if (stateblock->changed.indices)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3d65d93..bae0336 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2675,6 +2675,8 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, co
 void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs,
         UINT base_vertex_index) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs,
+        GLenum primitive_type) DECLSPEC_HIDDEN;
 
 /* Direct3D terminology with little modifications. We do not have an issued state
  * because only the driver knows about it, but we have a created state because d3d
-- 
2.4.2

