[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: Re: Support for D3DQUERY_TIMESTAMP* queries...
From: Adam Martinson <amartinson () codeweavers ! com>
Date: 2011-05-27 19:16:40
Message-ID: 4DDFF898.6090402 () codeweavers ! com
[Download RAW message or body]
On 05/27/2011 01:23 PM, Adam Martinson wrote:
> On 05/25/2011 11:31 AM, Stefan Dösinger wrote:
>> On Wednesday 25 May 2011 18:23:39 Adam Martinson wrote:
>>> Do you think that needs to be done before I submit those or is that
>>> something that can come later?
>> I'd prefer to have this checked before submitting. It shouldn't take
>> long.
>> Just write a test app that grabs the timestamp in a loop and prints
>> it to
>> stdout and see what kind of values it writes. If it does wrap around
>> in a
>> reasonable amount of time(e.g. a few hours) write a test that waits
>> for the
>> wraparound to approach, starts a disjoint query, waits until after the
>> wraparound, ends the disjoint query and prints its result.
> Ran a test for 10 mins or so, on my card it behaves like the
> GL_ARB_timer_query version, except the frequency is 10ns instead of
> 1ns... so it doesn't look like it would wrap around in my lifetime. I
> can include that test with an environment variable to set the number
> of iterations if you like.
Are these ok to submit now?
["0002-wined3d-Add-support-for-GL_ARB_timer_query.patch" (text/x-patch)]
From 22312de4267235eec7e9720383aaee073fd586a6 Mon Sep 17 00:00:00 2001
From: Adam Martinson <amartinson@codeweavers.com>
Date: Tue, 17 May 2011 11:14:01 -0500
Subject: [PATCH 02/11] wined3d: Add support for GL_ARB_timer_query.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
dlls/wined3d/directx.c | 1 +
dlls/wined3d/wined3d_gl.h | 19 +++++++++++++++++++
2 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index a29533e..c643956 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -86,6 +86,7 @@ static const struct {
{"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, \
MAKEDWORD_VERSION(2, 0) },
{"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE, 0 \
},
{"GL_ARB_texture_rg", ARB_TEXTURE_RG, 0 \
}, + {"GL_ARB_timer_query", ARB_TIMER_QUERY, 0 \
},
{"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA, 0 \
},
{"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 \
},
{"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 \
},
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index be50b2f..3248bdb 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -1769,6 +1769,7 @@ typedef enum wined3d_gl_extension
ARB_TEXTURE_NON_POWER_OF_TWO,
ARB_TEXTURE_RECTANGLE,
ARB_TEXTURE_RG,
+ ARB_TIMER_QUERY,
ARB_VERTEX_ARRAY_BGRA,
ARB_VERTEX_BLEND,
ARB_VERTEX_BUFFER_OBJECT,
@@ -2458,6 +2459,17 @@ typedef GLvoid (WINE_GLAPI *PGLFNGETSYNCIVPROC)(GLsync sync, \
GLenum pname, GLsiz #define GL_RG32UI \
0x823c #endif
+/* GL_ARB_timer_query */
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+#define GL_TIME_ELAPSED_ARB 0x88bf
+#define GL_TIMESTAMP_ARB 0x8e28
+#endif
+
+typedef void (WINE_GLAPI *PGLFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target);
+typedef void (WINE_GLAPI *PGLFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, \
GLint64 *params); +typedef void (WINE_GLAPI *PGLFNGLGETQUERYOBJECTUI64VPROC)(GLuint \
id, GLenum pname, GLuint64 *params); +
/* GL_ARB_vertex_blend */
#ifndef GL_ARB_vertex_blend
#define GL_ARB_vertex_blend 1
@@ -4002,6 +4014,13 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSWAPINTERVALEXTPROC)(int \
interval);
glCompressedTexSubImage3DARB, ARB_TEXTURE_COMPRESSION, \
NULL) \ USE_GL_FUNC(PGLFNGETCOMPRESSEDTEXIMAGEPROC, \
glGetCompressedTexImageARB, ARB_TEXTURE_COMPRESSION, \
NULL) \ + /* GL_ARB_timer_query */ \
+ USE_GL_FUNC(PGLFNGLQUERYCOUNTERPROC, \
+ glQueryCounter, ARB_TIMER_QUERY, \
NULL) \ + USE_GL_FUNC(PGLFNGLGETQUERYOBJECTI64VPROC, \
+ glGetQueryObjecti64v, ARB_TIMER_QUERY, \
NULL) \ + USE_GL_FUNC(PGLFNGLGETQUERYOBJECTUI64VPROC, \
+ glGetQueryObjectui64v, ARB_TIMER_QUERY, \
NULL) \ /* GL_ARB_vertex_blend */ \
USE_GL_FUNC(PGLFNGLWEIGHTPOINTERARB, \
glWeightPointerARB, ARB_VERTEX_BLEND, \
NULL) \
--
1.7.1
["0003-d3d9-tests-Add-tests-for-D3DQUERY_TIMESTAMP-queries.patch" (text/x-patch)]
From ca8157a3233c0a022c5c2084120db9a251c2eb8a Mon Sep 17 00:00:00 2001
From: Adam Martinson <amartinson@codeweavers.com>
Date: Fri, 27 May 2011 14:12:36 -0500
Subject: [PATCH 03/11] d3d9/tests: Add tests for D3DQUERY_TIMESTAMP* queries.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
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
["0004-wined3d-Add-support-for-D3DQUERY_TIMESTAMP-queries.patch" (text/x-patch)]
From 1e3276df1159f7719da52c21e820873224019039 Mon Sep 17 00:00:00 2001
From: Adam Martinson <amartinson@codeweavers.com>
Date: Mon, 23 May 2011 15:13:45 -0500
Subject: [PATCH 04/11] wined3d: Add support for D3DQUERY_TIMESTAMP queries.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
dlls/wined3d/context.c | 80 +++++++++++++++++++
dlls/wined3d/query.c | 165 +++++++++++++++++++++++++++++++++++++---
dlls/wined3d/wined3d_private.h | 17 ++++
3 files changed, 250 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 0494252..02aa5c4 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -650,6 +650,66 @@ void context_free_event_query(struct wined3d_event_query *query)
context->free_event_queries[context->free_event_query_count++] = query->object;
}
+/* Context activation is done by the caller.
+ * Only called when GL_ARB_timer_query is supported. */
+void context_alloc_timestamp_query(struct wined3d_context *context, struct \
wined3d_timestamp_query *query) +{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ int i, n_new;
+
+ for (i = 0; i < query->n_ids && i < context->free_timestamp_query_count; ++i)
+ query->ids[i] = \
context->free_timestamp_queries[--context->free_timestamp_query_count]; +
+ if ((n_new = query->n_ids - i))
+ {
+
+ ENTER_GL();
+ GL_EXTCALL(glGenQueriesARB(n_new, &query->ids[i]));
+ checkGLcall("glGenQueriesARB");
+ LEAVE_GL();
+
+ if (TRACE_ON(d3d))
+ {
+ for (; i < query->n_ids; ++i)
+ TRACE("Allocated timestamp query %u in context %p.\n", \
query->ids[i], context); + }
+ }
+
+ query->context = context;
+ list_add_head(&context->timestamp_queries, &query->entry);
+}
+
+/* Context activation is done by the caller.
+ * Only called when GL_ARB_timer_query is supported. */
+void context_free_timestamp_query(struct wined3d_timestamp_query *query)
+{
+ struct wined3d_context *context = query->context;
+ int i;
+
+ list_remove(&query->entry);
+ query->context = NULL;
+
+ if (context->free_timestamp_query_count + query->n_ids >= \
context->free_timestamp_query_size) + {
+ UINT new_size = context->free_timestamp_query_size << 1;
+ GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, \
context->free_timestamp_queries, + new_size * \
sizeof(*context->free_timestamp_queries)); +
+ if (!new_data)
+ {
+ for (i = 0; i < query->n_ids; ++i)
+ ERR("Failed to grow free list, leaking query %u in context %p.\n", \
query->ids[i], context); + return;
+ }
+
+ context->free_timestamp_query_size = new_size;
+ context->free_timestamp_queries = new_data;
+ }
+
+ for (i = 0; i < query->n_ids; ++i)
+ context->free_timestamp_queries[context->free_timestamp_query_count++] = \
query->ids[i]; +}
+
typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct \
fbo_entry *entry);
static void context_enum_surface_fbo_entries(struct wined3d_device *device,
@@ -924,6 +984,7 @@ static void context_destroy_gl_resources(struct wined3d_context \
*context) const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_occlusion_query *occlusion_query;
struct wined3d_event_query *event_query;
+ struct wined3d_timestamp_query *timestamp_query;
struct fbo_entry *entry, *entry2;
HGLRC restore_ctx;
HDC restore_dc;
@@ -960,6 +1021,13 @@ static void context_destroy_gl_resources(struct wined3d_context \
*context) event_query->context = NULL;
}
+ LIST_FOR_EACH_ENTRY(timestamp_query, &context->timestamp_queries, struct \
wined3d_timestamp_query, entry) + {
+ if (context->valid && gl_info->supported[ARB_TIMER_QUERY])
+ GL_EXTCALL(glDeleteQueriesARB(timestamp_query->n_ids, \
timestamp_query->ids)); + timestamp_query->context = NULL;
+ }
+
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct \
fbo_entry, entry) {
if (!context->valid) entry->id = 0;
@@ -987,6 +1055,9 @@ static void context_destroy_gl_resources(struct wined3d_context \
*context) if (gl_info->supported[ARB_OCCLUSION_QUERY])
GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, \
context->free_occlusion_queries));
+ if (gl_info->supported[ARB_TIMER_QUERY])
+ GL_EXTCALL(glDeleteQueriesARB(context->free_timestamp_query_count, \
context->free_timestamp_queries)); +
if (gl_info->supported[ARB_SYNC])
{
for (i = 0; i < context->free_event_query_count; ++i)
@@ -1016,6 +1087,7 @@ static void context_destroy_gl_resources(struct wined3d_context \
*context)
HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
HeapFree(GetProcessHeap(), 0, context->free_event_queries);
+ HeapFree(GetProcessHeap(), 0, context->free_timestamp_queries);
if (restore_ctx)
{
@@ -1512,6 +1584,13 @@ struct wined3d_context *context_create(struct \
wined3d_swapchain *swapchain,
list_init(&ret->event_queries);
+ ret->free_timestamp_query_size = 4;
+ ret->free_timestamp_queries = HeapAlloc(GetProcessHeap(), 0,
+ ret->free_timestamp_query_size * sizeof(*ret->free_timestamp_queries));
+ if (!ret->free_timestamp_queries) goto out;
+
+ list_init(&ret->timestamp_queries);
+
TRACE("Successfully created new context %p\n", ret);
list_init(&ret->fbo_list);
@@ -1660,6 +1739,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain \
*swapchain, out:
HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
+ HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries);
HeapFree(GetProcessHeap(), 0, ret->draw_buffers);
HeapFree(GetProcessHeap(), 0, ret->blit_targets);
HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty);
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index ca4426f..c0d5c63 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -4,6 +4,7 @@
* Copyright 2005 Oliver Stieber
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
* Copyright 2009-2010 Henri Verbeet for CodeWeavers.
+ * Copyright 2011 Adam Martinson for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -253,17 +254,35 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
* deleting the query will obviously leak it, but that's still better
* than potentially deleting a different query with the same id in this
* context, and (still) leaking the actual query. */
- if (query->type == WINED3DQUERYTYPE_EVENT)
+ switch (query->type)
{
- struct wined3d_event_query *event_query = query->extendedData;
- if (event_query) wined3d_event_query_destroy(event_query);
- }
- else if (query->type == WINED3DQUERYTYPE_OCCLUSION)
- {
- struct wined3d_occlusion_query *oq = query->extendedData;
+ case WINED3DQUERYTYPE_EVENT:
+ {
+ struct wined3d_event_query *event_query = query->extendedData;
+ if (event_query) wined3d_event_query_destroy(event_query);
+ }
+ break;
+
+ case WINED3DQUERYTYPE_OCCLUSION:
+ {
+ struct wined3d_occlusion_query *oq = query->extendedData;
- if (oq->context) context_free_occlusion_query(oq);
- HeapFree(GetProcessHeap(), 0, query->extendedData);
+ if (oq->context) context_free_occlusion_query(oq);
+ HeapFree(GetProcessHeap(), 0, query->extendedData);
+ }
+ break;
+
+ case WINED3DQUERYTYPE_TIMESTAMP:
+ {
+ struct wined3d_timestamp_query *tsq = query->extendedData;
+
+ if (tsq->context) context_free_timestamp_query(tsq);
+ HeapFree(GetProcessHeap(), 0, query->extendedData);
+ }
+ break;
+
+ default:
+ break;
}
HeapFree(GetProcessHeap(), 0, query);
@@ -414,6 +433,69 @@ static HRESULT wined3d_event_query_ops_get_data(struct \
wined3d_query *query, return S_OK;
}
+/* Only called when GL_ARB_timer_query is supported. */
+static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
+ void *data, DWORD size, DWORD \
flags) +{
+ const struct wined3d_gl_info *gl_info = &query->device->adapter->gl_info;
+ struct wined3d_timestamp_query *timestamp_query = query->extendedData;
+ struct wined3d_context *context;
+ GLuint available;
+ UINT64 *timestamp = data;
+ HRESULT res;
+
+ TRACE("(%p) : type D3DQUERY_TIMESTAMP, data %p, size %#x, flags %#x.\n", query, \
data, size, flags); +
+ if (!timestamp_query->context)
+ query->state = QUERY_CREATED;
+
+ if (query->state != QUERY_SIGNALLED)
+ {
+ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the \
data ourselves */ + TRACE("Query wasn't yet started, returning S_OK\n");
+ if (timestamp)
+ *timestamp = 0;
+ return S_OK;
+ }
+
+ if (timestamp_query->context->tid != GetCurrentThreadId())
+ {
+ FIXME("%p Wrong thread, returning 0.\n", query);
+ if (timestamp)
+ *timestamp = 0;
+ return S_OK;
+ }
+
+ context = context_acquire(query->device, timestamp_query->context->current_rt);
+
+ ENTER_GL();
+
+ GL_EXTCALL(glGetQueryObjectuivARB(timestamp_query->ids[0], \
GL_QUERY_RESULT_AVAILABLE_ARB, &available)); + \
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)"); + \
TRACE("available %#x.\n", available); +
+ if (available)
+ {
+ if (timestamp)
+ {
+ GL_EXTCALL(glGetQueryObjectui64v(timestamp_query->ids[0], \
GL_QUERY_RESULT_ARB, timestamp)); + \
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)"); + TRACE("Returning \
0x%08x%08x.\n", (UINT)((*timestamp) >> 32), (UINT)((*timestamp) & 0xFFFFFFFF)); + \
} + res = S_OK;
+ }
+ else
+ {
+ res = S_FALSE;
+ }
+
+ LEAVE_GL();
+
+ context_release(context);
+
+ return res;
+}
+
WINED3DQUERYTYPE CDECL wined3d_query_get_type(const struct wined3d_query *query)
{
TRACE("query %p.\n", query);
@@ -537,6 +619,39 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct \
wined3d_query *query, DW return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
}
+/* Only called when GL_ARB_timer_query is supported. */
+static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD \
flags) +{
+ const struct wined3d_gl_info *gl_info = &query->device->adapter->gl_info;
+ struct wined3d_timestamp_query *timestamp_query = query->extendedData;
+ struct wined3d_context *context;
+
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ /* MSDN: D3DISSUE_BEGIN not supported */
+
+ if (!timestamp_query->context)
+ {
+ context = context_acquire(query->device, NULL);
+ context_alloc_timestamp_query(context, timestamp_query);
+ }
+ else
+ {
+ context = context_acquire(query->device, \
timestamp_query->context->current_rt); + }
+
+ ENTER_GL();
+ GL_EXTCALL(glQueryCounter(timestamp_query->ids[0], GL_TIMESTAMP_ARB));
+ checkGLcall("glQueryCounter(GL_TIMESTAMP)");
+ LEAVE_GL();
+
+ context_release(context);
+
+ query->state = QUERY_SIGNALLED;
+
+ return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
+}
+
static const struct wined3d_query_ops event_query_ops =
{
wined3d_event_query_ops_get_data,
@@ -549,6 +664,12 @@ static const struct wined3d_query_ops occlusion_query_ops =
wined3d_occlusion_query_ops_issue,
};
+static const struct wined3d_query_ops timestamp_query_ops =
+{
+ wined3d_timestamp_query_ops_get_data,
+ wined3d_timestamp_query_ops_issue,
+};
+
static HRESULT query_init(struct wined3d_query *query, struct wined3d_device \
*device, WINED3DQUERYTYPE type) {
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@@ -593,12 +714,32 @@ static HRESULT query_init(struct wined3d_query *query, struct \
wined3d_device *de }
break;
- case WINED3DQUERYTYPE_VCACHE:
- case WINED3DQUERYTYPE_RESOURCEMANAGER:
- case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_TIMESTAMP:
+ TRACE("Timestamp query.\n");
+ if (!gl_info->supported[ARB_TIMER_QUERY])
+ {
+ WARN("GL_ARB_timer_query not supported, returning \
WINED3DERR_NOTAVAILABLE.\n"); + return WINED3DERR_NOTAVAILABLE;
+ }
+
+ query->data_size = sizeof(UINT64);
+ query->query_ops = ×tamp_query_ops;
+ query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, \
sizeof(struct wined3d_timestamp_query)); + if (!query->extendedData)
+ {
+ ERR("Failed to allocate event query memory.\n");
+ return E_OUTOFMEMORY;
+ }
+ ((struct wined3d_timestamp_query *)query->extendedData)->n_ids = 1;
+ ((struct wined3d_timestamp_query *)query->extendedData)->context = NULL;
+
+ break;
+
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
+ case WINED3DQUERYTYPE_VCACHE:
+ case WINED3DQUERYTYPE_RESOURCEMANAGER:
+ case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_PIPELINETIMINGS:
case WINED3DQUERYTYPE_INTERFACETIMINGS:
case WINED3DQUERYTYPE_VERTEXTIMINGS:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index aaf1423..39b39f8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1019,6 +1019,15 @@ struct wined3d_event_query
struct wined3d_context *context;
};
+struct wined3d_timestamp_query
+{
+ struct list entry;
+ struct wined3d_context *context;
+ int n_ids;
+ GLuint ids[3];
+};
+
+
enum wined3d_event_query_result
{
WINED3D_EVENT_QUERY_OK,
@@ -1110,6 +1119,11 @@ struct wined3d_context
UINT free_event_query_count;
struct list event_queries;
+ GLuint *free_timestamp_queries;
+ UINT free_timestamp_query_size;
+ UINT free_timestamp_query_count;
+ struct list timestamp_queries;
+
/* Extension emulation */
GLint gl_fog_source;
GLfloat fog_coord_value;
@@ -1208,6 +1222,8 @@ void context_alloc_event_query(struct wined3d_context *context,
struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_alloc_occlusion_query(struct wined3d_context *context,
struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
+void context_alloc_timestamp_query(struct wined3d_context *context,
+ struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN;
void context_apply_blit_state(struct wined3d_context *context, struct wined3d_device \
*device) DECLSPEC_HIDDEN; BOOL context_apply_clear_state(struct wined3d_context \
*context, struct wined3d_device *device,
UINT rt_count, struct wined3d_surface **rts, struct wined3d_surface \
*depth_stencil) DECLSPEC_HIDDEN; @@ -1223,6 +1239,7 @@ struct wined3d_context \
*context_create(struct wined3d_swapchain *swapchain, stru void \
context_destroy(struct wined3d_device *device, struct wined3d_context *context) \
DECLSPEC_HIDDEN; void context_free_event_query(struct wined3d_event_query *query) \
DECLSPEC_HIDDEN; void context_free_occlusion_query(struct wined3d_occlusion_query \
*query) DECLSPEC_HIDDEN; +void context_free_timestamp_query(struct \
wined3d_timestamp_query *query) DECLSPEC_HIDDEN; struct wined3d_context \
*context_get_current(void) DECLSPEC_HIDDEN; DWORD context_get_tls_idx(void) \
DECLSPEC_HIDDEN; void context_release(struct wined3d_context *context) \
DECLSPEC_HIDDEN;
--
1.7.1
["0005-wined3d-query-Add-support-for-D3DQUERY_TIMESTAMPDISJ.patch" (text/x-patch)]
From e9ecf1e85f1e6e4832683d95ffbe0407602ac18e Mon Sep 17 00:00:00 2001
From: Adam Martinson <amartinson@codeweavers.com>
Date: Mon, 23 May 2011 15:19:50 -0500
Subject: [PATCH 05/11] wined3d/query: Add support for D3DQUERY_TIMESTAMPDISJOINT \
queries.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
dlls/wined3d/query.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 176 insertions(+), 0 deletions(-)
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index c0d5c63..a9ff6f4 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -273,6 +273,7 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
break;
case WINED3DQUERYTYPE_TIMESTAMP:
+ case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
{
struct wined3d_timestamp_query *tsq = query->extendedData;
@@ -496,6 +497,78 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct \
wined3d_query *query, return res;
}
+/* Only called when GL_ARB_timer_query is supported. */
+static HRESULT wined3d_timestampdisjoint_query_ops_get_data(struct wined3d_query \
*query, + void *data, \
DWORD size, DWORD flags) +{
+ const struct wined3d_gl_info *gl_info = &query->device->adapter->gl_info;
+ struct wined3d_timestamp_query *timestamp_query = query->extendedData;
+ struct wined3d_context *context;
+ BOOL *disjoint = data;
+ GLuint available;
+ UINT64 time_start, time_end, time_elapsed;
+ HRESULT res;
+
+ TRACE("(%p) : type D3DQUERY_TIMESTAMPDISJOINT, data %p, size %#x, flags %#x.\n", \
query, data, size, flags); +
+ if (!timestamp_query->context)
+ query->state = QUERY_CREATED;
+
+ if (query->state != QUERY_SIGNALLED)
+ {
+ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the \
data ourselves */ + TRACE("Query wasn't yet started, returning S_OK\n");
+ if (disjoint)
+ *disjoint = TRUE;
+
+ return S_OK;
+ }
+
+ if (timestamp_query->context->tid != GetCurrentThreadId())
+ {
+ FIXME("%p Wrong thread, setting data to TRUE.\n", query);
+ if (disjoint)
+ *disjoint = TRUE;
+
+ return S_OK;
+ }
+
+ context = context_acquire(query->device, timestamp_query->context->current_rt);
+
+ ENTER_GL();
+
+ GL_EXTCALL(glGetQueryObjectuivARB(timestamp_query->ids[2], \
GL_QUERY_RESULT_AVAILABLE_ARB, &available)); + \
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)"); + \
TRACE("available %#x.\n", available); +
+ if (available)
+ {
+ if (disjoint)
+ {
+ GL_EXTCALL(glGetQueryObjectui64v(timestamp_query->ids[0], \
GL_QUERY_RESULT_ARB, &time_start)); + \
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)"); + \
GL_EXTCALL(glGetQueryObjectui64v(timestamp_query->ids[1], GL_QUERY_RESULT_ARB, \
&time_end)); + checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
+ GL_EXTCALL(glGetQueryObjectui64v(timestamp_query->ids[2], \
GL_QUERY_RESULT_ARB, &time_elapsed)); + \
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)"); +
+ *disjoint = ((time_start >= time_end) || ((time_end - time_start) > \
time_elapsed)); + }
+
+ res = S_OK;
+ }
+ else
+ {
+ res = S_FALSE;
+ }
+
+ LEAVE_GL();
+
+ context_release(context);
+
+ return res;
+}
+
WINED3DQUERYTYPE CDECL wined3d_query_get_type(const struct wined3d_query *query)
{
TRACE("query %p.\n", query);
@@ -652,6 +725,83 @@ static HRESULT wined3d_timestamp_query_ops_issue(struct \
wined3d_query *query, DW return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
}
+/* Only called when GL_ARB_timer_query is supported. */
+static HRESULT wined3d_timestampdisjoint_query_ops_issue(struct wined3d_query \
*query, DWORD flags) +{
+ const struct wined3d_gl_info *gl_info = &query->device->adapter->gl_info;
+ struct wined3d_timestamp_query *timestamp_query = query->extendedData;
+ struct wined3d_context *context;
+
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ if (flags & WINED3DISSUE_BEGIN)
+ {
+ if (query->state == QUERY_BUILDING)
+ {
+ if (timestamp_query->context->tid != GetCurrentThreadId())
+ {
+ FIXME("Wrong thread, can't restart query.\n");
+
+ context_free_timestamp_query(timestamp_query);
+ context = context_acquire(query->device, NULL);
+ context_alloc_timestamp_query(context, timestamp_query);
+ }
+ else
+ {
+ context = context_acquire(query->device, \
timestamp_query->context->current_rt); +
+ ENTER_GL();
+ GL_EXTCALL(glEndQueryARB(GL_TIME_ELAPSED_ARB));
+ checkGLcall("glEndQuery(GL_TIME_ELAPSED)");
+ LEAVE_GL();
+ }
+ }
+ else
+ {
+ if (timestamp_query->context) \
context_free_timestamp_query(timestamp_query); + context = \
context_acquire(query->device, NULL); + \
context_alloc_timestamp_query(context, timestamp_query); + }
+
+ ENTER_GL();
+ GL_EXTCALL(glBeginQueryARB(GL_TIME_ELAPSED_ARB, timestamp_query->ids[2]));
+ checkGLcall("glBeginQuery(GL_TIME_ELAPSED)");
+ GL_EXTCALL(glQueryCounter(timestamp_query->ids[0], GL_TIMESTAMP_ARB));
+ checkGLcall("glQueryCounter(GL_TIMESTAMP)");
+ LEAVE_GL();
+
+ context_release(context);
+ query->state = QUERY_BUILDING;
+ }
+ if (flags & WINED3DISSUE_END)
+ {
+ if (query->state == QUERY_BUILDING)
+ {
+ if (timestamp_query->context->tid != GetCurrentThreadId())
+ {
+ FIXME("Wrong thread, can't end query.\n");
+ }
+ else
+ {
+ context = context_acquire(query->device, \
timestamp_query->context->current_rt); +
+ ENTER_GL();
+ GL_EXTCALL(glQueryCounter(timestamp_query->ids[1], \
GL_TIMESTAMP_ARB)); + checkGLcall("glQueryCounter(GL_TIMESTAMP)");
+ GL_EXTCALL(glEndQueryARB(GL_TIME_ELAPSED_ARB));
+ checkGLcall("glEndQuery(GL_TIME_ELAPSED)");
+ LEAVE_GL();
+
+ context_release(context);
+ }
+ }
+
+ query->state = QUERY_SIGNALLED;
+ }
+
+ return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
+}
+
static const struct wined3d_query_ops event_query_ops =
{
wined3d_event_query_ops_get_data,
@@ -670,6 +820,12 @@ static const struct wined3d_query_ops timestamp_query_ops =
wined3d_timestamp_query_ops_issue,
};
+static const struct wined3d_query_ops timestampdisjoint_query_ops =
+{
+ wined3d_timestampdisjoint_query_ops_get_data,
+ wined3d_timestampdisjoint_query_ops_issue,
+};
+
static HRESULT query_init(struct wined3d_query *query, struct wined3d_device \
*device, WINED3DQUERYTYPE type) {
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@@ -736,6 +892,26 @@ static HRESULT query_init(struct wined3d_query *query, struct \
wined3d_device *de break;
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
+ TRACE("Timestampdisjoint query.\n");
+ if (!gl_info->supported[ARB_TIMER_QUERY])
+ {
+ WARN("GL_ARB_timer_query not supported, returning \
WINED3DERR_NOTAVAILABLE.\n"); + return WINED3DERR_NOTAVAILABLE;
+ }
+
+ query->data_size = sizeof(BOOL);
+ query->query_ops = ×tampdisjoint_query_ops;
+ query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, \
sizeof(struct wined3d_timestamp_query)); + if (!query->extendedData)
+ {
+ ERR("Failed to allocate event query memory.\n");
+ return E_OUTOFMEMORY;
+ }
+ ((struct wined3d_timestamp_query *)query->extendedData)->n_ids = 3;
+ ((struct wined3d_timestamp_query *)query->extendedData)->context = NULL;
+
+ break;
+
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
--
1.7.1
["0006-wined3d-query-Add-support-for-D3DQUERY_TIMESTAMPFREQ.patch" (text/x-patch)]
From 939258fd556764e38362015304b1d67d4b5abb1a Mon Sep 17 00:00:00 2001
From: Adam Martinson <amartinson@codeweavers.com>
Date: Mon, 23 May 2011 14:53:32 -0500
Subject: [PATCH 06/11] wined3d/query: Add support for D3DQUERY_TIMESTAMPFREQ queries.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
dlls/wined3d/query.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
include/wine/wined3d.h | 2 ++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index a9ff6f4..9688d49 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -569,6 +569,22 @@ static HRESULT \
wined3d_timestampdisjoint_query_ops_get_data(struct wined3d_query return res;
}
+/* Only called when GL_ARB_timer_query is supported. */
+static HRESULT wined3d_timestampfreq_query_ops_get_data(struct wined3d_query *query,
+ void *data, DWORD size, \
DWORD flags) +{
+ UINT64 *freq = data;
+
+ TRACE("(%p) : type D3DQUERY_TIMESTAMPFREQ, data %p, size %#x, flags %#x.\n", \
query, data, size, flags); +
+ /* We never go to the QUERY_BUILDING state for this. */
+
+ if (freq)
+ *freq = WINED3DQUERY_TIMESTAMP_FREQ;
+
+ return S_OK;
+}
+
WINED3DQUERYTYPE CDECL wined3d_query_get_type(const struct wined3d_query *query)
{
TRACE("query %p.\n", query);
@@ -802,6 +818,17 @@ static HRESULT wined3d_timestampdisjoint_query_ops_issue(struct \
wined3d_query *q return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
}
+/* Only called when GL_ARB_timer_query is supported. */
+static HRESULT wined3d_timestampfreq_query_ops_issue(struct wined3d_query *query, \
DWORD flags) +{
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ /* MSDN: WINED3DISSUE_BEGIN not supported */
+
+ query->state = QUERY_SIGNALLED;
+ return WINED3D_OK;
+}
+
static const struct wined3d_query_ops event_query_ops =
{
wined3d_event_query_ops_get_data,
@@ -826,6 +853,12 @@ static const struct wined3d_query_ops \
timestampdisjoint_query_ops = wined3d_timestampdisjoint_query_ops_issue,
};
+static const struct wined3d_query_ops timestampfreq_query_ops =
+{
+ wined3d_timestampfreq_query_ops_get_data,
+ wined3d_timestampfreq_query_ops_issue,
+};
+
static HRESULT query_init(struct wined3d_query *query, struct wined3d_device \
*device, WINED3DQUERYTYPE type) {
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@@ -913,6 +946,18 @@ static HRESULT query_init(struct wined3d_query *query, struct \
wined3d_device *de break;
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
+ TRACE("Timestamp Freqency query.\n");
+ if (!gl_info->supported[ARB_TIMER_QUERY])
+ {
+ WARN("GL_ARB_timer_query not supported, returning \
WINED3DERR_NOTAVAILABLE.\n"); + return WINED3DERR_NOTAVAILABLE;
+ }
+
+ query->data_size = sizeof(UINT64);
+ query->query_ops = ×tampfreq_query_ops;
+ query->extendedData = NULL;
+ break;
+
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
case WINED3DQUERYTYPE_VERTEXSTATS:
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index ed269f0..96dcacd 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -740,6 +740,8 @@ typedef enum _WINED3DQUERYTYPE
#define WINED3DISSUE_END (1 << 0)
#define WINED3DGETDATA_FLUSH (1 << 0)
+#define WINED3DQUERY_TIMESTAMP_FREQ 1000000000 /* \
nanoseconds */ +
typedef enum _WINED3DSTATEBLOCKTYPE
{
WINED3DSBT_INIT = 0,
--
1.7.1
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic