[PATCH 8/8] wined3d: Add support for patch list primitive type.

Józef Kucia jkucia at codeweavers.com
Thu May 18 08:20:01 CDT 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/d3d11/d3d11_private.h     |  4 ++++
 dlls/d3d11/device.c            | 24 ++++++++++++++++--------
 dlls/d3d11/utils.c             | 41 +++++++++++++++++++++++++++++++++++++++++
 dlls/d3d8/device.c             | 12 ++++++------
 dlls/d3d9/device.c             | 12 ++++++------
 dlls/ddraw/device.c            | 12 ++++++------
 dlls/ddraw/executebuffer.c     |  6 +++---
 dlls/wined3d/cs.c              |  8 ++++++--
 dlls/wined3d/device.c          | 29 +++++++++++++++++------------
 dlls/wined3d/drawprim.c        |  6 ++++++
 dlls/wined3d/stateblock.c      |  1 +
 dlls/wined3d/wined3d.spec      |  4 ++--
 dlls/wined3d/wined3d_private.h |  7 ++++---
 include/wine/wined3d.h         |  4 ++--
 14 files changed, 120 insertions(+), 50 deletions(-)

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 3f6622f..57f1e90 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -62,6 +62,10 @@ const char *debug_float4(const float *values) DECLSPEC_HIDDEN;
 
 DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN;
+void d3d11_primitive_topology_from_wined3d_primitive_type(enum wined3d_primitive_type primitive_type,
+        unsigned int patch_vertex_count, D3D11_PRIMITIVE_TOPOLOGY *topology) DECLSPEC_HIDDEN;
+void wined3d_primitive_type_from_d3d11_primitive_topology(D3D11_PRIMITIVE_TOPOLOGY topology,
+        enum wined3d_primitive_type *type, unsigned int *patch_vertex_count) DECLSPEC_HIDDEN;
 unsigned int wined3d_getdata_flags_from_d3d11_async_getdata_flags(unsigned int d3d11_flags) DECLSPEC_HIDDEN;
 DWORD wined3d_usage_from_d3d11(UINT bind_flags, enum D3D11_USAGE usage) DECLSPEC_HIDDEN;
 struct wined3d_resource *wined3d_resource_from_d3d11_resource(ID3D11Resource *resource) DECLSPEC_HIDDEN;
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index f15192d..8966460 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -442,11 +442,15 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_IASetPrimitiveTopology(ID3
         D3D11_PRIMITIVE_TOPOLOGY topology)
 {
     struct d3d_device *device = device_from_immediate_ID3D11DeviceContext(iface);
+    enum wined3d_primitive_type primitive_type;
+    unsigned int patch_vertex_count;
 
-    TRACE("iface %p, topology %u.\n", iface, topology);
+    TRACE("iface %p, topology %#x.\n", iface, topology);
+
+    wined3d_primitive_type_from_d3d11_primitive_topology(topology, &primitive_type, &patch_vertex_count);
 
     wined3d_mutex_lock();
-    wined3d_device_set_primitive_type(device->wined3d_device, (enum wined3d_primitive_type)topology);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, patch_vertex_count);
     wined3d_mutex_unlock();
 }
 
@@ -1695,12 +1699,16 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_IAGetPrimitiveTopology(ID3
         D3D11_PRIMITIVE_TOPOLOGY *topology)
 {
     struct d3d_device *device = device_from_immediate_ID3D11DeviceContext(iface);
+    enum wined3d_primitive_type primitive_type;
+    unsigned int patch_vertex_count;
 
     TRACE("iface %p, topology %p.\n", iface, topology);
 
     wined3d_mutex_lock();
-    wined3d_device_get_primitive_type(device->wined3d_device, (enum wined3d_primitive_type *)topology);
+    wined3d_device_get_primitive_type(device->wined3d_device, &primitive_type, &patch_vertex_count);
     wined3d_mutex_unlock();
+
+    d3d11_primitive_topology_from_wined3d_primitive_type(primitive_type, patch_vertex_count, topology);
 }
 
 static void STDMETHODCALLTYPE d3d11_immediate_context_VSGetShaderResources(ID3D11DeviceContext *iface,
@@ -2453,7 +2461,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_ClearState(ID3D11DeviceCon
     }
     wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0);
     wined3d_device_set_vertex_declaration(device->wined3d_device, NULL);
