[PATCH 1/5] wined3d: Implement d3d10 style instance data step rates.

Henri Verbeet hverbeet at codeweavers.com
Tue Mar 24 03:38:23 CDT 2015


---
 dlls/d3d10core/inputlayout.c     |    7 ++-----
 dlls/d3d8/vertexdeclaration.c    |    2 ++
 dlls/d3d9/vertexdeclaration.c    |    2 ++
 dlls/wined3d/context.c           |   19 +++++++++++++++++--
 dlls/wined3d/state.c             |   27 +++++++++++----------------
 dlls/wined3d/utils.c             |   14 ++++++++++++++
 dlls/wined3d/vertexdeclaration.c |   20 +++++++++++++-------
 dlls/wined3d/wined3d_private.h   |    8 ++++++--
 include/wine/wined3d.h           |   10 +++++++++-
 9 files changed, 76 insertions(+), 33 deletions(-)

diff --git a/dlls/d3d10core/inputlayout.c b/dlls/d3d10core/inputlayout.c
index fa08822..770f065 100644
--- a/dlls/d3d10core/inputlayout.c
+++ b/dlls/d3d10core/inputlayout.c
@@ -72,15 +72,12 @@ static HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEME
         e->input_slot = f->InputSlot;
         e->offset = f->AlignedByteOffset;
         e->output_slot = WINED3D_OUTPUT_SLOT_UNUSED;
+        e->input_slot_class = f->InputSlotClass;
+        e->instance_data_step_rate = f->InstanceDataStepRate;
         e->method = WINED3D_DECL_METHOD_DEFAULT;
         e->usage = 0;
         e->usage_idx = 0;
 
