[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