-    wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_UNDEFINED);
+    wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_UNDEFINED, 0);
     for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
     {
         wined3d_device_set_rendertarget_view(device->wined3d_device, i, NULL, FALSE);
@@ -3941,10 +3949,10 @@ static void STDMETHODCALLTYPE d3d10_device_IASetPrimitiveTopology(ID3D10Device1
 {
     struct d3d_device *device = impl_from_ID3D10Device(iface);
 
-    TRACE("iface %p, topology %s\n", iface, debug_d3d10_primitive_topology(topology));
+    TRACE("iface %p, topology %s.\n", iface, debug_d3d10_primitive_topology(topology));
 
     wined3d_mutex_lock();
-    wined3d_device_set_primitive_type(device->wined3d_device, (enum wined3d_primitive_type)topology);
+    wined3d_device_set_primitive_type(device->wined3d_device, (enum wined3d_primitive_type)topology, 0);
     wined3d_mutex_unlock();
 }
 
@@ -4592,10 +4600,10 @@ static void STDMETHODCALLTYPE d3d10_device_IAGetPrimitiveTopology(ID3D10Device1
 {
     struct d3d_device *device = impl_from_ID3D10Device(iface);
 
-    TRACE("iface %p, topology %p\n", iface, topology);
+    TRACE("iface %p, topology %p.\n", iface, topology);
 
     wined3d_mutex_lock();
-    wined3d_device_get_primitive_type(device->wined3d_device, (enum wined3d_primitive_type *)topology);
+    wined3d_device_get_primitive_type(device->wined3d_device, (enum wined3d_primitive_type *)topology, NULL);
     wined3d_mutex_unlock();
 }
 
diff --git a/dlls/d3d11/utils.c b/dlls/d3d11/utils.c
index bd2c840..b49177c 100644
--- a/dlls/d3d11/utils.c
+++ b/dlls/d3d11/utils.c
@@ -166,6 +166,47 @@ const char *debug_float4(const float *values)
             values[0], values[1], values[2], values[3]);
 }
 
+void d3d11_primitive_topology_from_wined3d_primitive_type(enum wined3d_primitive_type primitive_type,
+        unsigned int patch_vertex_count, D3D11_PRIMITIVE_TOPOLOGY *topology)
+{
+    if (primitive_type <= WINED3D_PT_TRIANGLESTRIP_ADJ)
+    {
+        *topology = (D3D11_PRIMITIVE_TOPOLOGY)primitive_type;
+        return;
+    }
+
+    if (primitive_type == WINED3D_PT_PATCH)
+    {
+        *topology = D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + patch_vertex_count - 1;
+        return;
+    }
+
+    *topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
+}
+
+void wined3d_primitive_type_from_d3d11_primitive_topology(D3D11_PRIMITIVE_TOPOLOGY topology,
+        enum wined3d_primitive_type *type, unsigned int *patch_vertex_count)
+{
+    if (topology <= D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ)
+    {
+        *type = (enum wined3d_primitive_type)topology;
+        *patch_vertex_count = 0;
+        return;
+    }
+
+    if (D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST <= topology
+            && topology <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST)
+    {
+        *type = WINED3D_PT_PATCH;
+        *patch_vertex_count = topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1;
+        return;
+    }
+
+    WARN("Invalid primitive topology %#x.\n", topology);
+    *type = WINED3D_PT_UNDEFINED;
+    *patch_vertex_count = 0;
+}
+
 DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format)
 {
     switch(format)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index f7d05cc..8b6bd3f 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -143,7 +143,7 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
 
 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
 {
-    switch(primitive_type)
+    switch (primitive_type)
     {
         case D3DPT_POINTLIST:
             return primitive_count;
@@ -162,7 +162,7 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U
             return primitive_count + 2;
 
         default:
-            FIXME("Unhandled primitive type %#x\n", primitive_type);
+            FIXME("Unhandled primitive type %#x.\n", primitive_type);
             return 0;
     }
 }
@@ -2068,7 +2068,7 @@ static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface,
             iface, primitive_type, start_vertex, primitive_count);
 
     wined3d_mutex_lock();
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
     wined3d_mutex_unlock();
