d3d11: Capture and restore vertex shader state.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b85af44374
commit
2213e5a489
|
@ -523,6 +523,13 @@ struct d3d_device_context_state
|
|||
LONG refcount;
|
||||
|
||||
struct wined3d_private_store private_store;
|
||||
struct
|
||||
{
|
||||
ID3D11VertexShader *shader;
|
||||
ID3D11SamplerState *samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
|
||||
ID3D11ShaderResourceView *srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
|
||||
ID3D11Buffer *cbs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
|
||||
} vs;
|
||||
|
||||
GUID emulated_interface;
|
||||
ID3D11Device2 *device;
|
||||
|
|
|
@ -76,12 +76,26 @@ static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContex
|
|||
{
|
||||
struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
|
||||
ULONG refcount = InterlockedDecrement(&state->refcount);
|
||||
unsigned int i;
|
||||
|
||||
TRACE("%p decreasing refcount to %u.\n", state, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
wined3d_private_store_cleanup(&state->private_store);
|
||||
if (state->vs.shader) ID3D11VertexShader_Release(state->vs.shader);
|
||||
for (i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
|
||||
{
|
||||
if (state->vs.samplers[i]) ID3D11SamplerState_Release(state->vs.samplers[i]);
|
||||
}
|
||||
for (i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
|
||||
{
|
||||
if (state->vs.srvs[i]) ID3D11ShaderResourceView_Release(state->vs.srvs[i]);
|
||||
}
|
||||
for (i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
|
||||
{
|
||||
if (state->vs.cbs[i]) ID3D11Buffer_Release(state->vs.cbs[i]);
|
||||
}
|
||||
ID3D11Device2_Release(state->device);
|
||||
heap_free(state);
|
||||
}
|
||||
|
@ -150,6 +164,7 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state
|
|||
state->refcount = 1;
|
||||
|
||||
wined3d_private_store_init(&state->private_store);
|
||||
memset(&state->vs, 0, sizeof(state->vs));
|
||||
|
||||
state->emulated_interface = *emulated_interface;
|
||||
state->device = &device->ID3D11Device2_iface;
|
||||
|
@ -2675,6 +2690,36 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetConstantBuffers1(ID3D
|
|||
iface, start_slot, buffer_count, buffers, first_constant, num_constants);
|
||||
}
|
||||
|
||||
static void d3d11_immediate_context_capture_state(ID3D11DeviceContext1 *iface, struct d3d_device_context_state *state)
|
||||
{
|
||||
wined3d_mutex_lock();
|
||||
|
||||
d3d11_immediate_context_VSGetShader(iface, &state->vs.shader, NULL, 0);
|
||||
d3d11_immediate_context_VSGetSamplers(iface, 0,
|
||||
D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->vs.samplers);
|
||||
d3d11_immediate_context_VSGetShaderResources(iface, 0,
|
||||
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->vs.srvs);
|
||||
d3d11_immediate_context_VSGetConstantBuffers(iface, 0,
|
||||
D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->vs.cbs);
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
}
|
||||
|
||||
static void d3d11_immediate_context_restore_state(ID3D11DeviceContext1 *iface, struct d3d_device_context_state *state)
|
||||
{
|
||||
wined3d_mutex_lock();
|
||||
|
||||
d3d11_immediate_context_VSSetShader(iface, state->vs.shader, NULL, 0);
|
||||
d3d11_immediate_context_VSSetSamplers(iface, 0,
|
||||
D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->vs.samplers);
|
||||
d3d11_immediate_context_VSSetShaderResources(iface, 0,
|
||||
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->vs.srvs);
|
||||
d3d11_immediate_context_VSSetConstantBuffers(iface, 0,
|
||||
D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->vs.cbs);
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3D11DeviceContext1 *iface,
|
||||
ID3DDeviceContextState *state, ID3DDeviceContextState **prev_state)
|
||||
{
|
||||
|
@ -2690,12 +2735,14 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3
|
|||
if ((state_impl = heap_alloc(sizeof(*state_impl))))
|
||||
{
|
||||
d3d_device_context_state_init(state_impl, device, &device->emulated_interface);
|
||||
d3d11_immediate_context_capture_state(iface, state_impl);
|
||||
*prev_state = &state_impl->ID3DDeviceContextState_iface;
|
||||
}
|
||||
}
|
||||
|
||||
if ((state_impl = impl_from_ID3DDeviceContextState(state)))
|
||||
{
|
||||
d3d11_immediate_context_restore_state(iface, state_impl);
|
||||
device->emulated_interface = state_impl->emulated_interface;
|
||||
if (d3d_device_is_d3d10_active(device))
|
||||
FIXME("D3D10 interface emulation not fully implemented yet!\n");
|
||||
|
|
|
@ -6597,16 +6597,36 @@ static void test_state_refcounting(const D3D_FEATURE_LEVEL feature_level)
|
|||
|
||||
static void test_device_context_state(void)
|
||||
{
|
||||
#if 0
|
||||
float4 main(float4 pos : POSITION) : POSITION
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
#endif
|
||||
static const DWORD simple_vs[] =
|
||||
{
|
||||
0x43425844, 0x66689e7c, 0x643f0971, 0xb7f67ff4, 0xabc48688, 0x00000001, 0x000000d4, 0x00000003,
|
||||
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
|
||||
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
|
||||
0x00000000, 0x0000000f, 0x49534f50, 0x4e4f4954, 0xababab00, 0x52444853, 0x00000038, 0x00010040,
|
||||
0x0000000e, 0x0300005f, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
|
||||
0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
|
||||
};
|
||||
|
||||
ID3DDeviceContextState *context_state, *previous_context_state;
|
||||
ID3D11SamplerState *sampler, *tmp_sampler;
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
ID3D11ShaderResourceView *tmp_srv, *srv;
|
||||
D3D11_DEVICE_CONTEXT_TYPE context_type;
|
||||
ID3D11DeviceContext1 *context = NULL;
|
||||
D3D11_SAMPLER_DESC sampler_desc;
|
||||
D3D_FEATURE_LEVEL feature_level;
|
||||
ID3D11VertexShader *tmp_vs, *vs;
|
||||
ID3D11Device *d3d11_device;
|
||||
ID3D11Device1 *device;
|
||||
struct vec4 constant;
|
||||
ID3D11Buffer *cb, *tmp_cb;
|
||||
ID3D11Buffer *cb, *srvb, *tmp_cb;
|
||||
ULONG refcount;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -6677,12 +6697,6 @@ static void test_device_context_state(void)
|
|||
ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
|
||||
ID3D11SamplerState_Release(tmp_sampler);
|
||||
|
||||
ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler);
|
||||
tmp_sampler = NULL;
|
||||
ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler);
|
||||
ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
|
||||
ID3D11SamplerState_Release(tmp_sampler);
|
||||
|
||||
feature_level = min(feature_level, D3D_FEATURE_LEVEL_11_1);
|
||||
hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION,
|
||||
&IID_ID3D11Device1, NULL, &context_state);
|
||||
|
@ -6705,6 +6719,7 @@ static void test_device_context_state(void)
|
|||
check_interface(device, &IID_ID3D11Device1, TRUE, FALSE);
|
||||
|
||||
cb = create_buffer((ID3D11Device *)device, D3D11_BIND_CONSTANT_BUFFER, sizeof(constant), NULL);
|
||||
srvb = create_buffer((ID3D11Device *)device, D3D11_BIND_SHADER_RESOURCE, 1024, NULL);
|
||||
|
||||
ID3D11DeviceContext1_CSSetConstantBuffers(context, 0, 1, &cb);
|
||||
tmp_cb = NULL;
|
||||
|
@ -6718,12 +6733,6 @@ static void test_device_context_state(void)
|
|||
ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
|
||||
ID3D11Buffer_Release(tmp_cb);
|
||||
|
||||
ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &cb);
|
||||
tmp_cb = NULL;
|
||||
ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
|
||||
ID3D11Buffer_Release(tmp_cb);
|
||||
|
||||
ID3D11DeviceContext1_DSSetConstantBuffers(context, 0, 1, &cb);
|
||||
tmp_cb = NULL;
|
||||
ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
|
@ -6742,6 +6751,22 @@ static void test_device_context_state(void)
|
|||
ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
|
||||
ID3D11Buffer_Release(tmp_cb);
|
||||
|
||||
hr = ID3D11Device1_CreateVertexShader(device, simple_vs, sizeof(simple_vs), NULL, &vs);
|
||||
ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
|
||||
|
||||
srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
U(srv_desc).Buffer.ElementOffset = 0;
|
||||
U(srv_desc).Buffer.ElementWidth = 64;
|
||||
hr = ID3D11Device1_CreateShaderResourceView(device, (ID3D11Resource *)srvb, &srv_desc, &srv);
|
||||
ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr);
|
||||
ID3D11Buffer_Release(srvb);
|
||||
|
||||
ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &cb);
|
||||
ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler);
|
||||
ID3D11DeviceContext1_VSSetShader(context, vs, NULL, 0);
|
||||
ID3D11DeviceContext1_VSSetShaderResources(context, 0, 1, &srv);
|
||||
|
||||
previous_context_state = NULL;
|
||||
ID3D11DeviceContext1_SwapDeviceContextState(context, context_state, &previous_context_state);
|
||||
refcount = ID3DDeviceContextState_Release(context_state);
|
||||
|
@ -6751,6 +6776,19 @@ static void test_device_context_state(void)
|
|||
context_type = ID3D11DeviceContext1_GetType(context);
|
||||
ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
|
||||
|
||||
tmp_cb = (ID3D11Buffer *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb);
|
||||
tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler);
|
||||
ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler);
|
||||
tmp_vs = (ID3D11VertexShader *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL);
|
||||
ok(!tmp_vs, "Got unexpected shader %p.\n", tmp_vs);
|
||||
tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv);
|
||||
ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv);
|
||||
|
||||
ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state);
|
||||
refcount = ID3DDeviceContextState_Release(context_state);
|
||||
ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
|
||||
|
@ -6812,6 +6850,14 @@ static void test_device_context_state(void)
|
|||
ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
|
||||
ID3D11Buffer_Release(tmp_cb);
|
||||
tmp_vs = (ID3D11VertexShader *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL);
|
||||
ok(tmp_vs == vs, "Got shader %p, expected %p.\n", tmp_vs, vs);
|
||||
ID3D11VertexShader_Release(tmp_vs);
|
||||
tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv);
|
||||
ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv);
|
||||
ID3D11ShaderResourceView_Release(tmp_srv);
|
||||
|
||||
feature_level = min(feature_level, D3D_FEATURE_LEVEL_10_1);
|
||||
hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION,
|
||||
|
@ -6866,11 +6912,27 @@ static void test_device_context_state(void)
|
|||
todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler);
|
||||
if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
|
||||
|
||||
ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &cb);
|
||||
ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler);
|
||||
ID3D11DeviceContext1_VSSetShader(context, vs, NULL, 0);
|
||||
ID3D11DeviceContext1_VSSetShaderResources(context, 0, 1, &srv);
|
||||
|
||||
tmp_cb = (ID3D11Buffer *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb);
|
||||
if (tmp_cb && tmp_cb != (ID3D11Buffer *)0xdeadbeef) ID3D11Buffer_Release(tmp_cb);
|
||||
tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler);
|
||||
todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler);
|
||||
if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
|
||||
if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) ID3D11SamplerState_Release(tmp_sampler);
|
||||
tmp_vs = (ID3D11VertexShader *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL);
|
||||
todo_wine ok(!tmp_vs, "Got unexpected shader %p.\n", tmp_vs);
|
||||
if (tmp_vs && tmp_vs != (ID3D11VertexShader *)0xdeadbeef) ID3D11VertexShader_Release(tmp_vs);
|
||||
tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv);
|
||||
todo_wine ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv);
|
||||
if (tmp_srv && tmp_srv != (ID3D11ShaderResourceView *)0xdeadbeef) ID3D11ShaderResourceView_Release(tmp_srv);
|
||||
|
||||
tmp_cb = (ID3D11Buffer *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
|
@ -6882,11 +6944,6 @@ static void test_device_context_state(void)
|
|||
todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb);
|
||||
if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
|
||||
|
||||
tmp_cb = (ID3D11Buffer *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb);
|
||||
if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
|
||||
|
||||
tmp_cb = (ID3D11Buffer *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb);
|
||||
|
@ -6929,10 +6986,29 @@ static void test_device_context_state(void)
|
|||
ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
|
||||
ID3D11SamplerState_Release(tmp_sampler);
|
||||
|
||||
tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler);
|
||||
ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
|
||||
ID3D11SamplerState_Release(tmp_sampler);
|
||||
tmp_cb = (ID3D11Buffer *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb);
|
||||
ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
|
||||
ID3D11Buffer_Release(tmp_cb);
|
||||
tmp_vs = (ID3D11VertexShader *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL);
|
||||
ok(tmp_vs == vs, "Got shader %p, expected %p.\n", tmp_vs, vs);
|
||||
ID3D11VertexShader_Release(tmp_vs);
|
||||
tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef;
|
||||
ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv);
|
||||
ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv);
|
||||
ID3D11ShaderResourceView_Release(tmp_srv);
|
||||
|
||||
check_interface(device, &IID_ID3D10Device, TRUE, FALSE);
|
||||
check_interface(device, &IID_ID3D10Device1, TRUE, FALSE);
|
||||
|
||||
ID3D11VertexShader_Release(vs);
|
||||
ID3D11Buffer_Release(cb);
|
||||
ID3D11ShaderResourceView_Release(srv);
|
||||
ID3D11SamplerState_Release(sampler);
|
||||
ID3D11DeviceContext1_Release(context);
|
||||
refcount = ID3D11Device1_Release(device);
|
||||
|
|
Loading…
Reference in New Issue