-        if (f->InputSlotClass != D3D10_INPUT_PER_VERTEX_DATA)
-            FIXME("Ignoring input slot class (%#x)\n", f->InputSlotClass);
-        if (f->InstanceDataStepRate)
-            FIXME("Ignoring instance data step rate (%#x)\n", f->InstanceDataStepRate);
-
         for (j = 0; j < is.element_count; ++j)
         {
             if (!strcmp(element_descs[i].SemanticName, is.elements[j].semantic_name)
diff --git a/dlls/d3d8/vertexdeclaration.c b/dlls/d3d8/vertexdeclaration.c
index 2277be4..4be9127 100644
--- a/dlls/d3d8/vertexdeclaration.c
+++ b/dlls/d3d8/vertexdeclaration.c
@@ -286,6 +286,8 @@ static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3
             element->input_slot = stream;
             element->offset = offset;
             element->output_slot = reg;
+            element->input_slot_class = WINED3D_INPUT_PER_VERTEX_DATA;
+            element->instance_data_step_rate = 0;
             element->method = WINED3D_DECL_METHOD_DEFAULT;
             element->usage = wined3d_usage_lookup[reg].usage;
             element->usage_idx = wined3d_usage_lookup[reg].usage_idx;
diff --git a/dlls/d3d9/vertexdeclaration.c b/dlls/d3d9/vertexdeclaration.c
index 086ac70..cc7998d 100644
--- a/dlls/d3d9/vertexdeclaration.c
+++ b/dlls/d3d9/vertexdeclaration.c
@@ -354,6 +354,8 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elem
         (*wined3d_elements)[i].input_slot = d3d9_elements[i].Stream;
         (*wined3d_elements)[i].offset = d3d9_elements[i].Offset;
         (*wined3d_elements)[i].output_slot = WINED3D_OUTPUT_SLOT_SEMANTIC;
+        (*wined3d_elements)[i].input_slot_class = WINED3D_INPUT_PER_VERTEX_DATA;
+        (*wined3d_elements)[i].instance_data_step_rate = 0;
         (*wined3d_elements)[i].method = d3d9_elements[i].Method;
         (*wined3d_elements)[i].usage = d3d9_elements[i].Usage;
         (*wined3d_elements)[i].usage_idx = d3d9_elements[i].UsageIndex;
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 894e259..f875006 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2806,16 +2806,31 @@ void context_stream_info_from_declaration(struct wined3d_context *context,
         if (stride_used)
         {
             TRACE("Load %s array %u [usage %s, usage_idx %u, "
-                    "input_slot %u, offset %u, stride %u, format %s].\n",
+                    "input_slot %u, offset %u, stride %u, format %s, class %s, step_rate %u].\n",
                     use_vshader ? "shader": "fixed function", idx,
                     debug_d3ddeclusage(element->usage), element->usage_idx, element->input_slot,
-                    element->offset, stream->stride, debug_d3dformat(element->format->id));
+                    element->offset, stream->stride, debug_d3dformat(element->format->id),
+                    debug_d3dinput_classification(element->input_slot_class), element->instance_data_step_rate);
 
             stream_info->elements[idx].format = element->format;
             stream_info->elements[idx].data.buffer_object = 0;
             stream_info->elements[idx].data.addr = (BYTE *)NULL + stream->offset + element->offset;
             stream_info->elements[idx].stride = stream->stride;
             stream_info->elements[idx].stream_idx = element->input_slot;
+            if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
+            {
+                stream_info->elements[idx].divisor = 1;
+            }
+            else if (element->input_slot_class == WINED3D_INPUT_PER_INSTANCE_DATA)
+            {
+                stream_info->elements[idx].divisor = element->instance_data_step_rate;
+                if (!element->instance_data_step_rate)
+                    FIXME("Instance step rate 0 not implemented.\n");
+            }
+            else
+            {
+                stream_info->elements[idx].divisor = 0;
+            }
 
             if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
                     && element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index bfef4b0..4118f69 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4105,25 +4105,20 @@ static void load_numbered_arrays(struct wined3d_context *context,
 
         stream = &state->streams[stream_info->elements[i].stream_idx];
 
-        if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
-        {
-            if (!context->instance_count)
-                context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
-
-            if (!gl_info->supported[ARB_INSTANCED_ARRAYS])
-            {
-                /* Unload instanced arrays, they will be loaded using
-                 * immediate mode instead. */
-                if (context->numbered_array_mask & (1 << i))
-                    unload_numbered_array(context, i);
-                continue;
-            }
+        if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
+            context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
 
-            GL_EXTCALL(glVertexAttribDivisor(i, 1));
+        if (gl_info->supported[ARB_INSTANCED_ARRAYS])
+        {
+            GL_EXTCALL(glVertexAttribDivisor(i, stream_info->elements[i].divisor));
         }
-        else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
+        else if (stream_info->elements[i].divisor)
         {
-            GL_EXTCALL(glVertexAttribDivisor(i, 0));
+            /* Unload instanced arrays, they will be loaded using
+             * immediate mode instead. */
+            if (context->numbered_array_mask & (1 << i))
+                unload_numbered_array(context, i);
+            continue;
         }
 
         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index b28142c..a772af8 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -2603,6 +2603,20 @@ const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
     }
 }
 
+const char *debug_d3dinput_classification(enum wined3d_input_classification classification)
+{
+    switch (classification)
+    {
+#define WINED3D_TO_STR(x) case x: return #x
+        WINED3D_TO_STR(WINED3D_INPUT_PER_VERTEX_DATA);
+        WINED3D_TO_STR(WINED3D_INPUT_PER_INSTANCE_DATA);
+#undef WINED3D_TO_STR
+        default:
+            FIXME("Unrecognized input classification %#x.\n", classification);
+            return "unrecognized";
+    }
+}
+
 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
 {
     switch (resource_type)
diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
index df54bdc..9eb5907 100644
--- a/dlls/wined3d/vertexdeclaration.c
+++ b/dlls/wined3d/vertexdeclaration.c
@@ -30,13 +30,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
 
 static void dump_wined3d_vertex_element(const struct wined3d_vertex_element *element)
 {
-    TRACE("     format: %s (%#x)\n", debug_d3dformat(element->format), element->format);
-    TRACE(" input_slot: %u\n", element->input_slot);
-    TRACE("     offset: %u\n", element->offset);
-    TRACE("output_slot: %u\n", element->output_slot);
-    TRACE("     method: %s (%#x)\n", debug_d3ddeclmethod(element->method), element->method);
-    TRACE("      usage: %s (%#x)\n", debug_d3ddeclusage(element->usage), element->usage);
-    TRACE("  usage_idx: %u\n", element->usage_idx);
+    TRACE("                 format: %s (%#x)\n", debug_d3dformat(element->format), element->format);
+    TRACE("             input_slot: %u\n", element->input_slot);
+    TRACE("                 offset: %u\n", element->offset);
+    TRACE("            output_slot: %u\n", element->output_slot);
+    TRACE("       input slot class: %s\n", debug_d3dinput_classification(element->input_slot_class));
+    TRACE("instance data step rate: %u\n", element->instance_data_step_rate);
+    TRACE("                 method: %s (%#x)\n", debug_d3ddeclmethod(element->method), element->method);
+    TRACE("                  usage: %s (%#x)\n", debug_d3ddeclusage(element->usage), element->usage);
+    TRACE("              usage_idx: %u\n", element->usage_idx);
 }
 
 ULONG CDECL wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration)
@@ -197,6 +199,8 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara
         e->input_slot = elements[i].input_slot;
         e->offset = elements[i].offset;
         e->output_slot = elements[i].output_slot;
+        e->input_slot_class = elements[i].input_slot_class;
+        e->instance_data_step_rate = elements[i].instance_data_step_rate;
         e->method = elements[i].method;
         e->usage = elements[i].usage;
         e->usage_idx = elements[i].usage_idx;
@@ -297,6 +301,8 @@ static void append_decl_element(struct wined3d_fvf_convert_state *state,
     elements[idx].input_slot = 0;
     elements[idx].offset = offset;
     elements[idx].output_slot = WINED3D_OUTPUT_SLOT_SEMANTIC;
+    elements[idx].input_slot_class = WINED3D_INPUT_PER_VERTEX_DATA;
+    elements[idx].instance_data_step_rate = 0;
     elements[idx].method = WINED3D_DECL_METHOD_DEFAULT;
     elements[idx].usage = usage;
     elements[idx].usage_idx = usage_idx;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4e36969..99d7aed 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -981,7 +981,8 @@ struct wined3d_stream_info_element
     const struct wined3d_format *format;
     struct wined3d_bo_address data;
     GLsizei stride;
-    UINT stream_idx;
+    unsigned int stream_idx;
+    unsigned int divisor;
 };
 
 struct wined3d_stream_info
@@ -2424,7 +2425,9 @@ struct wined3d_vertex_declaration_element
     BOOL ffp_valid;
     unsigned int input_slot;
     unsigned int offset;
-    UINT output_slot;
+    unsigned int output_slot;
+    enum wined3d_input_classification input_slot_class;
+    unsigned int instance_data_step_rate;
     BYTE method;
     BYTE usage;
     BYTE usage_idx;
@@ -2764,6 +2767,7 @@ const char *debug_d3dusage(DWORD usage) DECLSPEC_HIDDEN;
 const char *debug_d3dusagequery(DWORD usagequery) DECLSPEC_HIDDEN;
 const char *debug_d3ddeclmethod(enum wined3d_decl_method method) DECLSPEC_HIDDEN;
 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage) DECLSPEC_HIDDEN;
+const char *debug_d3dinput_classification(enum wined3d_input_classification classification) DECLSPEC_HIDDEN;
 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN;
 const char *debug_d3drenderstate(enum wined3d_render_state state) DECLSPEC_HIDDEN;
 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index b576e1a..2348be8 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1665,12 +1665,20 @@ struct wined3d_clip_status
    DWORD clip_intersection;
 };
 
+enum wined3d_input_classification
+{
+    WINED3D_INPUT_PER_VERTEX_DATA,
+    WINED3D_INPUT_PER_INSTANCE_DATA,
+};
+
 struct wined3d_vertex_element
 {
     enum wined3d_format_id format;
     unsigned int input_slot;
     unsigned int offset;
-    UINT output_slot; /* D3D 8 & 10 */
+    unsigned int output_slot; /* D3D 8 & 10 */
+    enum wined3d_input_classification input_slot_class;
+    unsigned int instance_data_step_rate;
     BYTE method;
     BYTE usage;
     BYTE usage_idx;
-- 
1.7.10.4




More information about the wine-patches mailing list