mirror of
https://github.com/reactos/wine.git
synced 2025-01-23 12:25:17 +00:00
wined3d: A more detailed occlusion query test and fixes.
This commit is contained in:
parent
54fa712981
commit
0e8c13e630
@ -135,6 +135,117 @@ static void test_query_support(IDirect3D9 *pD3d, HWND hwnd)
|
||||
if(pDevice) IDirect3DDevice9_Release(pDevice);
|
||||
}
|
||||
|
||||
static void test_occlusion_query_states(IDirect3D9 *pD3d, HWND hwnd)
|
||||
{
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
IDirect3DDevice9 *pDevice = NULL;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
D3DDISPLAYMODE d3ddm;
|
||||
IDirect3DQuery9 *pQuery = NULL;
|
||||
BYTE *data = NULL;
|
||||
float point[3] = {0.0, 0.0, 0.0};
|
||||
unsigned int count = 0;
|
||||
|
||||
IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
|
||||
ZeroMemory( &d3dpp, sizeof(d3dpp) );
|
||||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.BackBufferFormat = d3ddm.Format;
|
||||
|
||||
hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
|
||||
ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to create a d3d device\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_CreateQuery(pDevice, D3DQUERYTYPE_OCCLUSION, &pQuery);
|
||||
ok(hr == D3D_OK || D3DERR_NOTAVAILABLE,
|
||||
"IDirect3DDevice9_CreateQuery returned unexpected return value %s\n", DXGetErrorString9(hr));
|
||||
if(!pQuery) {
|
||||
skip("Occlusion queries not supported\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
data = HeapAlloc(GetProcessHeap(), 0, IDirect3DQuery9_GetDataSize(pQuery));
|
||||
|
||||
hr = IDirect3DQuery9_GetData(pQuery, NULL, 0, D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "IDirect3DQuery9_GetData(NULL) on a new query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
hr = IDirect3DQuery9_GetData(pQuery, data, IDirect3DQuery9_GetDataSize(pQuery), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "IDirect3DQuery9_GetData on a new query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_END);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DISSUE_END) on a new not yet started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_BEGIN);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DISSUE_BEGIN) on a new not yet started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_BEGIN);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DQUERY_BEGIN) on a started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DQuery9_GetData(pQuery, NULL, 0, D3DGETDATA_FLUSH);
|
||||
ok(hr == S_FALSE, "IDirect3DQuery9_GetData(NULL) on a started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
hr = IDirect3DQuery9_GetData(pQuery, data, IDirect3DQuery9_GetDataSize(pQuery), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_FALSE, "IDirect3DQuery9_GetData on a started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DDevice9_SetFVF(pDevice, D3DFVF_XYZ);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_BeginScene(pDevice);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
|
||||
if(SUCCEEDED(hr)) {
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(pDevice, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %s\n", DXGetErrorString9(hr));
|
||||
hr = IDirect3DDevice9_EndScene(pDevice);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
|
||||
}
|
||||
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_END);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DISSUE_END) on a started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = S_FALSE;
|
||||
while(hr == S_FALSE && count < 500) {
|
||||
hr = IDirect3DQuery9_GetData(pQuery, NULL, 0, D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK || hr == S_FALSE, "IDirect3DQuery9_GetData on a ended query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
count++;
|
||||
if(hr == S_FALSE) Sleep(10);
|
||||
}
|
||||
ok(hr == S_OK, "Occlusion query did not finish\n");
|
||||
|
||||
hr = IDirect3DQuery9_GetData(pQuery, data, IDirect3DQuery9_GetDataSize(pQuery), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "IDirect3DQuery9_GetData on a ended query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
hr = IDirect3DQuery9_GetData(pQuery, data, IDirect3DQuery9_GetDataSize(pQuery), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "IDirect3DQuery9_GetData a 2nd time on a ended query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_BEGIN);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DISSUE_BEGIN) on a new not yet started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_END);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DISSUE_END) on a started query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
hr = IDirect3DQuery9_Issue(pQuery, D3DISSUE_END);
|
||||
ok(hr == D3D_OK, "IDirect3DQuery9_Issue(D3DISSUE_END) on a ended query returned %s\n",
|
||||
DXGetErrorString9(hr));
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
if(pDevice) IDirect3DDevice9_Release(pDevice);
|
||||
}
|
||||
|
||||
START_TEST(query)
|
||||
{
|
||||
HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
|
||||
@ -166,6 +277,7 @@ START_TEST(query)
|
||||
}
|
||||
|
||||
test_query_support(pD3d, hwnd);
|
||||
test_occlusion_query_states(pD3d, hwnd);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
IDirect3D9_Release(pD3d);
|
||||
|
@ -1259,6 +1259,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
|
||||
|
||||
D3DCREATEOBJECTINSTANCE(object, Query)
|
||||
object->type = Type;
|
||||
object->state = QUERY_CREATED;
|
||||
/* allocated the 'extended' data based on the type of query requested */
|
||||
switch(Type){
|
||||
case WINED3DQUERYTYPE_OCCLUSION:
|
||||
|
@ -111,13 +111,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
|
||||
TRACE("(%p) : type %#x, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, This->type, pData, dwSize, dwGetDataFlags);
|
||||
|
||||
if(dwSize == 0){
|
||||
/*you can use this method to poll the resource for the query status*/
|
||||
/*We return success(S_OK) if we support a feature, and faikure(S_FALSE) if we don't, just return success and fluff it for now*/
|
||||
return S_OK;
|
||||
}else{
|
||||
}
|
||||
|
||||
switch (This->type){
|
||||
|
||||
case WINED3DQUERYTYPE_VCACHE:
|
||||
@ -125,6 +118,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
|
||||
WINED3DDEVINFO_VCACHE *data = (WINED3DDEVINFO_VCACHE *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->Pattern = WINEMAKEFOURCC('C','A','C','H');
|
||||
data->OptMethod = 0; /*0 get longest strips, 1 optimize vertex cache*/
|
||||
data->CacheSize = 0; /*cache size, only required if OptMethod == 1*/
|
||||
@ -137,6 +131,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
WINED3DDEVINFO_RESOURCEMANAGER *data = (WINED3DDEVINFO_RESOURCEMANAGER *)pData;
|
||||
int i;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
for(i = 0; i < WINED3DRTYPECOUNT; i++){
|
||||
/*I'm setting the default values to 1 so as to reduce the risk of a div/0 in the caller*/
|
||||
/* isTextureResident could be used to get some of this infomration */
|
||||
@ -159,6 +154,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
{
|
||||
WINED3DDEVINFO_VERTEXSTATS *data = (WINED3DDEVINFO_VERTEXSTATS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->NumRenderedTriangles = 1;
|
||||
data->NumExtraClippingTriangles = 1;
|
||||
|
||||
@ -168,7 +164,9 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
{
|
||||
BOOL* data = pData;
|
||||
WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
|
||||
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
|
||||
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;
|
||||
@ -187,7 +185,17 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
case WINED3DQUERYTYPE_OCCLUSION:
|
||||
{
|
||||
DWORD* data = pData;
|
||||
if (GL_SUPPORT(ARB_OCCLUSION_QUERY) &&
|
||||
|
||||
if(This->state == QUERY_CREATED) {
|
||||
/* D3D allows GetData on a new query, opengl doesn't. So just invent the data outselves */
|
||||
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;
|
||||
@ -199,10 +207,12 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
TRACE("(%p) : available %d.\n", This, available);
|
||||
|
||||
if (available) {
|
||||
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;
|
||||
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;
|
||||
@ -218,6 +228,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
{
|
||||
UINT64* data = pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMP\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
*data = 1; /*Don't know what this is supposed to be*/
|
||||
}
|
||||
break;
|
||||
@ -225,6 +236,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
{
|
||||
BOOL* data = pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMPDISJOINT\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
*data = FALSE; /*Don't know what this is supposed to be*/
|
||||
}
|
||||
break;
|
||||
@ -232,6 +244,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
{
|
||||
UINT64* data = pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMPFREQ\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
*data = 1; /*Don't know what this is supposed to be*/
|
||||
}
|
||||
break;
|
||||
@ -239,6 +252,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
{
|
||||
WINED3DDEVINFO_PIPELINETIMINGS *data = (WINED3DDEVINFO_PIPELINETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
|
||||
data->VertexProcessingTimePercent = 1.0f;
|
||||
data->PixelProcessingTimePercent = 1.0f;
|
||||
@ -251,6 +265,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
WINED3DDEVINFO_INTERFACETIMINGS *data = (WINED3DDEVINFO_INTERFACETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
|
||||
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->WaitingForGPUToUseApplicationResourceTimePercent = 1.0f;
|
||||
data->WaitingForGPUToAcceptMoreCommandsTimePercent = 1.0f;
|
||||
data->WaitingForGPUToStayWithinLatencyTimePercent = 1.0f;
|
||||
@ -264,6 +279,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
|
||||
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->MemoryProcessingPercent = 50.0f;
|
||||
data->ComputationProcessingPercent = 50.0f;
|
||||
|
||||
@ -274,6 +290,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
|
||||
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->MemoryProcessingPercent = 50.0f;
|
||||
data->ComputationProcessingPercent = 50.0f;
|
||||
}
|
||||
@ -283,6 +300,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
WINED3DDEVINFO_BANDWIDTHTIMINGS *data = (WINED3DDEVINFO_BANDWIDTHTIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
|
||||
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->MaxBandwidthUtilized = 1.0f;
|
||||
data->FrontEndUploadMemoryUtilizedPercent = 1.0f;
|
||||
data->VertexRateUtilizedPercent = 1.0f;
|
||||
@ -295,6 +313,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||
WINED3DDEVINFO_CACHEUTILIZATION *data = (WINED3DDEVINFO_CACHEUTILIZATION *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
|
||||
|
||||
if(pData == NULL || dwSize == 0) break;
|
||||
data->TextureCacheHitRate = 1.0f;
|
||||
data->PostTransformVertexCacheHitRate = 1.0f;
|
||||
}
|
||||
@ -387,13 +406,25 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
|
||||
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) {
|
||||
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
|
||||
checkGLcall("glEndQuery()");
|
||||
/* 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 {
|
||||
@ -432,6 +463,12 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
|
||||
break;
|
||||
}
|
||||
|
||||
if(dwIssueFlags & WINED3DISSUE_BEGIN) {
|
||||
This->state = QUERY_BUILDING;
|
||||
} else {
|
||||
This->state = QUERY_SIGNALLED;
|
||||
}
|
||||
|
||||
return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
|
||||
}
|
||||
|
||||
|
@ -1443,6 +1443,15 @@ extern void stateblock_copy(
|
||||
|
||||
extern const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl;
|
||||
|
||||
/* Direct3D terminology with little modifications. We do not have an issued state
|
||||
* because only the driver knows about it, but we have a created state because d3d
|
||||
* allows GetData on a created issue, but opengl doesn't
|
||||
*/
|
||||
enum query_state {
|
||||
QUERY_CREATED,
|
||||
QUERY_SIGNALLED,
|
||||
QUERY_BUILDING
|
||||
};
|
||||
/*****************************************************************************
|
||||
* IWineD3DQueryImpl implementation structure (extends IUnknown)
|
||||
*/
|
||||
@ -1460,6 +1469,7 @@ typedef struct IWineD3DQueryImpl
|
||||
#endif
|
||||
|
||||
/* IWineD3DQuery fields */
|
||||
enum query_state state;
|
||||
WINED3DQUERYTYPE type;
|
||||
/* TODO: Think about using a IUnknown instead of a void* */
|
||||
void *extendedData;
|
||||
|
Loading…
x
Reference in New Issue
Block a user