Commit 7f62678c authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

d3d10core: Implement d3d10_device_DrawIndexedInstanced().

parent eefe6346
...@@ -236,10 +236,16 @@ static void STDMETHODCALLTYPE d3d10_device_DrawIndexedInstanced(ID3D10Device *if ...@@ -236,10 +236,16 @@ static void STDMETHODCALLTYPE d3d10_device_DrawIndexedInstanced(ID3D10Device *if
UINT instance_index_count, UINT instance_count, UINT start_index_location, UINT instance_index_count, UINT instance_count, UINT start_index_location,
INT base_vertex_location, UINT start_instance_location) INT base_vertex_location, UINT start_instance_location)
{ {
FIXME("iface %p, instance_index_count %u, instance_count %u, start_index_location %u,\n" struct d3d10_device *device = impl_from_ID3D10Device(iface);
"\tbase_vertex_location %d, start_instance_location %u stub!\n",
TRACE("iface %p, instance_index_count %u, instance_count %u, start_index_location %u,\n"
"\tbase_vertex_location %d, start_instance_location %u.\n",
iface, instance_index_count, instance_count, start_index_location, iface, instance_index_count, instance_count, start_index_location,
base_vertex_location, start_instance_location); base_vertex_location, start_instance_location);
wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location);
wined3d_device_draw_indexed_primitive_instanced(device->wined3d_device, start_index_location,
instance_index_count, start_instance_location, instance_count);
} }
static void STDMETHODCALLTYPE d3d10_device_DrawInstanced(ID3D10Device *iface, static void STDMETHODCALLTYPE d3d10_device_DrawInstanced(ID3D10Device *iface,
......
...@@ -3868,7 +3868,7 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT ...@@ -3868,7 +3868,7 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT
/* Account for the loading offset due to index buffers. Instead of /* Account for the loading offset due to index buffers. Instead of
* reloading all sources correct it with the startvertex parameter. */ * reloading all sources correct it with the startvertex parameter. */
drawPrimitive(device, vertex_count, start_vertex, FALSE, NULL); draw_primitive(device, start_vertex, vertex_count, 0, 0, FALSE, NULL);
return WINED3D_OK; return WINED3D_OK;
} }
...@@ -3907,11 +3907,19 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic ...@@ -3907,11 +3907,19 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic
device_invalidate_state(device, STATE_BASEVERTEXINDEX); device_invalidate_state(device, STATE_BASEVERTEXINDEX);
} }
drawPrimitive(device, index_count, start_idx, TRUE, NULL); draw_primitive(device, start_idx, index_count, 0, 0, TRUE, NULL);
return WINED3D_OK; return WINED3D_OK;
} }
void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count)
{
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
draw_primitive(device, start_idx, index_count, start_instance, instance_count, TRUE, NULL);
}
HRESULT CDECL wined3d_device_draw_primitive_up(struct wined3d_device *device, UINT vertex_count, HRESULT CDECL wined3d_device_draw_primitive_up(struct wined3d_device *device, UINT vertex_count,
const void *stream_data, UINT stream_stride) const void *stream_data, UINT stream_stride)
{ {
...@@ -3945,7 +3953,7 @@ HRESULT CDECL wined3d_device_draw_primitive_up(struct wined3d_device *device, UI ...@@ -3945,7 +3953,7 @@ HRESULT CDECL wined3d_device_draw_primitive_up(struct wined3d_device *device, UI
/* TODO: Only mark dirty if drawing from a different UP address */ /* TODO: Only mark dirty if drawing from a different UP address */
device_invalidate_state(device, STATE_STREAMSRC); device_invalidate_state(device, STATE_STREAMSRC);
drawPrimitive(device, vertex_count, 0, FALSE, NULL); draw_primitive(device, 0, vertex_count, 0, 0, FALSE, NULL);
/* MSDN specifies stream zero settings must be set to NULL */ /* MSDN specifies stream zero settings must be set to NULL */
stream->buffer = NULL; stream->buffer = NULL;
...@@ -3983,7 +3991,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive_up(struct wined3d_device *de ...@@ -3983,7 +3991,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive_up(struct wined3d_device *de
device->stateBlock->state.user_stream = TRUE; device->stateBlock->state.user_stream = TRUE;
device->stateBlock->state.index_format = index_data_format_id; device->stateBlock->state.index_format = index_data_format_id;
/* Set to 0 as per msdn. Do it now due to the stream source loading during drawPrimitive */ /* Set to 0 as per MSDN. Do it now due to the stream source loading during draw_primitive(). */
device->stateBlock->state.base_vertex_index = 0; device->stateBlock->state.base_vertex_index = 0;
if (device->stateBlock->state.load_base_vertex_index) if (device->stateBlock->state.load_base_vertex_index)
{ {
...@@ -3994,7 +4002,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive_up(struct wined3d_device *de ...@@ -3994,7 +4002,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive_up(struct wined3d_device *de
device_invalidate_state(device, STATE_STREAMSRC); device_invalidate_state(device, STATE_STREAMSRC);
device_invalidate_state(device, STATE_INDEXBUFFER); device_invalidate_state(device, STATE_INDEXBUFFER);
drawPrimitive(device, index_count, 0, TRUE, index_data); draw_primitive(device, 0, index_count, 0, 0, TRUE, index_data);
/* MSDN specifies stream zero settings and index buffer must be set to NULL */ /* MSDN specifies stream zero settings and index buffer must be set to NULL */
stream->buffer = NULL; stream->buffer = NULL;
...@@ -4024,7 +4032,7 @@ HRESULT CDECL wined3d_device_draw_primitive_strided(struct wined3d_device *devic ...@@ -4024,7 +4032,7 @@ HRESULT CDECL wined3d_device_draw_primitive_strided(struct wined3d_device *devic
device->stateBlock->state.base_vertex_index = 0; device->stateBlock->state.base_vertex_index = 0;
device->up_strided = strided_data; device->up_strided = strided_data;
drawPrimitive(device, vertex_count, 0, FALSE, NULL); draw_primitive(device, 0, vertex_count, 0, 0, FALSE, NULL);
device->up_strided = NULL; device->up_strided = NULL;
/* Invalidate the states again to make sure the values from the stateblock /* Invalidate the states again to make sure the values from the stateblock
...@@ -4056,7 +4064,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive_strided(struct wined3d_devic ...@@ -4056,7 +4064,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive_strided(struct wined3d_devic
device->stateBlock->state.user_stream = TRUE; device->stateBlock->state.user_stream = TRUE;
device->stateBlock->state.base_vertex_index = 0; device->stateBlock->state.base_vertex_index = 0;
device->up_strided = strided_data; device->up_strided = strided_data;
drawPrimitive(device, index_count, 0, TRUE, index_data); draw_primitive(device, 0, index_count, 0, 0, TRUE, index_data);
device->up_strided = NULL; device->up_strided = NULL;
device->stateBlock->state.index_format = prev_idx_format; device->stateBlock->state.index_format = prev_idx_format;
......
...@@ -97,6 +97,7 @@ static const struct wined3d_extension_map gl_extension_map[] = ...@@ -97,6 +97,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
{"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE }, {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE },
{"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS }, {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS },
{"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX }, {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX },
{"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED },
{"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM },
{"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER }, {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER },
{"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT },
......
...@@ -36,12 +36,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); ...@@ -36,12 +36,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
/* GL locking is done by the caller */ /* GL locking is done by the caller */
static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size,
const void *idx_data, UINT start_idx, INT base_vertex_index) const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count)
{ {
if (idx_size) if (idx_size)
{ {
GLenum idxtype = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; GLenum idxtype = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) if (instance_count)
{
if (!gl_info->supported[ARB_DRAW_INSTANCED])
{
FIXME("Instanced drawing not supported.\n");
}
else
{
if (start_instance)
FIXME("Start instance (%u) not supported.\n", start_instance);
GL_EXTCALL(glDrawElementsInstancedBaseVertex(primitive_type, count, idxtype,
(const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_index));
checkGLcall("glDrawElementsInstancedBaseVertex");
}
}
else if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
{ {
GL_EXTCALL(glDrawElementsBaseVertex(primitive_type, count, idxtype, GL_EXTCALL(glDrawElementsBaseVertex(primitive_type, count, idxtype,
(const char *)idx_data + (idx_size * start_idx), base_vertex_index)); (const char *)idx_data + (idx_size * start_idx), base_vertex_index));
...@@ -577,7 +592,8 @@ static void remove_vbos(const struct wined3d_gl_info *gl_info, ...@@ -577,7 +592,8 @@ static void remove_vbos(const struct wined3d_gl_info *gl_info,
} }
/* Routine common to the draw primitive and draw indexed primitive routines */ /* Routine common to the draw primitive and draw indexed primitive routines */
void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartIdx, BOOL indexed, const void *idxData) void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count,
UINT start_instance, UINT instance_count, BOOL indexed, const void *idx_data)
{ {
const struct wined3d_state *state = &device->stateBlock->state; const struct wined3d_state *state = &device->stateBlock->state;
struct wined3d_event_query *ib_query = NULL; struct wined3d_event_query *ib_query = NULL;
...@@ -682,11 +698,11 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId ...@@ -682,11 +698,11 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId
{ {
struct wined3d_buffer *index_buffer = state->index_buffer; struct wined3d_buffer *index_buffer = state->index_buffer;
if (!index_buffer->buffer_object || !stream_info->all_vbo) if (!index_buffer->buffer_object || !stream_info->all_vbo)
idxData = index_buffer->resource.allocatedMemory; idx_data = index_buffer->resource.allocatedMemory;
else else
{ {
ib_query = index_buffer->query; ib_query = index_buffer->query;
idxData = NULL; idx_data = NULL;
} }
} }
...@@ -744,24 +760,25 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId ...@@ -744,24 +760,25 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId
} else { } else {
TRACE("Using immediate mode with vertex shaders for half float emulation\n"); TRACE("Using immediate mode with vertex shaders for half float emulation\n");
} }
drawStridedSlowVs(gl_info, state, stream_info, drawStridedSlowVs(gl_info, state, stream_info, index_count,
index_count, glPrimType, idxData, idx_size, StartIdx); glPrimType, idx_data, idx_size, start_idx);
} }
else else
{ {
drawStridedSlow(device, context, stream_info, index_count, drawStridedSlow(device, context, stream_info, index_count,
glPrimType, idxData, idx_size, StartIdx); glPrimType, idx_data, idx_size, start_idx);
} }
} }
else if (device->instancedDraw) else if (device->instancedDraw)
{ {
/* Instancing emulation with mixing immediate mode and arrays */ /* Instancing emulation with mixing immediate mode and arrays */
drawStridedInstanced(gl_info, state, stream_info, drawStridedInstanced(gl_info, state, stream_info, index_count,
index_count, glPrimType, idxData, idx_size, StartIdx, base_vertex_index); glPrimType, idx_data, idx_size, start_idx, base_vertex_index);
} }
else else
{ {
drawStridedFast(gl_info, glPrimType, index_count, idx_size, idxData, StartIdx, base_vertex_index); drawStridedFast(gl_info, glPrimType, index_count, idx_size, idx_data,
start_idx, base_vertex_index, start_instance, instance_count);
} }
} }
......
...@@ -6195,7 +6195,8 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s ...@@ -6195,7 +6195,8 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s
UINT shader_model; UINT shader_model;
if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING] if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING]
&& gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)) && gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)
&& gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && gl_info->supported[ARB_DRAW_INSTANCED])
shader_model = 4; shader_model = 4;
/* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3 /* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
* texldd and texldl instructions. */ * texldd and texldl instructions. */
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
@ cdecl wined3d_device_decref(ptr) @ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_delete_patch(ptr long) @ cdecl wined3d_device_delete_patch(ptr long)
@ cdecl wined3d_device_draw_indexed_primitive(ptr long long) @ cdecl wined3d_device_draw_indexed_primitive(ptr long long)
@ cdecl wined3d_device_draw_indexed_primitive_instanced(ptr long long long long)
@ cdecl wined3d_device_draw_indexed_primitive_strided(ptr long ptr long ptr long) @ cdecl wined3d_device_draw_indexed_primitive_strided(ptr long ptr long ptr long)
@ cdecl wined3d_device_draw_indexed_primitive_up(ptr long ptr long ptr long) @ cdecl wined3d_device_draw_indexed_primitive_up(ptr long ptr long ptr long)
@ cdecl wined3d_device_draw_primitive(ptr long long) @ cdecl wined3d_device_draw_primitive(ptr long long)
......
...@@ -49,6 +49,7 @@ enum wined3d_gl_extension ...@@ -49,6 +49,7 @@ enum wined3d_gl_extension
ARB_DEPTH_TEXTURE, ARB_DEPTH_TEXTURE,
ARB_DRAW_BUFFERS, ARB_DRAW_BUFFERS,
ARB_DRAW_ELEMENTS_BASE_VERTEX, ARB_DRAW_ELEMENTS_BASE_VERTEX,
ARB_DRAW_INSTANCED,
ARB_FRAGMENT_PROGRAM, ARB_FRAGMENT_PROGRAM,
ARB_FRAGMENT_SHADER, ARB_FRAGMENT_SHADER,
ARB_FRAMEBUFFER_OBJECT, ARB_FRAMEBUFFER_OBJECT,
...@@ -184,6 +185,9 @@ enum wined3d_gl_extension ...@@ -184,6 +185,9 @@ enum wined3d_gl_extension
USE_GL_FUNC(glDrawElementsInstancedBaseVertex) \ USE_GL_FUNC(glDrawElementsInstancedBaseVertex) \
USE_GL_FUNC(glDrawRangeElementsBaseVertex) \ USE_GL_FUNC(glDrawRangeElementsBaseVertex) \
USE_GL_FUNC(glMultiDrawElementsBaseVertex) \ USE_GL_FUNC(glMultiDrawElementsBaseVertex) \
/* GL_ARB_draw_instanced */ \
USE_GL_FUNC(glDrawArraysInstancedARB) \
USE_GL_FUNC(glDrawElementsInstancedARB) \
/* GL_ARB_framebuffer_object */ \ /* GL_ARB_framebuffer_object */ \
USE_GL_FUNC(glBindFramebuffer) \ USE_GL_FUNC(glBindFramebuffer) \
USE_GL_FUNC(glBindRenderbuffer) \ USE_GL_FUNC(glBindRenderbuffer) \
......
...@@ -944,13 +944,8 @@ struct wined3d_stream_info ...@@ -944,13 +944,8 @@ struct wined3d_stream_info
WORD use_map; /* MAX_ATTRIBS, 16 */ WORD use_map; /* MAX_ATTRIBS, 16 */
}; };
/***************************************************************************** void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count,
* Prototypes UINT start_instance, UINT instance_count, BOOL indexed, const void *idx_data) DECLSPEC_HIDDEN;
*/
/* Routine common to the draw primitive and draw indexed primitive routines */
void drawPrimitive(struct wined3d_device *device, UINT index_count,
UINT start_idx, BOOL indexed, const void *idxData) DECLSPEC_HIDDEN;
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
typedef void (WINE_GLAPI *glAttribFunc)(const void *data); typedef void (WINE_GLAPI *glAttribFunc)(const void *data);
......
...@@ -2088,6 +2088,8 @@ HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, ...@@ -2088,6 +2088,8 @@ HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
ULONG __cdecl wined3d_device_decref(struct wined3d_device *device); ULONG __cdecl wined3d_device_decref(struct wined3d_device *device);
HRESULT __cdecl wined3d_device_delete_patch(struct wined3d_device *device, UINT handle); HRESULT __cdecl wined3d_device_delete_patch(struct wined3d_device *device, UINT handle);
HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count); HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count);
void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count);
HRESULT __cdecl wined3d_device_draw_indexed_primitive_strided(struct wined3d_device *device, UINT index_count, HRESULT __cdecl wined3d_device_draw_indexed_primitive_strided(struct wined3d_device *device, UINT index_count,
const struct wined3d_strided_data *strided_data, UINT vertex_count, const void *index_data, const struct wined3d_strided_data *strided_data, UINT vertex_count, const void *index_data,
enum wined3d_format_id index_data_format_id); enum wined3d_format_id index_data_format_id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment