wined3d: Subclass queries.
This commit is contained in:
parent
6dee6819b2
commit
071d4afb2b
|
@ -1143,11 +1143,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
IWineD3DQueryImpl *object; /*NOTE: impl ref allowed since this is a create function */
|
IWineD3DQueryImpl *object; /*NOTE: impl ref allowed since this is a create function */
|
||||||
HRESULT hr = WINED3DERR_NOTAVAILABLE;
|
HRESULT hr = WINED3DERR_NOTAVAILABLE;
|
||||||
|
const IWineD3DQueryVtbl *vtable;
|
||||||
|
|
||||||
/* Just a check to see if we support this type of query */
|
/* Just a check to see if we support this type of query */
|
||||||
switch(Type) {
|
switch(Type) {
|
||||||
case WINED3DQUERYTYPE_OCCLUSION:
|
case WINED3DQUERYTYPE_OCCLUSION:
|
||||||
TRACE("(%p) occlusion query\n", This);
|
TRACE("(%p) occlusion query\n", This);
|
||||||
|
/* Use the base Query vtable until we have a occlusion query one */
|
||||||
|
vtable = &IWineD3DQuery_Vtbl;
|
||||||
if (GL_SUPPORT(ARB_OCCLUSION_QUERY))
|
if (GL_SUPPORT(ARB_OCCLUSION_QUERY))
|
||||||
hr = WINED3D_OK;
|
hr = WINED3D_OK;
|
||||||
else
|
else
|
||||||
|
@ -1161,6 +1164,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
|
||||||
*/
|
*/
|
||||||
FIXME("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
|
FIXME("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
|
||||||
}
|
}
|
||||||
|
vtable = &IWineD3DEventQuery_Vtbl;
|
||||||
hr = WINED3D_OK;
|
hr = WINED3D_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1177,6 +1181,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
|
||||||
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
|
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
|
||||||
case WINED3DQUERYTYPE_CACHEUTILIZATION:
|
case WINED3DQUERYTYPE_CACHEUTILIZATION:
|
||||||
default:
|
default:
|
||||||
|
/* Use the base Query vtable until we have a special one for each query */
|
||||||
|
vtable = &IWineD3DQuery_Vtbl;
|
||||||
FIXME("(%p) Unhandled query type %d\n", This, Type);
|
FIXME("(%p) Unhandled query type %d\n", This, Type);
|
||||||
}
|
}
|
||||||
if(NULL == ppQuery || hr != WINED3D_OK) {
|
if(NULL == ppQuery || hr != WINED3D_OK) {
|
||||||
|
@ -1184,6 +1190,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DCREATEOBJECTINSTANCE(object, Query)
|
D3DCREATEOBJECTINSTANCE(object, Query)
|
||||||
|
object->lpVtbl = vtable;
|
||||||
object->type = Type;
|
object->type = Type;
|
||||||
object->state = QUERY_CREATED;
|
object->state = QUERY_CREATED;
|
||||||
/* allocated the 'extended' data based on the type of query requested */
|
/* allocated the 'extended' data based on the type of query requested */
|
||||||
|
|
|
@ -158,28 +158,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_EVENT:
|
|
||||||
{
|
|
||||||
BOOL* data = pData;
|
|
||||||
WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
|
|
||||||
if(pData == NULL || dwSize == 0) {
|
|
||||||
break;
|
|
||||||
} if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
|
|
||||||
/* See comment in IWineD3DQuery::Issue, event query codeblock */
|
|
||||||
WARN("Query context not active, reporting GPU idle\n");
|
|
||||||
*data = TRUE;
|
|
||||||
} else if(GL_SUPPORT(APPLE_FENCE)) {
|
|
||||||
*data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
|
|
||||||
checkGLcall("glTestFenceAPPLE");
|
|
||||||
} else if(GL_SUPPORT(NV_FENCE)) {
|
|
||||||
*data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
|
|
||||||
checkGLcall("glTestFenceNV");
|
|
||||||
} else {
|
|
||||||
WARN("(%p): reporting GPU idle\n", This);
|
|
||||||
*data = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WINED3DQUERYTYPE_OCCLUSION:
|
case WINED3DQUERYTYPE_OCCLUSION:
|
||||||
{
|
{
|
||||||
DWORD* data = pData;
|
DWORD* data = pData;
|
||||||
|
@ -329,6 +307,32 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
return res; /* S_OK if the query data is available*/
|
return res; /* S_OK if the query data is available*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
|
||||||
|
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
|
||||||
|
BOOL* data = pData;
|
||||||
|
WineD3DContext *ctx;
|
||||||
|
TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
|
||||||
|
|
||||||
|
ctx = ((WineQueryEventData *)This->extendedData)->ctx;
|
||||||
|
if(pData == NULL || dwSize == 0) {
|
||||||
|
return S_OK;
|
||||||
|
} if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
|
||||||
|
/* See comment in IWineD3DQuery::Issue, event query codeblock */
|
||||||
|
WARN("Query context not active, reporting GPU idle\n");
|
||||||
|
*data = TRUE;
|
||||||
|
} else if(GL_SUPPORT(APPLE_FENCE)) {
|
||||||
|
*data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
|
||||||
|
checkGLcall("glTestFenceAPPLE");
|
||||||
|
} else if(GL_SUPPORT(NV_FENCE)) {
|
||||||
|
*data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
|
||||||
|
checkGLcall("glTestFenceNV");
|
||||||
|
} else {
|
||||||
|
WARN("(%p): reporting GPU idle\n", This);
|
||||||
|
*data = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
||||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||||
|
@ -384,6 +388,11 @@ static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
||||||
return dataSize;
|
return dataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
||||||
|
TRACE("(%p) : type D3DQUERY_EVENT\n", iface);
|
||||||
|
|
||||||
|
return sizeof(BOOL);
|
||||||
|
}
|
||||||
|
|
||||||
static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
|
static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
|
||||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||||
|
@ -391,6 +400,42 @@ static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags) {
|
||||||
|
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p) : dwIssueFlags %#x, type D3DQUERY_EVENT\n", This, dwIssueFlags);
|
||||||
|
if (dwIssueFlags & WINED3DISSUE_END) {
|
||||||
|
WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
|
||||||
|
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
|
||||||
|
/* GL fences can be used only from the context that created them,
|
||||||
|
* so if a different context is active, don't bother setting the query. The penalty
|
||||||
|
* of a context switch is most likely higher than the gain of a correct query result
|
||||||
|
*
|
||||||
|
* If the query is used from a different thread, don't bother creating a multithread
|
||||||
|
* context - there's no point in doing that as the query would be unusable anyway
|
||||||
|
*/
|
||||||
|
WARN("Query context not active\n");
|
||||||
|
} else if(GL_SUPPORT(APPLE_FENCE)) {
|
||||||
|
GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
|
||||||
|
checkGLcall("glSetFenceAPPLE");
|
||||||
|
} else if (GL_SUPPORT(NV_FENCE)) {
|
||||||
|
GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
|
||||||
|
checkGLcall("glSetFenceNV");
|
||||||
|
}
|
||||||
|
} else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
|
||||||
|
/* Started implicitly at device creation */
|
||||||
|
ERR("Event query issued with START flag - what to do?\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dwIssueFlags & WINED3DISSUE_BEGIN) {
|
||||||
|
This->state = QUERY_BUILDING;
|
||||||
|
} else {
|
||||||
|
This->state = QUERY_SIGNALLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WINED3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags){
|
static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags){
|
||||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||||
|
|
||||||
|
@ -430,31 +475,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINED3DQUERYTYPE_EVENT: {
|
|
||||||
if (dwIssueFlags & WINED3DISSUE_END) {
|
|
||||||
WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
|
|
||||||
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
|
|
||||||
/* GL fences can be used only from the context that created them,
|
|
||||||
* so if a different context is active, don't bother setting the query. The penalty
|
|
||||||
* of a context switch is most likely higher than the gain of a correct query result
|
|
||||||
*
|
|
||||||
* If the query is used from a different thread, don't bother creating a multithread
|
|
||||||
* context - there's no point in doing that as the query would be unusable anyway
|
|
||||||
*/
|
|
||||||
WARN("Query context not active\n");
|
|
||||||
} else if(GL_SUPPORT(APPLE_FENCE)) {
|
|
||||||
GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
|
|
||||||
checkGLcall("glSetFenceAPPLE");
|
|
||||||
} else if (GL_SUPPORT(NV_FENCE)) {
|
|
||||||
GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
|
|
||||||
checkGLcall("glSetFenceNV");
|
|
||||||
}
|
|
||||||
} else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
|
|
||||||
/* Started implicitly at device creation */
|
|
||||||
ERR("Event query issued with START flag - what to do?\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* The fixme is printed when the app asks for the resulting data */
|
/* The fixme is printed when the app asks for the resulting data */
|
||||||
WARN("(%p) : Unhandled query type %#x\n", This, This->type);
|
WARN("(%p) : Unhandled query type %#x\n", This, This->type);
|
||||||
|
@ -489,3 +509,18 @@ const IWineD3DQueryVtbl IWineD3DQuery_Vtbl =
|
||||||
IWineD3DQueryImpl_GetType,
|
IWineD3DQueryImpl_GetType,
|
||||||
IWineD3DQueryImpl_Issue
|
IWineD3DQueryImpl_Issue
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
|
||||||
|
{
|
||||||
|
/*** IUnknown methods ***/
|
||||||
|
IWineD3DQueryImpl_QueryInterface,
|
||||||
|
IWineD3DQueryImpl_AddRef,
|
||||||
|
IWineD3DQueryImpl_Release,
|
||||||
|
/*** IWineD3Dquery methods ***/
|
||||||
|
IWineD3DQueryImpl_GetParent,
|
||||||
|
IWineD3DQueryImpl_GetDevice,
|
||||||
|
IWineD3DEventQueryImpl_GetData,
|
||||||
|
IWineD3DEventQueryImpl_GetDataSize,
|
||||||
|
IWineD3DQueryImpl_GetType,
|
||||||
|
IWineD3DEventQueryImpl_Issue
|
||||||
|
};
|
||||||
|
|
|
@ -1571,6 +1571,7 @@ typedef struct IWineD3DQueryImpl
|
||||||
} IWineD3DQueryImpl;
|
} IWineD3DQueryImpl;
|
||||||
|
|
||||||
extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
|
extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
|
||||||
|
extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl;
|
||||||
|
|
||||||
/* Datastructures for IWineD3DQueryImpl.extendedData */
|
/* Datastructures for IWineD3DQueryImpl.extendedData */
|
||||||
typedef struct WineQueryOcclusionData {
|
typedef struct WineQueryOcclusionData {
|
||||||
|
|
Loading…
Reference in New Issue