[PATCH 03/11] d3d9/tests: Add tests for D3DQUERY_TIMESTAMP* queries.
Adam Martinson
amartinson at codeweavers.com
Fri May 27 14:12:36 CDT 2011
---
dlls/d3d9/tests/query.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 301 insertions(+), 0 deletions(-)
diff --git a/dlls/d3d9/tests/query.c b/dlls/d3d9/tests/query.c
index 97d3508..89daccc 100644
--- a/dlls/d3d9/tests/query.c
+++ b/dlls/d3d9/tests/query.c
@@ -246,6 +246,305 @@ cleanup:
}
}
+/* Test for basic sanity against QueryPerformanceCounter()/QueryPerformanceFrequency() */
+static void test_timestamp_queries(IDirect3D9 *d3d, HWND hwnd)
+{
+ HRESULT hr;
+ int i, j;
+ IDirect3DDevice9 *device = NULL;
+ D3DPRESENT_PARAMETERS d3dpp;
+ D3DDISPLAYMODE d3ddm;
+ IDirect3DQuery9 *q_ts1 = NULL, *q_ts2 = NULL, *q_disjoint = NULL, *q_freq = NULL;
+ UINT64 freq = 0, ts1 = 0, ts2 = 0, elapsed, qp_elapsed1, qp_elapsed2;
+ LARGE_INTEGER qp_freq, qp_ts1, qp_ts2, qp_ts3, qp_ts4;
+ BOOL ts_dj = TRUE;
+ UINT size;
+
+ if (!QueryPerformanceFrequency(&qp_freq))
+ {
+ skip("QueryPerformanceFrequency() failed\n");
+ goto cleanup;
+ }
+
+ IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ d3dpp.BackBufferFormat = d3ddm.Format;
+
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
+ if (FAILED(hr))
+ {
+ skip("Failed to create a d3d device\n");
+ goto cleanup;
+ }
+
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &q_ts1);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &q_ts2);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &q_freq);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &q_disjoint);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+
+ if(!q_freq || !q_ts1 || !q_ts2 || !q_disjoint)
+ {
+ skip("Timestamp queries not supported\n");
+ goto cleanup;
+ }
+
+ /* Non-issued queries should succeed, but the data is garbage. */
+ hr = IDirect3DQuery9_GetData(q_ts1, &ts1, sizeof(ts1), D3DGETDATA_FLUSH);
+ ok(hr == D3D_OK, "IDirect3DQuery9_GetData(q_ts1) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_GetData(q_freq, &freq, sizeof(freq), D3DGETDATA_FLUSH);
+ ok(hr == D3D_OK, "IDirect3DQuery9_GetData(q_freq) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_GetData(q_disjoint, &ts_dj, sizeof(ts_dj), D3DGETDATA_FLUSH);
+ ok(hr == D3D_OK, "IDirect3DQuery9_GetData(q_disjoint) returned %08x\n", hr);
+
+ for (i = 0; i < 2; ++i)
+ {
+ do
+ {
+ QueryPerformanceCounter(&qp_ts1);
+
+ hr = IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_BEGIN);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_BEGIN) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_GetData(q_disjoint, &ts_dj, sizeof(ts_dj), 0);
+ ok(hr == D3D_OK, "IDirect3DQuery9_GetData(q_disjoint) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_Issue(q_freq, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_freq, D3DISSUE_END) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_Issue(q_ts1, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_ts1, D3DISSUE_END) returned %08x\n", hr);
+
+ do
+ {
+ QueryPerformanceCounter(&qp_ts2);
+ }
+ while (qp_ts1.QuadPart == qp_ts2.QuadPart);
+
+ do
+ {
+ QueryPerformanceCounter(&qp_ts3);
+ }
+ while (qp_ts2.QuadPart == qp_ts3.QuadPart);
+
+ hr = IDirect3DQuery9_Issue(q_ts2, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_ts2, D3DISSUE_END) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_END) returned %08x\n", hr);
+
+ do
+ {
+ QueryPerformanceCounter(&qp_ts4);
+ }
+ while (qp_ts3.QuadPart == qp_ts4.QuadPart);
+
+ }
+ while (qp_ts1.QuadPart > qp_ts2.QuadPart || qp_ts2.QuadPart > qp_ts3.QuadPart || qp_ts3.QuadPart > qp_ts4.QuadPart);
+
+ size = IDirect3DQuery9_GetDataSize(q_ts1);
+ ok(size == sizeof(ts1), "IDirect3DQuery9_GetDataSize(q_ts1) returned %i\n", size);
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_ts1, &ts1, size, D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestamp query failed: %08x\n", hr);
+
+ size = IDirect3DQuery9_GetDataSize(q_ts2);
+ ok(size == sizeof(ts2), "IDirect3DQuery9_GetDataSize(q_ts2) returned %i\n", size);
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_ts2, &ts2, size, D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestamp query failed: %08x\n", hr);
+
+ size = IDirect3DQuery9_GetDataSize(q_freq);
+ ok(size == sizeof(freq), "IDirect3DQuery9_GetDataSize(q_freq) returned %i\n", size);
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_freq, &freq, size, D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestampfreq query failed: %08x\n", hr);
+
+ ts_dj = TRUE;
+ size = IDirect3DQuery9_GetDataSize(q_disjoint);
+ ok(size == sizeof(ts_dj), "IDirect3DQuery9_GetDataSize(q_disjoint) returned %i\n", size);
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_disjoint, &ts_dj, size, D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestampdisjoint query failed: %08x\n", hr);
+
+ if (!ts_dj)
+ break;
+ }
+ ok(!ts_dj, "Timestamps may be disjoint\n");
+
+#define NANOSECONDS 1000000000
+ ok(ts1 != ts2, "Timestamps are equal: 0x%08x%08x\n", (UINT)(ts1 >> 32), (UINT)(ts1 & 0xFFFFFFFF));
+ elapsed = ((double)(ts2 - ts1) / freq) * NANOSECONDS;
+ qp_elapsed1 = ((double)(qp_ts4.QuadPart - qp_ts1.QuadPart) / qp_freq.QuadPart) * NANOSECONDS;
+ qp_elapsed2 = ((double)(qp_ts3.QuadPart - qp_ts2.QuadPart) / qp_freq.QuadPart) * NANOSECONDS;
+
+ /* sanity check */
+ ok(qp_elapsed1 >= elapsed && elapsed >= qp_elapsed2, "Timestamp sanity check fail: 0x%08x%08x >= 0x%08x%08x >= 0x%08x%08x\n",
+ (UINT)(qp_elapsed1 >> 32), (UINT)(qp_elapsed1 & 0xFFFFFFFF),
+ (UINT)(elapsed >> 32), (UINT)(elapsed & 0xFFFFFFFF),
+ (UINT)(qp_elapsed2 >> 32), (UINT)(qp_elapsed2 & 0xFFFFFFFF));
+
+cleanup:
+ if (q_ts1) IDirect3DQuery9_Release(q_ts1);
+ if (q_ts2) IDirect3DQuery9_Release(q_ts2);
+ if (q_freq) IDirect3DQuery9_Release(q_freq);
+ if (q_disjoint) IDirect3DQuery9_Release(q_disjoint);
+ if (device)
+ {
+ UINT refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ }
+}
+
+/* Test counter overflow */
+static void test_timestampdisjoint_queries(IDirect3D9 *d3d, HWND hwnd)
+{
+ HRESULT hr;
+ int i, j, len;
+ IDirect3DDevice9 *device = NULL;
+ D3DPRESENT_PARAMETERS d3dpp;
+ D3DDISPLAYMODE d3ddm;
+ IDirect3DQuery9 *q_ts = NULL, *q_disjoint = NULL, *q_freq = NULL;
+ UINT64 freq1 = 0, freq2 = 0, ts1 = 0, ts2 = 0;
+ BOOL ts_dj = TRUE;
+ int iterations;
+
+ if ((len = GetEnvironmentVariableA("D3D9TEST_TSDJ_ITERATIONS", NULL, 0)))
+ {
+ char* buf = HeapAlloc(GetProcessHeap(), 0, len);
+ GetEnvironmentVariableA("D3D9TEST_TSDJ_ITERATIONS", buf, len);
+ iterations = strtol(buf, NULL, 0);
+ }
+ else
+ {
+ iterations = 60;
+ }
+
+ IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ d3dpp.BackBufferFormat = d3ddm.Format;
+
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
+ if (FAILED(hr))
+ {
+ skip("Failed to create a d3d device\n");
+ goto cleanup;
+ }
+
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &q_ts);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &q_freq);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+ hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &q_disjoint);
+ ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE,
+ "IDirect3DDevice9_CreateQuery returned unexpected return value %08x\n", hr);
+
+ if(!q_freq || !q_ts || !q_disjoint)
+ {
+ skip("Timestamp queries not supported\n");
+ goto cleanup;
+ }
+
+ hr = IDirect3DQuery9_Issue(q_freq, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_freq, D3DISSUE_END) returned %08x\n", hr);
+
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_freq, &freq1, sizeof(freq1), D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestampfreq query failed: %08x\n", hr);
+ trace("freq: 0x%08x%08x\n", (UINT)(freq1 >> 32), (UINT)(freq1 & 0xFFFFFFFF));
+
+ hr = IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_BEGIN);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_BEGIN) returned %08x\n", hr);
+
+ hr = IDirect3DQuery9_Issue(q_ts, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_ts, D3DISSUE_END) returned %08x\n", hr);
+
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_ts, &ts1, sizeof(ts1), D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestamp query failed: %08x\n", hr);
+ trace("ts: 0x%08x%08x\n", (UINT)(ts1 >> 32), (UINT)(ts1 & 0xFFFFFFFF));
+
+ for (i = 0; i < iterations; ++i)
+ {
+ hr = IDirect3DQuery9_Issue(q_freq, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_freq, D3DISSUE_END) returned %08x\n", hr);
+ hr = IDirect3DQuery9_Issue(q_ts, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_ts, D3DISSUE_END) returned %08x\n", hr);
+
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_freq, &freq2, sizeof(freq2), D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestampfreq query failed: %08x\n", hr);
+
+ trace("freq: 0x%08x%08x\n", (UINT)(freq2 >> 32), (UINT)(freq2 & 0xFFFFFFFF));
+ if (freq1 != freq2)
+ break;
+
+
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_ts, &ts2, sizeof(ts2), D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestamp query failed: %08x\n", hr);
+
+ trace("ts: 0x%08x%08x\n", (UINT)(ts2 >> 32), (UINT)(ts2 & 0xFFFFFFFF));
+ if (ts2 < ts1)
+ break;
+
+ Sleep(500);
+ }
+
+ hr = IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_END);
+ ok(hr == D3D_OK, "IDirect3DQuery9_Issue(q_disjoint, D3DISSUE_END) returned %08x\n", hr);
+
+ for (j = 0; (hr = IDirect3DQuery9_GetData(q_disjoint, &ts_dj, sizeof(ts_dj), D3DGETDATA_FLUSH)) == S_FALSE && j < 500; ++j)
+ {
+ Sleep(10);
+ }
+ ok(hr == S_OK, "Timestampdisjoint query failed: %08x\n", hr);
+ ok((ts2 < ts1 || freq1 != freq2) == ts_dj, "Timestamps disjoint check failed\n");
+
+cleanup:
+ if (q_ts) IDirect3DQuery9_Release(q_ts);
+ if (q_freq) IDirect3DQuery9_Release(q_freq);
+ if (q_disjoint) IDirect3DQuery9_Release(q_disjoint);
+ if (device)
+ {
+ UINT refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ }
+}
+
START_TEST(query)
{
HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
@@ -282,6 +581,8 @@ START_TEST(query)
test_query_support(pD3d, hwnd);
test_occlusion_query_states(pD3d, hwnd);
+ test_timestamp_queries(pD3d, hwnd);
+ test_timestampdisjoint_queries(pD3d, hwnd);
out:
if(pD3d) IDirect3D9_Release(pD3d);
--
1.7.1
--------------040801020906020701060908
Content-Type: text/x-patch;
name="0004-wined3d-Add-support-for-D3DQUERY_TIMESTAMP-queries.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment;
filename*0="0004-wined3d-Add-support-for-D3DQUERY_TIMESTAMP-queries.patc";
filename*1="h"
More information about the wine-devel
mailing list