wined3d: Give occlusion queries their own vtable.

This commit is contained in:
Stefan Dösinger 2008-02-28 21:03:41 +01:00 committed by Alexandre Julliard
parent 071d4afb2b
commit 32be503c62
3 changed files with 113 additions and 86 deletions

View File

@ -1149,12 +1149,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
switch(Type) {
case WINED3DQUERYTYPE_OCCLUSION:
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))
hr = WINED3D_OK;
else
WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY/NV_OCCLUSION_QUERY\n");
vtable = &IWineD3DOcclusionQuery_Vtbl;
break;
case WINED3DQUERYTYPE_EVENT:

View File

@ -158,48 +158,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
}
break;
case WINED3DQUERYTYPE_OCCLUSION:
{
DWORD* data = pData;
if(This->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");
res = S_OK;
if(data) *data = 0;
} else if(This->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");
res = S_FALSE;
} else if (GL_SUPPORT(ARB_OCCLUSION_QUERY) &&
((WineQueryOcclusionData *)This->extendedData)->ctx == This->wineD3DDevice->activeContext &&
This->wineD3DDevice->activeContext->tid == GetCurrentThreadId()) {
GLuint available;
GLuint samples;
GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
TRACE("(%p) : available %d.\n", This, available);
if (available) {
if(data) {
GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
TRACE("(%p) : Returning %d samples.\n", This, samples);
*data = samples;
}
res = S_OK;
} else {
res = S_FALSE;
}
} else {
WARN("(%p) : Occlusion queries not supported, or wrong context. Returning 1.\n", This);
*data = 1;
res = S_OK;
}
}
break;
case WINED3DQUERYTYPE_TIMESTAMP:
{
UINT64* data = pData;
@ -307,6 +265,51 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
return res; /* S_OK if the query data is available*/
}
static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
DWORD* data = pData;
HRESULT res;
TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
if(This->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");
res = S_OK;
if(data) *data = 0;
} else if(This->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");
res = S_FALSE;
} else if (GL_SUPPORT(ARB_OCCLUSION_QUERY) &&
((WineQueryOcclusionData *)This->extendedData)->ctx == This->wineD3DDevice->activeContext &&
This->wineD3DDevice->activeContext->tid == GetCurrentThreadId()) {
GLuint available;
GLuint samples;
GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
TRACE("(%p) : available %d.\n", This, available);
if (available) {
if(data) {
GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
TRACE("(%p) : Returning %d samples.\n", This, samples);
*data = samples;
}
res = S_OK;
} else {
res = S_FALSE;
}
} else {
WARN("(%p) : Occlusion queries not supported, or wrong context. Returning 1.\n", This);
*data = 1;
res = S_OK;
}
return res;
}
static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
BOOL* data = pData;
@ -351,9 +354,6 @@ static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){
case WINED3DQUERYTYPE_EVENT:
dataSize = sizeof(BOOL);
break;
case WINED3DQUERYTYPE_OCCLUSION:
dataSize = sizeof(DWORD);
break;
case WINED3DQUERYTYPE_TIMESTAMP:
dataSize = sizeof(UINT64);
break;
@ -394,6 +394,12 @@ static DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* 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;
@ -436,50 +442,55 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
WARN("Not the owning context, can't start query\n");
} else {
/* This is allowed according to msdn and our tests. Reset the query and restart */
if (dwIssueFlags & WINED3DISSUE_BEGIN) {
if(This->state == QUERY_BUILDING) {
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
checkGLcall("glEndQuery()");
}
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, ((WineQueryOcclusionData *)This->extendedData)->queryId));
checkGLcall("glBeginQuery()");
}
if (dwIssueFlags & WINED3DISSUE_END) {
/* Msdn says _END on a non-building occlusion query returns an error, but
* our tests show that it returns OK. But OpenGL doesn't like it, so avoid
* generating an error
*/
if(This->state == QUERY_BUILDING) {
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
checkGLcall("glEndQuery()");
}
}
}
} else {
FIXME("(%p) : Occlusion queries not supported\n", This);
}
if(dwIssueFlags & WINED3DISSUE_BEGIN) {
This->state = QUERY_BUILDING;
} else {
This->state = QUERY_SIGNALLED;
}
return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
}
static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags){
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
TRACE("(%p) : dwIssueFlags %#x, type %#x\n", This, dwIssueFlags, This->type);
switch (This->type) {
case WINED3DQUERYTYPE_OCCLUSION:
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
WARN("Not the owning context, can't start query\n");
} else {
/* This is allowed according to msdn and our tests. Reset the query and restart */
if (dwIssueFlags & WINED3DISSUE_BEGIN) {
if(This->state == QUERY_BUILDING) {
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
checkGLcall("glEndQuery()");
}
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, ((WineQueryOcclusionData *)This->extendedData)->queryId));
checkGLcall("glBeginQuery()");
}
if (dwIssueFlags & WINED3DISSUE_END) {
/* Msdn says _END on a non-building occlusion query returns an error, but
* our tests show that it returns OK. But OpenGL doesn't like it, so avoid
* generating an error
*/
if(This->state == QUERY_BUILDING) {
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
checkGLcall("glEndQuery()");
}
}
}
} else {
FIXME("(%p) : Occlusion queries not supported\n", This);
}
break;
default:
/* The fixme is printed when the app asks for the resulting data */
WARN("(%p) : Unhandled query type %#x\n", This, This->type);
break;
}
/* The fixme is printed when the app asks for the resulting data */
WARN("(%p) : Unhandled query type %#x\n", This, This->type);
if(dwIssueFlags & WINED3DISSUE_BEGIN) {
This->state = QUERY_BUILDING;
@ -524,3 +535,18 @@ const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
IWineD3DQueryImpl_GetType,
IWineD3DEventQueryImpl_Issue
};
const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
{
/*** IUnknown methods ***/
IWineD3DQueryImpl_QueryInterface,
IWineD3DQueryImpl_AddRef,
IWineD3DQueryImpl_Release,
/*** IWineD3Dquery methods ***/
IWineD3DQueryImpl_GetParent,
IWineD3DQueryImpl_GetDevice,
IWineD3DOcclusionQueryImpl_GetData,
IWineD3DOcclusionQueryImpl_GetDataSize,
IWineD3DQueryImpl_GetType,
IWineD3DOcclusionQueryImpl_Issue
};

View File

@ -1572,6 +1572,7 @@ typedef struct IWineD3DQueryImpl
extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl;
extern const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl;
/* Datastructures for IWineD3DQueryImpl.extendedData */
typedef struct WineQueryOcclusionData {