Commit 1c810a64 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

wined3d: Check for a valid index buffer in d3d[89]_device_DrawIndexedPrimitive().

parent 997ae6dd
...@@ -2518,22 +2518,27 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface, ...@@ -2518,22 +2518,27 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
unsigned int index_count; unsigned int index_count;
int base_vertex_index; int base_vertex_index;
HRESULT hr;
TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n", TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n",
iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count); iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count);
index_count = vertex_count_from_primitive_count(primitive_type, primitive_count); index_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
wined3d_mutex_lock(); wined3d_mutex_lock();
if (!device->stateblock_state->index_buffer)
{
wined3d_mutex_unlock();
WARN("Index buffer not set, returning D3D_OK.\n");
return D3D_OK;
}
base_vertex_index = device->stateblock_state->base_vertex_index; base_vertex_index = device->stateblock_state->base_vertex_index;
d3d8_device_upload_sysmem_vertex_buffers(device, base_vertex_index + min_vertex_idx, vertex_count); d3d8_device_upload_sysmem_vertex_buffers(device, base_vertex_index + min_vertex_idx, vertex_count);
d3d8_device_upload_sysmem_index_buffer(device, start_idx, index_count); d3d8_device_upload_sysmem_index_buffer(device, start_idx, index_count);
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0);
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, index_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, index_count);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
return hr; return D3D_OK;
} }
/* The caller is responsible for wined3d locking */ /* The caller is responsible for wined3d locking */
...@@ -2752,7 +2757,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface ...@@ -2752,7 +2757,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0);
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);
wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0); wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
wined3d_stateblock_set_index_buffer(device->state, NULL, WINED3DFMT_UNKNOWN); wined3d_stateblock_set_index_buffer(device->state, NULL, WINED3DFMT_UNKNOWN);
......
...@@ -10176,7 +10176,7 @@ static void test_draw_primitive(void) ...@@ -10176,7 +10176,7 @@ static void test_draw_primitive(void)
hr = IDirect3DDevice8_SetIndices(device, NULL, 0); hr = IDirect3DDevice8_SetIndices(device, NULL, 0);
ok(SUCCEEDED(hr), "SetIndices failed, hr %#x.\n", hr); ok(SUCCEEDED(hr), "SetIndices failed, hr %#x.\n", hr);
hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 4, 0, 2); hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 4, 0, 2);
todo_wine ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed, hr %#x.\n", hr); ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* Valid index buffer, NULL stream source. */ /* Valid index buffer, NULL stream source. */
hr = IDirect3DDevice8_SetIndices(device, index_buffer, 1); hr = IDirect3DDevice8_SetIndices(device, index_buffer, 1);
......
...@@ -3049,7 +3049,6 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface ...@@ -3049,7 +3049,6 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
{ {
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
unsigned int index_count; unsigned int index_count;
HRESULT hr;
TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u, " TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u, "
"vertex_count %u, start_idx %u, primitive_count %u.\n", "vertex_count %u, start_idx %u, primitive_count %u.\n",
...@@ -3063,6 +3062,12 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface ...@@ -3063,6 +3062,12 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
WARN("Called without a valid vertex declaration set.\n"); WARN("Called without a valid vertex declaration set.\n");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
if (!device->stateblock_state->index_buffer)
{
wined3d_mutex_unlock();
WARN("Called without a valid index buffer set.\n");
return D3DERR_INVALIDCALL;
}
index_count = vertex_count_from_primitive_count(primitive_type, primitive_count); index_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
d3d9_device_upload_sysmem_vertex_buffers(device, base_vertex_idx, min_vertex_idx, vertex_count); d3d9_device_upload_sysmem_vertex_buffers(device, base_vertex_idx, min_vertex_idx, vertex_count);
d3d9_device_upload_sysmem_index_buffer(device, start_idx, index_count); d3d9_device_upload_sysmem_index_buffer(device, start_idx, index_count);
...@@ -3070,12 +3075,11 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface ...@@ -3070,12 +3075,11 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
wined3d_stateblock_set_base_vertex_index(device->state, base_vertex_idx); wined3d_stateblock_set_base_vertex_index(device->state, base_vertex_idx);
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0);
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, index_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, index_count);
if (SUCCEEDED(hr)) d3d9_rts_flag_auto_gen_mipmap(device);
d3d9_rts_flag_auto_gen_mipmap(device);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
return hr; return D3D_OK;
} }
/* The caller is responsible for wined3d locking */ /* The caller is responsible for wined3d locking */
...@@ -3322,13 +3326,12 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa ...@@ -3322,13 +3326,12 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_d3d(primitive_type), 0);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);
wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0); wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
wined3d_stateblock_set_index_buffer(device->state, NULL, WINED3DFMT_UNKNOWN); wined3d_stateblock_set_index_buffer(device->state, NULL, WINED3DFMT_UNKNOWN);
if (SUCCEEDED(hr)) d3d9_rts_flag_auto_gen_mipmap(device);
d3d9_rts_flag_auto_gen_mipmap(device);
done: done:
wined3d_mutex_unlock(); wined3d_mutex_unlock();
......
...@@ -3736,7 +3736,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, ...@@ -3736,7 +3736,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
wined3d_stateblock_set_base_vertex_index(device->state, vb_pos / stride); wined3d_stateblock_set_base_vertex_index(device->state, vb_pos / stride);
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
d3d_device_sync_surfaces(device); d3d_device_sync_surfaces(device);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(*indices), index_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(*indices), index_count);
done: done:
wined3d_mutex_unlock(); wined3d_mutex_unlock();
...@@ -4200,7 +4200,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, ...@@ -4200,7 +4200,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
d3d_device_sync_surfaces(device); d3d_device_sync_surfaces(device);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
done: done:
wined3d_mutex_unlock(); wined3d_mutex_unlock();
...@@ -4478,7 +4478,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, ...@@ -4478,7 +4478,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
wined3d_device_apply_stateblock(device->wined3d_device, device->state); wined3d_device_apply_stateblock(device->wined3d_device, device->state);
d3d_device_sync_surfaces(device); d3d_device_sync_surfaces(device);
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count); wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
......
...@@ -4480,26 +4480,14 @@ void CDECL wined3d_device_draw_primitive_instanced_indirect(struct wined3d_devic ...@@ -4480,26 +4480,14 @@ void CDECL wined3d_device_draw_primitive_instanced_indirect(struct wined3d_devic
state->patch_vertex_count, buffer, offset, false); state->patch_vertex_count, buffer, offset, false);
} }
HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) void CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count)
{ {
struct wined3d_state *state = device->cs->c.state; struct wined3d_state *state = device->cs->c.state;
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
if (!state->index_buffer)
{
/* D3D9 returns D3DERR_INVALIDCALL when DrawIndexedPrimitive is called
* without an index buffer set. (The first time at least...)
* D3D8 simply dies, but I doubt it can do much harm to return
* D3DERR_INVALIDCALL there as well. */
WARN("Called without a valid index buffer set, returning WINED3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
wined3d_device_context_emit_draw(&device->cs->c, state->primitive_type, state->patch_vertex_count, wined3d_device_context_emit_draw(&device->cs->c, state->primitive_type, state->patch_vertex_count,
state->base_vertex_index, start_idx, index_count, 0, 0, true); state->base_vertex_index, start_idx, index_count, 0, 0, true);
return WINED3D_OK;
} }
void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device, void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
......
...@@ -2373,7 +2373,7 @@ void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device, ...@@ -2373,7 +2373,7 @@ void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device,
unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z); unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z);
void __cdecl wined3d_device_dispatch_compute_indirect(struct wined3d_device *device, void __cdecl wined3d_device_dispatch_compute_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset); struct wined3d_buffer *buffer, unsigned int offset);
HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count); void __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, void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count); UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count);
void __cdecl wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device, void __cdecl wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device,
......
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