d3d10core: Implement d3d10_device_DrawIndexedInstanced().

This commit is contained in:
Henri Verbeet 2012-11-26 22:52:41 +01:00 committed by Alexandre Julliard
parent eefe6346a9
commit 7f62678c16
9 changed files with 63 additions and 28 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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 },

View File

@ -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);
}
}

View File

@ -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. */

View File

@ -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)

View File

@ -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) \

View File

@ -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);

View File

@ -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);