diff --git a/dlls/d3d10core/inputlayout.c b/dlls/d3d10core/inputlayout.c index fa088224356..770f065a54d 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 2277be4b26f..4be91279f0d 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 086ac70b9b2..cc7998ddcdc 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 894e2599d20..f87500676ea 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 bfef4b0ed21..4118f69b97b 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 ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count) + context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; + + if (gl_info->supported[ARB_INSTANCED_ARRAYS]) { - 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; - } - - GL_EXTCALL(glVertexAttribDivisor(i, 1)); + 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 b28142c7a3b..a772af87144 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 df54bdc0b56..9eb59076b01 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 4e36969b412..99d7aed25be 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 b576e1abba0..2348be87452 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;