[PATCH 5/5] d3d10core: Implement d3d10_device_DrawIndexedInstanced().
Henri Verbeet
hverbeet at codeweavers.com
Mon Nov 26 15:52:41 CST 2012
---
dlls/d3d10core/device.c | 10 ++++++++--
dlls/wined3d/device.c | 22 +++++++++++++++-------
dlls/wined3d/directx.c | 1 +
dlls/wined3d/drawprim.c | 39 ++++++++++++++++++++++++++++-----------
dlls/wined3d/glsl_shader.c | 3 ++-
dlls/wined3d/wined3d.spec | 1 +
dlls/wined3d/wined3d_gl.h | 4 ++++
dlls/wined3d/wined3d_private.h | 9 ++-------
include/wine/wined3d.h | 2 ++
9 files changed, 63 insertions(+), 28 deletions(-)
diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c
index 3ac02a0..dff8fd3 100644
--- a/dlls/d3d10core/device.c
+++ b/dlls/d3d10core/device.c
@@ -236,10 +236,16 @@ static void STDMETHODCALLTYPE d3d10_device_DrawIndexedInstanced(ID3D10Device *if
UINT instance_index_count, UINT instance_count, UINT start_index_location,
INT base_vertex_location, UINT start_instance_location)
{
- FIXME("iface %p, instance_index_count %u, instance_count %u, start_index_location %u,\n"
- "\tbase_vertex_location %d, start_instance_location %u stub!\n",
+ struct d3d10_device *device = impl_from_ID3D10Device(iface);
+
+ 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,
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,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 20c535c..713e959 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -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
* 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;
}
@@ -3907,11 +3907,19 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic
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;
}
+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,
const void *stream_data, UINT stream_stride)
{
@@ -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 */
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 */
stream->buffer = NULL;
@@ -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.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;
if (device->stateBlock->state.load_base_vertex_index)
{
@@ -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_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 */
stream->buffer = NULL;
@@ -4024,7 +4032,7 @@ HRESULT CDECL wined3d_device_draw_primitive_strided(struct wined3d_device *devic
device->stateBlock->state.base_vertex_index = 0;
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;
/* 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
device->stateBlock->state.user_stream = TRUE;
device->stateBlock->state.base_vertex_index = 0;
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->stateBlock->state.index_format = prev_idx_format;
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 58dc0da..ccfcf4b 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -97,6 +97,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
{"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE },
{"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS },
{"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_shader", ARB_FRAGMENT_SHADER },
{"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT },
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 2aea660..02d0144 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -36,12 +36,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
/* 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,
- 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)
{
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,
(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,
}
/* 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;
struct wined3d_event_query *ib_query = NULL;
@@ -682,11 +698,11 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId
{
struct wined3d_buffer *index_buffer = state->index_buffer;
if (!index_buffer->buffer_object || !stream_info->all_vbo)
- idxData = index_buffer->resource.allocatedMemory;
+ idx_data = index_buffer->resource.allocatedMemory;
else
{
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
} else {
TRACE("Using immediate mode with vertex shaders for half float emulation\n");
}
- drawStridedSlowVs(gl_info, state, stream_info,
- index_count, glPrimType, idxData, idx_size, StartIdx);
+ drawStridedSlowVs(gl_info, state, stream_info, index_count,
+ glPrimType, idx_data, idx_size, start_idx);
}
else
{
drawStridedSlow(device, context, stream_info, index_count,
- glPrimType, idxData, idx_size, StartIdx);
+ glPrimType, idx_data, idx_size, start_idx);
}
}
else if (device->instancedDraw)
{
/* Instancing emulation with mixing immediate mode and arrays */
- drawStridedInstanced(gl_info, state, stream_info,
- index_count, glPrimType, idxData, idx_size, StartIdx, base_vertex_index);
+ drawStridedInstanced(gl_info, state, stream_info, index_count,
+ glPrimType, idx_data, idx_size, start_idx, base_vertex_index);
}
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);
}
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 85c8437..9490552 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -6195,7 +6195,8 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s
UINT shader_model;
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;
/* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
* texldd and texldl instructions. */
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 549a444..d664c76 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -43,6 +43,7 @@
@ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_delete_patch(ptr 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_up(ptr long ptr long ptr long)
@ cdecl wined3d_device_draw_primitive(ptr long long)
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 4575400..fc0a68c 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -49,6 +49,7 @@ enum wined3d_gl_extension
ARB_DEPTH_TEXTURE,
ARB_DRAW_BUFFERS,
ARB_DRAW_ELEMENTS_BASE_VERTEX,
+ ARB_DRAW_INSTANCED,
ARB_FRAGMENT_PROGRAM,
ARB_FRAGMENT_SHADER,
ARB_FRAMEBUFFER_OBJECT,
@@ -184,6 +185,9 @@ enum wined3d_gl_extension
USE_GL_FUNC(glDrawElementsInstancedBaseVertex) \
USE_GL_FUNC(glDrawRangeElementsBaseVertex) \
USE_GL_FUNC(glMultiDrawElementsBaseVertex) \
+ /* GL_ARB_draw_instanced */ \
+ USE_GL_FUNC(glDrawArraysInstancedARB) \
+ USE_GL_FUNC(glDrawElementsInstancedARB) \
/* GL_ARB_framebuffer_object */ \
USE_GL_FUNC(glBindFramebuffer) \
USE_GL_FUNC(glBindRenderbuffer) \
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ea3010f..fb1a6be 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -944,13 +944,8 @@ struct wined3d_stream_info
WORD use_map; /* MAX_ATTRIBS, 16 */
};
-/*****************************************************************************
- * Prototypes
- */
-
-/* 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;
+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) DECLSPEC_HIDDEN;
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
typedef void (WINE_GLAPI *glAttribFunc)(const void *data);
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index dd4d29b..b540991 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2088,6 +2088,8 @@ HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
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_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,
const struct wined3d_strided_data *strided_data, UINT vertex_count, const void *index_data,
enum wined3d_format_id index_data_format_id);
--
1.7.8.6
More information about the wine-patches
mailing list