Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- I don't know if this is the best way to test dynamic map patterns, but it ended up being useful enough when touching mapping code.
dlls/d3d11/tests/d3d11.c | 95 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 67551ac3ca0..d30918a0ad1 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -33896,6 +33896,100 @@ static void test_constant_buffer_offset(void) release_test_context(&test_context); }
+static void fill_dynamic_vb_quad(const D3D11_MAPPED_SUBRESOURCE *map_desc, unsigned int x, unsigned int y) +{ + struct vec3 *quad = (struct vec3 *)map_desc->pData + 4 * x; + + memset(quad, 0, 4 * sizeof(*quad)); + + quad[0].x = quad[1].x = -1.0f + 0.01f * x; + quad[2].x = quad[3].x = -1.0f + 0.01f * (x + 1); + + quad[0].y = quad[2].y = -1.0f + 0.01f * y; + quad[1].y = quad[3].y = -1.0f + 0.01f * (y + 1); +} + +/* Stress-test dynamic maps, to ensure that we are applying the correct + * synchronization guarantees. */ +static void test_dynamic_map_synchronization(void) +{ + static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f}; + static const struct vec4 red = {1.0f, 0.0f, 0.0f, 1.0f}; + ID3D11DeviceContext *immediate, *deferred; + struct d3d11_test_context test_context; + D3D11_BUFFER_DESC buffer_desc = {0}; + D3D11_MAPPED_SUBRESOURCE map_desc; + ID3D11CommandList *list; + ID3D11Device *device; + unsigned int x, y; + HRESULT hr; + + if (!init_test_context(&test_context, NULL)) + return; + device = test_context.device; + immediate = test_context.immediate_context; + + hr = ID3D11Device_CreateDeferredContext(device, 0, &deferred); + ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); + + buffer_desc.ByteWidth = 200 * 4 * sizeof(struct vec3); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + hr = ID3D11Device_CreateBuffer(device, &buffer_desc, NULL, &test_context.vb); + ok(hr == S_OK, "Failed to create vertex buffer, hr %#x.\n", hr); + + ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &red.x); + + for (y = 0; y < 200; ++y) + { + if (y % 2) + { + hr = ID3D11DeviceContext_Map(immediate, (ID3D11Resource *)test_context.vb, + 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc); + ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr); + + fill_dynamic_vb_quad(&map_desc, 0, y); + + ID3D11DeviceContext_Unmap(immediate, (ID3D11Resource *)test_context.vb, 0); + draw_color_quad(&test_context, &green); + } + else + { + hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)test_context.vb, + 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc); + ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr); + + fill_dynamic_vb_quad(&map_desc, 0, y); + + ID3D11DeviceContext_Unmap(deferred, (ID3D11Resource *)test_context.vb, 0); + + hr = ID3D11DeviceContext_FinishCommandList(deferred, FALSE, &list); + ok(hr == S_OK, "Failed to record command list, hr %#x.\n", hr); + ID3D11DeviceContext_ExecuteCommandList(immediate, list, TRUE); + ID3D11CommandList_Release(list); + draw_color_quad(&test_context, &green); + } + + for (x = 1; x < 200; ++x) + { + hr = ID3D11DeviceContext_Map(immediate, (ID3D11Resource *)test_context.vb, + 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map_desc); + ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr); + + fill_dynamic_vb_quad(&map_desc, x, y); + + ID3D11DeviceContext_Unmap(immediate, (ID3D11Resource *)test_context.vb, 0); + ID3D11DeviceContext_Draw(immediate, 4, x * 4); + } + } + + check_texture_color(test_context.backbuffer, 0xff00ff00, 0); + + ID3D11DeviceContext_Release(deferred); + release_test_context(&test_context); +} + START_TEST(d3d11) { unsigned int argc, i; @@ -34072,6 +34166,7 @@ START_TEST(d3d11) queue_test(test_unbound_streams); queue_test(test_texture_compressed_3d); queue_test(test_constant_buffer_offset); + queue_test(test_dynamic_map_synchronization);
run_queued_tests(); }