wined3d: Store and use stream offset in state block.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=21161 Signed-off-by: Paul Gofman <gofmanp@gmail.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
870f99eced
commit
57653b9527
|
@ -67,6 +67,7 @@ struct state_test
|
|||
/* Apparently recorded stateblocks record and apply vertex declarations,
|
||||
* but don't capture them */
|
||||
#define SB_QUIRK_RECORDED_VDECL_CAPTURE 0x00000001
|
||||
#define SB_QUIRK_STREAM_OFFSET_NOT_UPDATED 0x00000002
|
||||
|
||||
struct event_data
|
||||
{
|
||||
|
@ -135,6 +136,7 @@ static void execute_test_chain(IDirect3DDevice9 *device, struct state_test *test
|
|||
{
|
||||
const void *data;
|
||||
|
||||
trace("event %u.\n", j);
|
||||
/* Execute the next event handler (if available). */
|
||||
if (event[j].event_fn)
|
||||
{
|
||||
|
@ -349,16 +351,17 @@ static void execute_test_chain_all(IDirect3DDevice9 *device, struct state_test *
|
|||
struct event capture_reapply_stateblock_events[] =
|
||||
{
|
||||
{begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
|
||||
{end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
|
||||
{end_stateblock, SB_DATA_NONE, SB_DATA_DEFAULT},
|
||||
{capture_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
|
||||
{apply_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE, SB_QUIRK_RECORDED_VDECL_CAPTURE},
|
||||
{capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
|
||||
{apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT, SB_QUIRK_RECORDED_VDECL_CAPTURE},
|
||||
};
|
||||
|
||||
struct event create_stateblock_capture_apply_all_events[] =
|
||||
{
|
||||
{create_stateblock_all, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
|
||||
{capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
|
||||
{apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
|
||||
{apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE, SB_QUIRK_STREAM_OFFSET_NOT_UPDATED},
|
||||
};
|
||||
|
||||
struct event create_stateblock_apply_all_events[] =
|
||||
|
@ -421,43 +424,52 @@ static void execute_test_chain_all(IDirect3DDevice9 *device, struct state_test *
|
|||
}
|
||||
|
||||
trace("Running initial read state tests\n");
|
||||
execute_test_chain(device, test, ntests, read_events, 1, NULL);
|
||||
execute_test_chain(device, test, ntests, read_events, ARRAY_SIZE(read_events), NULL);
|
||||
|
||||
trace("Running write-read state tests\n");
|
||||
execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
|
||||
execute_test_chain(device, test, ntests, write_read_events, ARRAY_SIZE(write_read_events), NULL);
|
||||
|
||||
trace("Running stateblock abort state tests\n");
|
||||
execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, abort_stateblock_events, ARRAY_SIZE(abort_stateblock_events), &arg);
|
||||
|
||||
trace("Running stateblock apply state tests\n");
|
||||
execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, apply_stateblock_events, ARRAY_SIZE(apply_stateblock_events), &arg);
|
||||
|
||||
trace("Running stateblock capture/reapply state tests\n");
|
||||
execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
|
||||
execute_test_chain(device, test, ntests, capture_reapply_stateblock_events,
|
||||
ARRAY_SIZE(capture_reapply_stateblock_events), &arg);
|
||||
|
||||
trace("Running create stateblock capture/apply all state tests\n");
|
||||
execute_test_chain(device, test, ntests, create_stateblock_capture_apply_all_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, create_stateblock_capture_apply_all_events,
|
||||
ARRAY_SIZE(create_stateblock_capture_apply_all_events), &arg);
|
||||
|
||||
trace("Running create stateblock apply state all tests\n");
|
||||
execute_test_chain(device, test, ntests, create_stateblock_apply_all_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, create_stateblock_apply_all_events,
|
||||
ARRAY_SIZE(create_stateblock_apply_all_events), &arg);
|
||||
|
||||
trace("Running create stateblock capture/apply vertex state tests\n");
|
||||
execute_test_chain(device, test, ntests, create_stateblock_capture_apply_vertex_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, create_stateblock_capture_apply_vertex_events,
|
||||
ARRAY_SIZE(create_stateblock_capture_apply_vertex_events), &arg);
|
||||
|
||||
trace("Running create stateblock apply vertex state tests\n");
|
||||
execute_test_chain(device, test, ntests, create_stateblock_apply_vertex_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, create_stateblock_apply_vertex_events,
|
||||
ARRAY_SIZE(create_stateblock_apply_vertex_events), &arg);
|
||||
|
||||
trace("Running create stateblock capture/apply pixel state tests\n");
|
||||
execute_test_chain(device, test, ntests, create_stateblock_capture_apply_pixel_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, create_stateblock_capture_apply_pixel_events,
|
||||
ARRAY_SIZE(create_stateblock_capture_apply_pixel_events), &arg);
|
||||
|
||||
trace("Running create stateblock apply pixel state tests\n");
|
||||
execute_test_chain(device, test, ntests, create_stateblock_apply_pixel_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, create_stateblock_apply_pixel_events,
|
||||
ARRAY_SIZE(create_stateblock_apply_pixel_events), &arg);
|
||||
|
||||
trace("Running rendertarget switch state tests\n");
|
||||
execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
|
||||
execute_test_chain(device, test, ntests, rendertarget_switch_events,
|
||||
ARRAY_SIZE(rendertarget_switch_events), &arg);
|
||||
|
||||
trace("Running stateblock apply over rendertarget switch interrupt tests\n");
|
||||
execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
|
||||
execute_test_chain(device, test, ntests, rendertarget_stateblock_events,
|
||||
ARRAY_SIZE(rendertarget_stateblock_events), &arg);
|
||||
|
||||
/* Cleanup resources */
|
||||
for (i = 0; i < ntests; ++i)
|
||||
|
@ -649,6 +661,7 @@ static const struct light_data light_poison_data =
|
|||
0x1337c0de,
|
||||
};
|
||||
|
||||
|
||||
static const struct light_data light_default_data =
|
||||
{
|
||||
{
|
||||
|
@ -1666,6 +1679,7 @@ struct resource_test_data
|
|||
IDirect3DPixelShader9 *ps;
|
||||
IDirect3DIndexBuffer9 *ib;
|
||||
IDirect3DVertexBuffer9 **vb;
|
||||
unsigned int stream_offset, stream_stride;
|
||||
IDirect3DTexture9 **tex;
|
||||
};
|
||||
|
||||
|
@ -1682,6 +1696,7 @@ static void resource_apply_data(IDirect3DDevice9 *device, const struct state_tes
|
|||
{
|
||||
const struct resource_test_arg *arg = test->test_arg;
|
||||
const struct resource_test_data *d = data;
|
||||
IDirect3DVertexBuffer9 *temp_vb = NULL;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1699,10 +1714,26 @@ static void resource_apply_data(IDirect3DDevice9 *device, const struct state_tes
|
|||
|
||||
for (i = 0; i < arg->stream_count; ++i)
|
||||
{
|
||||
hr = IDirect3DDevice9_SetStreamSource(device, i, d->vb[i], 0, 64);
|
||||
ok(SUCCEEDED(hr), "SetStreamSource (%u, %p, 0, 64) returned %#x.\n",
|
||||
i, d->vb[i], hr);
|
||||
if (!d->vb[i])
|
||||
{
|
||||
/* Use a non NULL vertex buffer to really set offset and stride and avoid leftover values. */
|
||||
if (!temp_vb)
|
||||
{
|
||||
hr = IDirect3DDevice9_CreateVertexBuffer(device, 64, D3DUSAGE_DYNAMIC,
|
||||
0, D3DPOOL_DEFAULT, &temp_vb, NULL);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
}
|
||||
hr = IDirect3DDevice9_SetStreamSource(device, i, temp_vb, d->stream_offset, d->stream_stride);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_SetStreamSource(device, i, d->vb[i], d->stream_offset, d->stream_stride);
|
||||
ok(hr == D3D_OK, "Unexpected SetStreamSource result, i %u, vb %p, "
|
||||
"stream_offset %u, stream_stride %u), hr %#x.\n",
|
||||
i, d->vb[i], d->stream_offset, d->stream_stride, hr);
|
||||
}
|
||||
if (temp_vb)
|
||||
IDirect3DVertexBuffer9_Release(temp_vb);
|
||||
|
||||
for (i = 0; i < arg->tex_count; ++i)
|
||||
{
|
||||
|
@ -1718,6 +1749,7 @@ static void resource_check_data(IDirect3DDevice9 *device, const struct state_tes
|
|||
const struct resource_test_data *poison = &ctx->poison_data;
|
||||
const struct resource_test_arg *arg = test->test_arg;
|
||||
const struct resource_test_data *d = expected_data;
|
||||
unsigned int expected_offset;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
void *ptr;
|
||||
|
@ -1771,6 +1803,7 @@ static void resource_check_data(IDirect3DDevice9 *device, const struct state_tes
|
|||
IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)ptr);
|
||||
}
|
||||
|
||||
expected_offset = quirk & SB_QUIRK_STREAM_OFFSET_NOT_UPDATED ? 0 : d->stream_offset;
|
||||
for (i = 0; i < arg->stream_count; ++i)
|
||||
{
|
||||
ptr = poison->vb[i];
|
||||
|
@ -1778,6 +1811,8 @@ static void resource_check_data(IDirect3DDevice9 *device, const struct state_tes
|
|||
ok(SUCCEEDED(hr), "GetStreamSource (%u) returned %#x.\n", i, hr);
|
||||
ok(ptr == d->vb[i], "Chain stage %u, stream %u, expected vertex buffer %p, received %p.\n",
|
||||
chain_stage, i, d->vb[i], ptr);
|
||||
ok(v == expected_offset, "Stream source offset %u, expected %u, stride %u.\n", v, expected_offset, w);
|
||||
ok(w == d->stream_stride, "Stream source stride %u, expected %u.\n", w, d->stream_stride);
|
||||
if (SUCCEEDED(hr) && ptr)
|
||||
{
|
||||
IDirect3DIndexBuffer9_Release((IDirect3DVertexBuffer9 *)ptr);
|
||||
|
@ -1811,6 +1846,8 @@ static void resource_default_data_init(struct resource_test_data *data, const st
|
|||
{
|
||||
data->vb[i] = NULL;
|
||||
}
|
||||
data->stream_offset = 0;
|
||||
data->stream_stride = 0;
|
||||
data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
|
||||
for (i = 0; i < arg->tex_count; ++i)
|
||||
{
|
||||
|
@ -1885,6 +1922,8 @@ static void resource_test_data_init(IDirect3DDevice9 *device,
|
|||
0, D3DPOOL_DEFAULT, &data->vb[i], NULL);
|
||||
ok(SUCCEEDED(hr), "CreateVertexBuffer (%u) returned %#x.\n", i, hr);
|
||||
}
|
||||
data->stream_offset = 4;
|
||||
data->stream_stride = 64;
|
||||
data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
|
||||
for (i = 0; i < arg->tex_count; ++i)
|
||||
{
|
||||
|
@ -1908,6 +1947,8 @@ static void resource_poison_data_init(struct resource_test_data *data, const str
|
|||
{
|
||||
data->vb[i] = (IDirect3DVertexBuffer9 *)poison++;
|
||||
}
|
||||
data->stream_offset = 16;
|
||||
data->stream_stride = 128;
|
||||
data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
|
||||
for (i = 0; i < arg->tex_count; ++i)
|
||||
{
|
||||
|
|
|
@ -1388,6 +1388,7 @@ HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UI
|
|||
wined3d_buffer_decref(device->update_stateblock_state->streams[stream_idx].buffer);
|
||||
device->update_stateblock_state->streams[stream_idx].buffer = buffer;
|
||||
device->update_stateblock_state->streams[stream_idx].stride = stride;
|
||||
device->update_stateblock_state->streams[stream_idx].offset = offset;
|
||||
|
||||
if (device->recording)
|
||||
{
|
||||
|
|
|
@ -916,13 +916,17 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
|
|||
if (!(map & 1)) continue;
|
||||
|
||||
if (stateblock->stateblock_state.streams[i].stride != state->streams[i].stride
|
||||
|| stateblock->stateblock_state.streams[i].offset != state->streams[i].offset
|
||||
|| stateblock->stateblock_state.streams[i].buffer != state->streams[i].buffer)
|
||||
{
|
||||
TRACE("Updating stream source %u to %p, stride to %u.\n",
|
||||
i, state->streams[i].buffer,
|
||||
state->streams[i].stride);
|
||||
TRACE("stateblock %p, stream source %u, buffer %p, stride %u, offset %u.\n",
|
||||
stateblock, i, state->streams[i].buffer, state->streams[i].stride,
|
||||
state->streams[i].offset);
|
||||
|
||||
stateblock->stateblock_state.streams[i].stride = state->streams[i].stride;
|
||||
if (stateblock->changed.store_stream_offset)
|
||||
stateblock->stateblock_state.streams[i].offset = state->streams[i].offset;
|
||||
|
||||
if (state->streams[i].buffer)
|
||||
wined3d_buffer_incref(state->streams[i].buffer);
|
||||
if (stateblock->stateblock_state.streams[i].buffer)
|
||||
|
@ -1211,18 +1215,23 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
|
|||
map = stateblock->changed.streamSource;
|
||||
for (i = 0; map; map >>= 1, ++i)
|
||||
{
|
||||
unsigned int offset, stride;
|
||||
|
||||
if (!(map & 1)) continue;
|
||||
|
||||
state->streams[i].stride = stateblock->stateblock_state.streams[i].stride;
|
||||
if (stateblock->stateblock_state.streams[i].buffer)
|
||||
wined3d_buffer_incref(stateblock->stateblock_state.streams[i].buffer);
|
||||
if (state->streams[i].buffer)
|
||||
wined3d_buffer_decref(state->streams[i].buffer);
|
||||
state->streams[i].buffer = stateblock->stateblock_state.streams[i].buffer;
|
||||
|
||||
offset = stateblock->stateblock_state.streams[i].offset;
|
||||
stride = stateblock->stateblock_state.streams[i].stride;
|
||||
|
||||
state->streams[i].stride = stride;
|
||||
state->streams[i].offset = offset;
|
||||
wined3d_device_set_stream_source(device, i,
|
||||
stateblock->stateblock_state.streams[i].buffer,
|
||||
0, stateblock->stateblock_state.streams[i].stride);
|
||||
stateblock->stateblock_state.streams[i].buffer, offset, stride);
|
||||
}
|
||||
|
||||
map = stateblock->changed.streamFreq;
|
||||
|
@ -1554,6 +1563,7 @@ void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state,
|
|||
|
||||
if (flags & WINED3D_STATE_INIT_DEFAULT)
|
||||
stateblock_state_init_default(state, &device->adapter->d3d_info);
|
||||
|
||||
}
|
||||
|
||||
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
|
||||
|
@ -1565,6 +1575,8 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
|
|||
stateblock->device = device;
|
||||
wined3d_stateblock_state_init(&stateblock->stateblock_state, device, 0);
|
||||
|
||||
stateblock->changed.store_stream_offset = 1;
|
||||
|
||||
if (type == WINED3D_SBT_RECORDED)
|
||||
return WINED3D_OK;
|
||||
|
||||
|
@ -1599,6 +1611,12 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
|
|||
stateblock_init_contained_states(stateblock);
|
||||
wined3d_stateblock_capture(stateblock);
|
||||
|
||||
/* According to the tests, stream offset is not updated in the captured state if
|
||||
* the state was captured on state block creation. This is not the case for
|
||||
* state blocks initialized with BeginStateBlock / EndStateBlock, multiple
|
||||
* captures get stream offsets updated. */
|
||||
stateblock->changed.store_stream_offset = 0;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -3657,7 +3657,8 @@ struct wined3d_saved_states
|
|||
DWORD vertexShader : 1;
|
||||
DWORD scissorRect : 1;
|
||||
DWORD blend_state : 1;
|
||||
DWORD padding : 4;
|
||||
DWORD store_stream_offset : 1;
|
||||
DWORD padding : 3;
|
||||
};
|
||||
|
||||
struct StageState {
|
||||
|
|
Loading…
Reference in New Issue