Commit 70889d68 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Unify the query get_data() implementations.

parent 2337c50e
...@@ -26,13 +26,15 @@ ...@@ -26,13 +26,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DEFAULT_DEBUG_CHANNEL(d3d);
static void wined3d_query_init(struct wined3d_query *query, struct wined3d_device *device, static void wined3d_query_init(struct wined3d_query *query, struct wined3d_device *device,
enum wined3d_query_type type, DWORD data_size, const struct wined3d_query_ops *query_ops, void *parent) enum wined3d_query_type type, const void *data, DWORD data_size,
const struct wined3d_query_ops *query_ops, void *parent)
{ {
query->ref = 1; query->ref = 1;
query->parent = parent; query->parent = parent;
query->device = device; query->device = device;
query->state = QUERY_CREATED; query->state = QUERY_CREATED;
query->type = type; query->type = type;
query->data = data;
query->data_size = data_size; query->data_size = data_size;
query->query_ops = query_ops; query->query_ops = query_ops;
} }
...@@ -317,7 +319,24 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, ...@@ -317,7 +319,24 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query,
TRACE("query %p, data %p, data_size %u, flags %#x.\n", TRACE("query %p, data %p, data_size %u, flags %#x.\n",
query, data, data_size, flags); query, data, data_size, flags);
return query->query_ops->query_get_data(query, data, data_size, flags); if (flags)
WARN("Ignoring flags %#x.\n", flags);
if (query->state == QUERY_BUILDING)
{
WARN("Query is building, returning S_FALSE.\n");
return S_FALSE;
}
if (query->state == QUERY_CREATED)
WARN("Query wasn't started yet.\n");
else if (!query->query_ops->query_poll(query))
return S_FALSE;
if (data)
memcpy(data, query->data, min(data_size, query->data_size));
return S_OK;
} }
UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query) UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query)
...@@ -334,52 +353,25 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) ...@@ -334,52 +353,25 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags)
return query->query_ops->query_issue(query, flags); return query->query_ops->query_issue(query, flags);
} }
static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size) static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query)
{
memcpy(out, result, min(out_size, result_size));
}
static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
void *data, DWORD size, DWORD flags)
{ {
struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query);
struct wined3d_device *device = query->device; struct wined3d_device *device = query->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_gl_info *gl_info;
struct wined3d_context *context; struct wined3d_context *context;
GLuint available; GLuint available;
GLuint samples;
HRESULT res;
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
if (!oq->context) TRACE("query %p.\n", query);
query->state = QUERY_CREATED;
if (query->state == QUERY_CREATED)
{
/* 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");
samples = 0;
fill_query_data(data, size, &samples, sizeof(samples));
return S_OK;
}
if (query->state == QUERY_BUILDING)
{
/* Msdn says this returns an error, but our tests show that S_FALSE is returned */
TRACE("Query is building, returning S_FALSE\n");
return S_FALSE;
}
if (oq->context->tid != GetCurrentThreadId()) if (oq->context->tid != GetCurrentThreadId())
{ {
FIXME("%p Wrong thread, returning 1.\n", query); FIXME("%p Wrong thread, returning 1.\n", query);
samples = 1; oq->samples = 1;
fill_query_data(data, size, &samples, sizeof(samples)); return TRUE;
return S_OK;
} }
context = context_acquire(device, context_get_rt_surface(oq->context)); context = context_acquire(device, context_get_rt_surface(oq->context));
gl_info = context->gl_info;
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available)); GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
...@@ -387,63 +379,45 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, ...@@ -387,63 +379,45 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
if (available) if (available)
{ {
if (size) GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &oq->samples));
{
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)");
TRACE("Returning %d samples.\n", samples); TRACE("Returning %u samples.\n", oq->samples);
fill_query_data(data, size, &samples, sizeof(samples));
}
res = S_OK;
}
else
{
res = S_FALSE;
} }
context_release(context); context_release(context);
return res; return available;
} }
static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query)
void *data, DWORD size, DWORD flags)
{ {
struct wined3d_event_query *event_query = wined3d_event_query_from_query(query); struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
enum wined3d_event_query_result ret; enum wined3d_event_query_result ret;
BOOL signaled;
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
if (!data || !size) TRACE("query %p.\n", query);
return S_OK;
ret = wined3d_event_query_test(event_query, query->device); ret = wined3d_event_query_test(event_query, query->device);
switch(ret) switch (ret)
{ {
case WINED3D_EVENT_QUERY_OK: case WINED3D_EVENT_QUERY_OK:
case WINED3D_EVENT_QUERY_NOT_STARTED: case WINED3D_EVENT_QUERY_NOT_STARTED:
signaled = TRUE; return event_query->signalled = TRUE;
fill_query_data(data, size, &signaled, sizeof(signaled));
break;
case WINED3D_EVENT_QUERY_WAITING: case WINED3D_EVENT_QUERY_WAITING:
signaled = FALSE; return event_query->signalled = FALSE;
fill_query_data(data, size, &signaled, sizeof(signaled));
break;
case WINED3D_EVENT_QUERY_WRONG_THREAD: case WINED3D_EVENT_QUERY_WRONG_THREAD:
FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
signaled = TRUE; return event_query->signalled = TRUE;
fill_query_data(data, size, &signaled, sizeof(signaled));
break;
case WINED3D_EVENT_QUERY_ERROR: case WINED3D_EVENT_QUERY_ERROR:
ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); ERR("The GL event query failed.\n");
return WINED3DERR_INVALIDCALL; return event_query->signalled = TRUE;
}
return S_OK; default:
ERR("Unexpected wined3d_event_query_test result %#x.\n", ret);
return event_query->signalled = TRUE;
}
} }
void * CDECL wined3d_query_get_parent(const struct wined3d_query *query) void * CDECL wined3d_query_get_parent(const struct wined3d_query *query)
...@@ -559,40 +533,26 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW ...@@ -559,40 +533,26 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
} }
static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query)
void *data, DWORD size, DWORD flags)
{ {
struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query);
struct wined3d_device *device = query->device; struct wined3d_device *device = query->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_gl_info *gl_info;
struct wined3d_context *context; struct wined3d_context *context;
GLuint available;
GLuint64 timestamp; GLuint64 timestamp;
HRESULT res; GLuint available;
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
if (!tq->context)
query->state = QUERY_CREATED;
if (query->state == QUERY_CREATED) TRACE("query %p.\n", query);
{
/* 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");
timestamp = 0;
fill_query_data(data, size, &timestamp, sizeof(timestamp));
return S_OK;
}
if (tq->context->tid != GetCurrentThreadId()) if (tq->context->tid != GetCurrentThreadId())
{ {
FIXME("%p Wrong thread, returning 1.\n", query); FIXME("%p Wrong thread, returning 1.\n", query);
timestamp = 1; tq->timestamp = 1;
fill_query_data(data, size, &timestamp, sizeof(timestamp)); return TRUE;
return S_OK;
} }
context = context_acquire(device, context_get_rt_surface(tq->context)); context = context_acquire(device, context_get_rt_surface(tq->context));
gl_info = context->gl_info;
GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
...@@ -600,23 +560,15 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, ...@@ -600,23 +560,15 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
if (available) if (available)
{ {
if (size)
{
GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, &timestamp)); GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, &timestamp));
checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)");
TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp));
fill_query_data(data, size, &timestamp, sizeof(timestamp)); tq->timestamp = timestamp;
}
res = S_OK;
}
else
{
res = S_FALSE;
} }
context_release(context); context_release(context);
return res; return available;
} }
static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags)
...@@ -648,30 +600,11 @@ static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DW ...@@ -648,30 +600,11 @@ static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DW
return WINED3D_OK; return WINED3D_OK;
} }
static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query)
void *data, DWORD size, DWORD flags)
{ {
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); TRACE("query %p.\n", query);
if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
{
static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE};
if (query->state == QUERY_BUILDING)
{
TRACE("Query is building, returning S_FALSE.\n");
return S_FALSE;
}
fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data));
}
else
{
static const UINT64 freq = 1000 * 1000 * 1000;
fill_query_data(data, size, &freq, sizeof(freq)); return TRUE;
}
return S_OK;
} }
static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags)
...@@ -688,7 +621,7 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query * ...@@ -688,7 +621,7 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *
static const struct wined3d_query_ops event_query_ops = static const struct wined3d_query_ops event_query_ops =
{ {
wined3d_event_query_ops_get_data, wined3d_event_query_ops_poll,
wined3d_event_query_ops_issue, wined3d_event_query_ops_issue,
}; };
...@@ -709,7 +642,8 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device, ...@@ -709,7 +642,8 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, sizeof(BOOL), &event_query_ops, parent); wined3d_query_init(&object->query, device, type, &object->signalled,
sizeof(object->signalled), &event_query_ops, parent);
TRACE("Created query %p.\n", object); TRACE("Created query %p.\n", object);
*query = &object->query; *query = &object->query;
...@@ -719,7 +653,7 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device, ...@@ -719,7 +653,7 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
static const struct wined3d_query_ops occlusion_query_ops = static const struct wined3d_query_ops occlusion_query_ops =
{ {
wined3d_occlusion_query_ops_get_data, wined3d_occlusion_query_ops_poll,
wined3d_occlusion_query_ops_issue, wined3d_occlusion_query_ops_issue,
}; };
...@@ -740,7 +674,8 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device, ...@@ -740,7 +674,8 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, sizeof(DWORD), &occlusion_query_ops, parent); wined3d_query_init(&object->query, device, type, &object->samples,
sizeof(object->samples), &occlusion_query_ops, parent);
TRACE("Created query %p.\n", object); TRACE("Created query %p.\n", object);
*query = &object->query; *query = &object->query;
...@@ -750,7 +685,7 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device, ...@@ -750,7 +685,7 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
static const struct wined3d_query_ops timestamp_query_ops = static const struct wined3d_query_ops timestamp_query_ops =
{ {
wined3d_timestamp_query_ops_get_data, wined3d_timestamp_query_ops_poll,
wined3d_timestamp_query_ops_issue, wined3d_timestamp_query_ops_issue,
}; };
...@@ -771,7 +706,8 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device, ...@@ -771,7 +706,8 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, sizeof(UINT64), &timestamp_query_ops, parent); wined3d_query_init(&object->query, device, type, &object->timestamp,
sizeof(object->timestamp), &timestamp_query_ops, parent);
TRACE("Created query %p.\n", object); TRACE("Created query %p.\n", object);
*query = &object->query; *query = &object->query;
...@@ -781,7 +717,7 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device, ...@@ -781,7 +717,7 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
static const struct wined3d_query_ops timestamp_disjoint_query_ops = static const struct wined3d_query_ops timestamp_disjoint_query_ops =
{ {
wined3d_timestamp_disjoint_query_ops_get_data, wined3d_timestamp_disjoint_query_ops_poll,
wined3d_timestamp_disjoint_query_ops_issue, wined3d_timestamp_disjoint_query_ops_issue,
}; };
...@@ -803,10 +739,19 @@ static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *de ...@@ -803,10 +739,19 @@ static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *de
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if (type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) if (type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
wined3d_query_init(object, device, type, {
sizeof(struct wined3d_query_data_timestamp_disjoint), &timestamp_disjoint_query_ops, parent); static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE};
wined3d_query_init(object, device, type, &disjoint_data,
sizeof(disjoint_data), &timestamp_disjoint_query_ops, parent);
}
else else
wined3d_query_init(object, device, type, sizeof(UINT64), &timestamp_disjoint_query_ops, parent); {
static const UINT64 freq = 1000 * 1000 * 1000;
wined3d_query_init(object, device, type, &freq,
sizeof(freq), &timestamp_disjoint_query_ops, parent);
}
TRACE("Created query %p.\n", object); TRACE("Created query %p.\n", object);
*query = object; *query = object;
......
...@@ -1379,7 +1379,7 @@ enum wined3d_query_state ...@@ -1379,7 +1379,7 @@ enum wined3d_query_state
struct wined3d_query_ops struct wined3d_query_ops
{ {
HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); BOOL (*query_poll)(struct wined3d_query *query);
HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags); HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags);
}; };
...@@ -1391,6 +1391,7 @@ struct wined3d_query ...@@ -1391,6 +1391,7 @@ struct wined3d_query
struct wined3d_device *device; struct wined3d_device *device;
enum wined3d_query_state state; enum wined3d_query_state state;
enum wined3d_query_type type; enum wined3d_query_type type;
const void *data;
DWORD data_size; DWORD data_size;
const struct wined3d_query_ops *query_ops; const struct wined3d_query_ops *query_ops;
}; };
...@@ -1408,6 +1409,7 @@ struct wined3d_event_query ...@@ -1408,6 +1409,7 @@ struct wined3d_event_query
struct list entry; struct list entry;
union wined3d_gl_query_object object; union wined3d_gl_query_object object;
struct wined3d_context *context; struct wined3d_context *context;
BOOL signalled;
}; };
enum wined3d_event_query_result enum wined3d_event_query_result
...@@ -1432,6 +1434,7 @@ struct wined3d_occlusion_query ...@@ -1432,6 +1434,7 @@ struct wined3d_occlusion_query
struct list entry; struct list entry;
GLuint id; GLuint id;
struct wined3d_context *context; struct wined3d_context *context;
DWORD samples;
}; };
struct wined3d_timestamp_query struct wined3d_timestamp_query
...@@ -1441,6 +1444,7 @@ struct wined3d_timestamp_query ...@@ -1441,6 +1444,7 @@ struct wined3d_timestamp_query
struct list entry; struct list entry;
GLuint id; GLuint id;
struct wined3d_context *context; struct wined3d_context *context;
UINT64 timestamp;
}; };
void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment