mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 03:08:42 +00:00
wined3d: Use an internal call table for query operations.
This commit is contained in:
parent
b59dc811e2
commit
831a29d250
2 changed files with 113 additions and 82 deletions
|
@ -284,12 +284,40 @@ static ULONG WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
|
|||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery *iface,
|
||||
void *data, DWORD data_size, DWORD flags)
|
||||
{
|
||||
struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface;
|
||||
|
||||
TRACE("iface %p, data %p, data_size %u, flags %#x.\n",
|
||||
iface, data, data_size, flags);
|
||||
|
||||
return query->query_ops->query_get_data(query, data, data_size, flags);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery *iface)
|
||||
{
|
||||
struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface;
|
||||
|
||||
TRACE("iface %p.\n", iface);
|
||||
|
||||
return query->data_size;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery *iface, DWORD flags)
|
||||
{
|
||||
struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface;
|
||||
|
||||
TRACE("iface %p, flags %#x.\n", iface, flags);
|
||||
|
||||
return query->query_ops->query_issue(query, flags);
|
||||
}
|
||||
|
||||
static HRESULT wined3d_occlusion_query_ops_get_data(struct IWineD3DQueryImpl *query,
|
||||
void *pData, DWORD dwSize, DWORD flags)
|
||||
{
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
|
||||
struct wined3d_occlusion_query *query = This->extendedData;
|
||||
IWineD3DDeviceImpl *device = This->device;
|
||||
struct wined3d_occlusion_query *oq = query->extendedData;
|
||||
IWineD3DDeviceImpl *device = query->device;
|
||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
struct wined3d_context *context;
|
||||
DWORD* data = pData;
|
||||
|
@ -297,11 +325,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
|
|||
GLuint samples;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", This, pData, dwSize, flags);
|
||||
TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
|
||||
|
||||
if (!query->context) This->state = QUERY_CREATED;
|
||||
if (!oq->context)
|
||||
query->state = QUERY_CREATED;
|
||||
|
||||
if (This->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");
|
||||
|
@ -309,7 +338,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if (This->state == QUERY_BUILDING)
|
||||
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");
|
||||
|
@ -318,33 +347,33 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
|
|||
|
||||
if (!gl_info->supported[ARB_OCCLUSION_QUERY])
|
||||
{
|
||||
WARN("(%p) : Occlusion queries not supported. Returning 1.\n", This);
|
||||
WARN("%p Occlusion queries not supported. Returning 1.\n", query);
|
||||
*data = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (query->context->tid != GetCurrentThreadId())
|
||||
if (oq->context->tid != GetCurrentThreadId())
|
||||
{
|
||||
FIXME("%p Wrong thread, returning 1.\n", This);
|
||||
FIXME("%p Wrong thread, returning 1.\n", query);
|
||||
*data = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
context = context_acquire(This->device, query->context->current_rt);
|
||||
context = context_acquire(query->device, oq->context->current_rt);
|
||||
|
||||
ENTER_GL();
|
||||
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
|
||||
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
|
||||
TRACE("(%p) : available %d.\n", This, available);
|
||||
TRACE("available %#x.\n", available);
|
||||
|
||||
if (available)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_ARB, &samples));
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples));
|
||||
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
|
||||
TRACE("(%p) : Returning %d samples.\n", This, samples);
|
||||
TRACE("Returning %d samples.\n", samples);
|
||||
*data = samples;
|
||||
}
|
||||
res = S_OK;
|
||||
|
@ -361,25 +390,24 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
|
|||
return res;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface,
|
||||
static HRESULT wined3d_event_query_ops_get_data(IWineD3DQueryImpl *query,
|
||||
void *pData, DWORD dwSize, DWORD flags)
|
||||
{
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
|
||||
struct wined3d_event_query *query = This->extendedData;
|
||||
struct wined3d_event_query *event_query = query->extendedData;
|
||||
BOOL *data = pData;
|
||||
enum wined3d_event_query_result ret;
|
||||
|
||||
TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, flags %#x.\n", This, pData, dwSize, flags);
|
||||
TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
|
||||
|
||||
if (!pData || !dwSize) return S_OK;
|
||||
if (!query)
|
||||
if (!event_query)
|
||||
{
|
||||
WARN("(%p): Event query not supported by GL, reporting GPU idle\n", This);
|
||||
WARN("Event query not supported by GL, reporting GPU idle.\n");
|
||||
*data = TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ret = wined3d_event_query_test(query, This->device);
|
||||
ret = wined3d_event_query_test(event_query, query->device);
|
||||
switch(ret)
|
||||
{
|
||||
case WINED3D_EVENT_QUERY_OK:
|
||||
|
@ -392,7 +420,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface,
|
|||
break;
|
||||
|
||||
case WINED3D_EVENT_QUERY_WRONG_THREAD:
|
||||
FIXME("(%p) Wrong thread, reporting GPU idle.\n", This);
|
||||
FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
|
||||
*data = TRUE;
|
||||
break;
|
||||
|
||||
|
@ -404,36 +432,24 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
||||
TRACE("(%p) : type D3DQUERY_EVENT\n", iface);
|
||||
|
||||
return sizeof(BOOL);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DOcclusionQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
||||
TRACE("(%p) : type D3DQUERY_OCCLUSION\n", iface);
|
||||
|
||||
return sizeof(DWORD);
|
||||
}
|
||||
|
||||
static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
return This->type;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD flags)
|
||||
static HRESULT wined3d_event_query_ops_issue(struct IWineD3DQueryImpl *query, DWORD flags)
|
||||
{
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
TRACE("query %p, flags %#x.\n", query, flags);
|
||||
|
||||
TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", This, flags);
|
||||
TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", query, flags);
|
||||
if (flags & WINED3DISSUE_END)
|
||||
{
|
||||
struct wined3d_event_query *query = This->extendedData;
|
||||
struct wined3d_event_query *event_query = query->extendedData;
|
||||
|
||||
/* Faked event query support */
|
||||
if (!query) return WINED3D_OK;
|
||||
if (!event_query) return WINED3D_OK;
|
||||
|
||||
wined3d_event_query_issue(query, This->device);
|
||||
wined3d_event_query_issue(event_query, query->device);
|
||||
}
|
||||
else if (flags & WINED3DISSUE_BEGIN)
|
||||
{
|
||||
|
@ -442,40 +458,41 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD f
|
|||
}
|
||||
|
||||
if (flags & WINED3DISSUE_BEGIN)
|
||||
This->state = QUERY_BUILDING;
|
||||
query->state = QUERY_BUILDING;
|
||||
else
|
||||
This->state = QUERY_SIGNALLED;
|
||||
query->state = QUERY_SIGNALLED;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWORD flags)
|
||||
static HRESULT wined3d_occlusion_query_ops_issue(struct IWineD3DQueryImpl *query, DWORD flags)
|
||||
{
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
IWineD3DDeviceImpl *device = This->device;
|
||||
IWineD3DDeviceImpl *device = query->device;
|
||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
|
||||
TRACE("query %p, flags %#x.\n", query, flags);
|
||||
|
||||
if (gl_info->supported[ARB_OCCLUSION_QUERY])
|
||||
{
|
||||
struct wined3d_occlusion_query *query = This->extendedData;
|
||||
struct wined3d_occlusion_query *oq = query->extendedData;
|
||||
struct wined3d_context *context;
|
||||
|
||||
/* This is allowed according to msdn and our tests. Reset the query and restart */
|
||||
if (flags & WINED3DISSUE_BEGIN)
|
||||
{
|
||||
if (This->state == QUERY_BUILDING)
|
||||
if (query->state == QUERY_BUILDING)
|
||||
{
|
||||
if (query->context->tid != GetCurrentThreadId())
|
||||
if (oq->context->tid != GetCurrentThreadId())
|
||||
{
|
||||
FIXME("Wrong thread, can't restart query.\n");
|
||||
|
||||
context_free_occlusion_query(query);
|
||||
context = context_acquire(This->device, NULL);
|
||||
context_alloc_occlusion_query(context, query);
|
||||
context_free_occlusion_query(oq);
|
||||
context = context_acquire(query->device, NULL);
|
||||
context_alloc_occlusion_query(context, oq);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(This->device, query->context->current_rt);
|
||||
context = context_acquire(query->device, oq->context->current_rt);
|
||||
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
|
||||
|
@ -485,13 +502,13 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO
|
|||
}
|
||||
else
|
||||
{
|
||||
if (query->context) context_free_occlusion_query(query);
|
||||
context = context_acquire(This->device, NULL);
|
||||
context_alloc_occlusion_query(context, query);
|
||||
if (oq->context) context_free_occlusion_query(oq);
|
||||
context = context_acquire(query->device, NULL);
|
||||
context_alloc_occlusion_query(context, oq);
|
||||
}
|
||||
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id));
|
||||
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id));
|
||||
checkGLcall("glBeginQuery()");
|
||||
LEAVE_GL();
|
||||
|
||||
|
@ -503,15 +520,15 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO
|
|||
* our tests show that it returns OK. But OpenGL doesn't like it, so avoid
|
||||
* generating an error
|
||||
*/
|
||||
if (This->state == QUERY_BUILDING)
|
||||
if (query->state == QUERY_BUILDING)
|
||||
{
|
||||
if (query->context->tid != GetCurrentThreadId())
|
||||
if (oq->context->tid != GetCurrentThreadId())
|
||||
{
|
||||
FIXME("Wrong thread, can't end query.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(This->device, query->context->current_rt);
|
||||
context = context_acquire(query->device, oq->context->current_rt);
|
||||
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
|
||||
|
@ -522,42 +539,43 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FIXME("(%p) : Occlusion queries not supported\n", This);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("%p Occlusion queries not supported.\n", query);
|
||||
}
|
||||
|
||||
if (flags & WINED3DISSUE_BEGIN)
|
||||
This->state = QUERY_BUILDING;
|
||||
query->state = QUERY_BUILDING;
|
||||
else
|
||||
This->state = QUERY_SIGNALLED;
|
||||
query->state = QUERY_SIGNALLED;
|
||||
|
||||
return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
|
||||
}
|
||||
|
||||
static const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
|
||||
static const struct wined3d_query_ops event_query_ops =
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
IWineD3DQueryImpl_QueryInterface,
|
||||
IWineD3DQueryImpl_AddRef,
|
||||
IWineD3DQueryImpl_Release,
|
||||
/*** IWineD3Dquery methods ***/
|
||||
IWineD3DEventQueryImpl_GetData,
|
||||
IWineD3DEventQueryImpl_GetDataSize,
|
||||
IWineD3DQueryImpl_GetType,
|
||||
IWineD3DEventQueryImpl_Issue
|
||||
wined3d_event_query_ops_get_data,
|
||||
wined3d_event_query_ops_issue,
|
||||
};
|
||||
|
||||
static const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
|
||||
static const struct wined3d_query_ops occlusion_query_ops =
|
||||
{
|
||||
wined3d_occlusion_query_ops_get_data,
|
||||
wined3d_occlusion_query_ops_issue,
|
||||
};
|
||||
|
||||
static const struct IWineD3DQueryVtbl IWineD3DQuery_Vtbl =
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
IWineD3DQueryImpl_QueryInterface,
|
||||
IWineD3DQueryImpl_AddRef,
|
||||
IWineD3DQueryImpl_Release,
|
||||
/*** IWineD3Dquery methods ***/
|
||||
IWineD3DOcclusionQueryImpl_GetData,
|
||||
IWineD3DOcclusionQueryImpl_GetDataSize,
|
||||
IWineD3DQueryImpl_GetData,
|
||||
IWineD3DQueryImpl_GetDataSize,
|
||||
IWineD3DQueryImpl_GetType,
|
||||
IWineD3DOcclusionQueryImpl_Issue
|
||||
IWineD3DQueryImpl_Issue,
|
||||
};
|
||||
|
||||
HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3DQUERYTYPE type)
|
||||
|
@ -573,7 +591,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D
|
|||
WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n");
|
||||
return WINED3DERR_NOTAVAILABLE;
|
||||
}
|
||||
query->lpVtbl = &IWineD3DOcclusionQuery_Vtbl;
|
||||
query->query_ops = &occlusion_query_ops;
|
||||
query->data_size = sizeof(DWORD);
|
||||
query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
|
||||
if (!query->extendedData)
|
||||
{
|
||||
|
@ -593,7 +612,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D
|
|||
* lowering performance. */
|
||||
FIXME("Event query: Unimplemented, but pretending to be supported.\n");
|
||||
}
|
||||
query->lpVtbl = &IWineD3DEventQuery_Vtbl;
|
||||
query->query_ops = &event_query_ops;
|
||||
query->data_size = sizeof(BOOL);
|
||||
query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query));
|
||||
if (!query->extendedData)
|
||||
{
|
||||
|
@ -619,6 +639,7 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D
|
|||
return WINED3DERR_NOTAVAILABLE;
|
||||
}
|
||||
|
||||
query->lpVtbl = &IWineD3DQuery_Vtbl;
|
||||
query->type = type;
|
||||
query->state = QUERY_CREATED;
|
||||
query->device = device;
|
||||
|
|
|
@ -2467,6 +2467,15 @@ enum query_state {
|
|||
QUERY_SIGNALLED,
|
||||
QUERY_BUILDING
|
||||
};
|
||||
|
||||
struct IWineD3DQueryImpl;
|
||||
|
||||
struct wined3d_query_ops
|
||||
{
|
||||
HRESULT (*query_get_data)(struct IWineD3DQueryImpl *query, void *data, DWORD data_size, DWORD flags);
|
||||
HRESULT (*query_issue)(struct IWineD3DQueryImpl *query, DWORD flags);
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* IWineD3DQueryImpl implementation structure (extends IUnknown)
|
||||
*/
|
||||
|
@ -2475,12 +2484,13 @@ typedef struct IWineD3DQueryImpl
|
|||
const IWineD3DQueryVtbl *lpVtbl;
|
||||
LONG ref; /* Note: Ref counting not required */
|
||||
|
||||
const struct wined3d_query_ops *query_ops;
|
||||
IWineD3DDeviceImpl *device;
|
||||
|
||||
/* IWineD3DQuery fields */
|
||||
enum query_state state;
|
||||
WINED3DQUERYTYPE type;
|
||||
/* TODO: Think about using a IUnknown instead of a void* */
|
||||
DWORD data_size;
|
||||
void *extendedData;
|
||||
} IWineD3DQueryImpl;
|
||||
|
||||
|
|
Loading…
Reference in a new issue