@@ -2087,7 +2087,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
             iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count);
 
     wined3d_mutex_lock();
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
     wined3d_mutex_unlock();
@@ -2174,7 +2174,7 @@ static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface,
     if (FAILED(hr))
         goto done;
 
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
     wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
 
@@ -2294,7 +2294,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface
             wined3dformat_from_d3dformat(index_format), 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx);
 
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);
 
     wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 38d821a..b4cb253 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -162,7 +162,7 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
 
 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
 {
-    switch(primitive_type)
+    switch (primitive_type)
     {
         case D3DPT_POINTLIST:
             return primitive_count;
@@ -181,7 +181,7 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U
             return primitive_count + 2;
 
         default:
-            FIXME("Unhandled primitive type %#x\n", primitive_type);
+            FIXME("Unhandled primitive type %#x.\n", primitive_type);
             return 0;
     }
 }
@@ -2481,7 +2481,7 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
         WARN("Called without a valid vertex declaration set.\n");
         return D3DERR_INVALIDCALL;
     }
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
     wined3d_mutex_unlock();
@@ -2509,7 +2509,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
         return D3DERR_INVALIDCALL;
     }
     wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
             vertex_count_from_primitive_count(primitive_type, primitive_count));
     wined3d_mutex_unlock();
@@ -2603,7 +2603,7 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
     if (FAILED(hr))
         goto done;
 
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
     wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
 
@@ -2730,7 +2730,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
             wined3dformat_from_d3dformat(index_format), 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx);
 
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);
 
     wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 6a6c19c..7d92df5 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3539,7 +3539,7 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface,
         goto done;
 
     wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf));
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vertex_count);
 
 done:
@@ -3742,7 +3742,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
     wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, WINED3DFMT_R16_UINT, 0);
 
     wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf));
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / stride);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(*indices), index_count);
 
@@ -4055,7 +4055,7 @@ static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIM
         goto done;
     wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf));
 
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / dst_stride, vertex_count);
 
 done:
@@ -4190,7 +4190,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
     wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vtx_dst_stride);
 
     wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf));
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
 
 done:
@@ -4288,7 +4288,7 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE
     }
 
     /* Now draw the primitives */
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count);
 
     wined3d_mutex_unlock();
@@ -4420,7 +4420,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
         return hr;
     }
 
-    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
 
     wined3d_mutex_unlock();
diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c
index 393c52c..ea5a55c 100644
--- a/dlls/ddraw/executebuffer.c
+++ b/dlls/ddraw/executebuffer.c
@@ -88,7 +88,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
             case D3DOP_POINT:
             {
                 const D3DPOINT *p = (D3DPOINT *)instr;
-                wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_POINTLIST);
+                wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_POINTLIST, 0);
                 wined3d_device_set_stream_source(device->wined3d_device, 0,
                         buffer->dst_vertex_buffer, 0, sizeof(D3DTLVERTEX));
                 wined3d_device_set_vertex_declaration(device->wined3d_device,
@@ -103,7 +103,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
 
             case D3DOP_LINE:
                 primitive_size = 2;
-                wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_LINELIST);
+                wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_LINELIST, 0);
                 /* Drop through. */
             case D3DOP_TRIANGLE:
             {
@@ -116,7 +116,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
 
                 if (!primitive_size)
                 {
-                    wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST);
+                    wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST, 0);
                     primitive_size = 3;
                 }
 
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index c878d24..7d89a2e 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -120,6 +120,7 @@ struct wined3d_cs_draw
 {
     enum wined3d_cs_op opcode;
     GLenum primitive_type;
+    GLint patch_vertex_count;
     int base_vertex_idx;
     unsigned int start_idx;
     unsigned int index_count;
@@ -738,6 +739,7 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
             device_invalidate_state(cs->device, STATE_POINT_ENABLE);
         state->gl_primitive_type = op->primitive_type;
     }
+    state->gl_patch_vertices = op->patch_vertex_count;
 
     draw_primitive(cs->device, state, op->base_vertex_idx, op->start_idx,
             op->index_count, op->start_instance, op->instance_count, op->indexed);
@@ -771,8 +773,9 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
             state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]);
 }
 
-void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, int base_vertex_idx, unsigned int start_idx,
-        unsigned int index_count, unsigned int start_instance, unsigned int instance_count, BOOL indexed)
+void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count,
+        int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
+        unsigned int start_instance, unsigned int instance_count, BOOL indexed)
 {
     const struct wined3d_state *state = &cs->device->state;
     struct wined3d_cs_draw *op;
@@ -781,6 +784,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, int base
     op = cs->ops->require_space(cs, sizeof(*op));
     op->opcode = WINED3D_CS_OP_DRAW;
     op->primitive_type = primitive_type;
+    op->patch_vertex_count = patch_vertex_count;
     op->base_vertex_idx = base_vertex_idx;
     op->start_idx = start_idx;
     op->index_count = index_count;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 26a1911..c06d9b1 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3641,29 +3641,34 @@ void CDECL wined3d_device_dispatch_compute(struct wined3d_device *device,
 }
 
 void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
-        enum wined3d_primitive_type primitive_type)
+        enum wined3d_primitive_type primitive_type, unsigned int patch_vertex_count)
 {
-    TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type));
+    TRACE("device %p, primitive_type %s, patch_vertex_count %u.\n",
+            device, debug_d3dprimitivetype(primitive_type), patch_vertex_count);
 
     device->state.gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
+    device->state.gl_patch_vertices = patch_vertex_count;
 }
 
 void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device,
-        enum wined3d_primitive_type *primitive_type)
+        enum wined3d_primitive_type *primitive_type, unsigned int *patch_vertex_count)
 {
-    TRACE("device %p, primitive_type %p\n", device, primitive_type);
+    TRACE("device %p, primitive_type %p, patch_vertex_count %p.\n",
+            device, primitive_type, patch_vertex_count);
 
     *primitive_type = d3d_primitive_type_from_gl(device->state.gl_primitive_type);
+    if (patch_vertex_count)
+        *patch_vertex_count = device->state.gl_patch_vertices;
 
-    TRACE("Returning %s\n", debug_d3dprimitivetype(*primitive_type));
+    TRACE("Returning %s.\n", debug_d3dprimitivetype(*primitive_type));
 }
 
 HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT start_vertex, UINT vertex_count)
 {
     TRACE("device %p, start_vertex %u, vertex_count %u.\n", device, start_vertex, vertex_count);
 
-    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, 0,
-            start_vertex, vertex_count, 0, 0, FALSE);
+    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices,
+            0, start_vertex, vertex_count, 0, 0, FALSE);
 
     return WINED3D_OK;
 }
@@ -3674,8 +3679,8 @@ void CDECL wined3d_device_draw_primitive_instanced(struct wined3d_device *device
     TRACE("device %p, start_vertex %u, vertex_count %u, start_instance %u, instance_count %u.\n",
             device, start_vertex, vertex_count, start_instance, instance_count);
 
-    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, 0,
-            start_vertex, vertex_count, start_instance, instance_count, FALSE);
+    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices,
+            0, start_vertex, vertex_count, start_instance, instance_count, FALSE);
 }
 
 HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count)
@@ -3692,7 +3697,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic
         return WINED3DERR_INVALIDCALL;
     }
 
-    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type,
+    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices,
             device->state.base_vertex_index, start_idx, index_count, 0, 0, TRUE);
 
     return WINED3D_OK;
@@ -3704,8 +3709,8 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device
     TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n",
             device, start_idx, index_count, start_instance, instance_count);
 
-    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.base_vertex_index,
-            start_idx, index_count, start_instance, instance_count, TRUE);
+    wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices,
+            device->state.base_vertex_index, start_idx, index_count, start_instance, instance_count, TRUE);
 }
 
 HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 1fde7ea..f844b25 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -628,6 +628,12 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
         }
     }
 
+    if (state->gl_primitive_type == GL_PATCHES)
+    {
+        GL_EXTCALL(glPatchParameteri(GL_PATCH_VERTICES, state->gl_patch_vertices));
+        checkGLcall("glPatchParameteri");
+    }
+
     if (context->use_immediate_mode_draw || emulation)
         draw_primitive_immediate_mode(context, state, stream_info, idx_data,
                 idx_size, base_vertex_idx, start_idx, index_count, instance_count);
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index b197052..40ce7b3 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -1117,6 +1117,7 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
 
     get_identity_matrix(&identity);
     state->gl_primitive_type = ~0u;
+    state->gl_patch_vertices = 0;
 
     /* Set some of the defaults for lights, transforms etc */
     state->transforms[WINED3D_TS_PROJECTION] = identity;
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 26af671..43ec7aa 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -81,7 +81,7 @@
 @ cdecl wined3d_device_get_npatch_mode(ptr)
 @ cdecl wined3d_device_get_pixel_shader(ptr)
 @ cdecl wined3d_device_get_predication(ptr ptr)
-@ cdecl wined3d_device_get_primitive_type(ptr ptr)
+@ cdecl wined3d_device_get_primitive_type(ptr ptr ptr)
 @ cdecl wined3d_device_get_ps_cb(ptr long)
 @ cdecl wined3d_device_get_ps_consts_b(ptr long long ptr)
 @ cdecl wined3d_device_get_ps_consts_f(ptr long long ptr)
@@ -155,7 +155,7 @@
 @ cdecl wined3d_device_set_npatch_mode(ptr float)
 @ cdecl wined3d_device_set_pixel_shader(ptr ptr)
 @ cdecl wined3d_device_set_predication(ptr ptr long)
-@ cdecl wined3d_device_set_primitive_type(ptr long)
+@ cdecl wined3d_device_set_primitive_type(ptr long long)
 @ cdecl wined3d_device_set_ps_cb(ptr long ptr)
 @ cdecl wined3d_device_set_ps_consts_b(ptr long long ptr)
 @ cdecl wined3d_device_set_ps_consts_f(ptr long long ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9592b85..bdbd9ea 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2629,6 +2629,7 @@ struct wined3d_state
     int base_vertex_index;
     int load_base_vertex_index; /* Non-indexed drawing needs 0 here, indexed needs base_vertex_index. */
     GLenum gl_primitive_type;
+    GLint gl_patch_vertices;
     struct wined3d_query *predicate;
     BOOL predicate_value;
 
@@ -3312,9 +3313,9 @@ void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs,
         struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
         unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN;
-void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, int base_vertex_idx,
-        unsigned int start_idx, unsigned int index_count, unsigned int start_instance,
-        unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count,
+        int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
+        unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 7ab0c68..f41dfed 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2245,7 +2245,7 @@ float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device
 struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device);
 struct wined3d_query * __cdecl wined3d_device_get_predication(struct wined3d_device *device, BOOL *value);
 void __cdecl wined3d_device_get_primitive_type(const struct wined3d_device *device,
-        enum wined3d_primitive_type *primitive_topology);
+        enum wined3d_primitive_type *primitive_topology, unsigned int *patch_vertex_count);
 struct wined3d_buffer * __cdecl wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx);
 HRESULT __cdecl wined3d_device_get_ps_consts_b(const struct wined3d_device *device,
         unsigned int start_idx, unsigned int count, BOOL *constants);
@@ -2361,7 +2361,7 @@ void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, stru
 void __cdecl wined3d_device_set_predication(struct wined3d_device *device,
         struct wined3d_query *predicate, BOOL value);
 void __cdecl wined3d_device_set_primitive_type(struct wined3d_device *device,
-        enum wined3d_primitive_type primitive_topology);
+        enum wined3d_primitive_type primitive_topology, unsigned int patch_vertex_count);
 void __cdecl wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer);
 HRESULT __cdecl wined3d_device_set_ps_consts_b(struct wined3d_device *device,
         unsigned int start_idx, unsigned int count, const BOOL *constants);
-- 
2.10.2




More information about the wine-patches mailing list