wined3d: Remove unused GetDevice() implementations.
[wine] / dlls / wined3d / query.c
1 /*
2  * IWineD3DQuery implementation
3  *
4  * Copyright 2005 Oliver Stieber
5  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
6  * Copyright 2009 Henri Verbeet for CodeWeavers.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23
24 #include "config.h"
25 #include "wined3d_private.h"
26
27 /*
28  * Occlusion Queries:
29  * http://www.gris.uni-tuebingen.de/~bartz/Publications/paper/hww98.pdf
30  * http://oss.sgi.com/projects/ogl-sample/registry/ARB/occlusion_query.txt
31  */
32
33 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
34 #define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
35
36 /* *******************************************
37    IWineD3DQuery IUnknown parts follow
38    ******************************************* */
39 static HRESULT  WINAPI IWineD3DQueryImpl_QueryInterface(IWineD3DQuery *iface, REFIID riid, LPVOID *ppobj)
40 {
41     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
42     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
43     if (IsEqualGUID(riid, &IID_IUnknown)
44         || IsEqualGUID(riid, &IID_IWineD3DBase)
45         || IsEqualGUID(riid, &IID_IWineD3DQuery)) {
46         IUnknown_AddRef(iface);
47         *ppobj = This;
48         return S_OK;
49     }
50     *ppobj = NULL;
51     return E_NOINTERFACE;
52 }
53
54 static ULONG  WINAPI IWineD3DQueryImpl_AddRef(IWineD3DQuery *iface) {
55     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
56     TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
57     return InterlockedIncrement(&This->ref);
58 }
59
60 static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
61     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
62     ULONG ref;
63     TRACE("(%p) : Releasing from %d\n", This, This->ref);
64     ref = InterlockedDecrement(&This->ref);
65     if (ref == 0) {
66         /* Queries are specific to the GL context that created them. Not
67          * deleting the query will obviously leak it, but that's still better
68          * than potentially deleting a different query with the same id in this
69          * context, and (still) leaking the actual query. */
70         if (This->type == WINED3DQUERYTYPE_EVENT)
71         {
72             struct wined3d_event_query *query = This->extendedData;
73
74             if (query->context) context_free_event_query(query);
75         }
76         else if (This->type == WINED3DQUERYTYPE_OCCLUSION)
77         {
78             struct wined3d_occlusion_query *query = This->extendedData;
79
80             if (query->context) context_free_occlusion_query(query);
81         }
82
83         HeapFree(GetProcessHeap(), 0, This->extendedData);
84         HeapFree(GetProcessHeap(), 0, This);
85     }
86     return ref;
87 }
88
89 /* *******************************************
90    IWineD3DQuery IWineD3DQuery parts follow
91    ******************************************* */
92 static HRESULT  WINAPI IWineD3DQueryImpl_GetParent(IWineD3DQuery *iface, IUnknown** parent){
93     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
94
95     *parent= (IUnknown*) parent;
96     IUnknown_AddRef(*parent);
97     TRACE("(%p) : returning %p\n", This, *parent);
98     return WINED3D_OK;
99 }
100
101 static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags){
102     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
103     HRESULT res = S_OK;
104
105     TRACE("(%p) : type %#x, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, This->type, pData, dwSize, dwGetDataFlags);
106
107     switch (This->type){
108
109     case WINED3DQUERYTYPE_VCACHE:
110     {
111
112         WINED3DDEVINFO_VCACHE *data = pData;
113         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
114         if(pData == NULL || dwSize == 0) break;
115         data->Pattern     = WINEMAKEFOURCC('C','A','C','H');
116         data->OptMethod   = 0; /*0 get longest strips, 1 optimize vertex cache*/
117         data->CacheSize   = 0; /*cache size, only required if OptMethod == 1*/
118         data->MagicNumber = 0; /*only required if OptMethod == 1 (used internally)*/
119
120     }
121     break;
122     case WINED3DQUERYTYPE_RESOURCEMANAGER:
123     {
124         WINED3DDEVINFO_RESOURCEMANAGER *data = pData;
125         int i;
126         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
127         if(pData == NULL || dwSize == 0) break;
128         for(i = 0; i < WINED3DRTYPECOUNT; i++){
129             /*I'm setting the default values to 1 so as to reduce the risk of a div/0 in the caller*/
130             /*  isTextureResident could be used to get some of this information  */
131             data->stats[i].bThrashing            = FALSE;
132             data->stats[i].ApproxBytesDownloaded = 1;
133             data->stats[i].NumEvicts             = 1;
134             data->stats[i].NumVidCreates         = 1;
135             data->stats[i].LastPri               = 1;
136             data->stats[i].NumUsed               = 1;
137             data->stats[i].NumUsedInVidMem       = 1;
138             data->stats[i].WorkingSet            = 1;
139             data->stats[i].WorkingSetBytes       = 1;
140             data->stats[i].TotalManaged          = 1;
141             data->stats[i].TotalBytes            = 1;
142         }
143
144     }
145     break;
146     case WINED3DQUERYTYPE_VERTEXSTATS:
147     {
148         WINED3DDEVINFO_VERTEXSTATS *data = pData;
149         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
150         if(pData == NULL || dwSize == 0) break;
151         data->NumRenderedTriangles      = 1;
152         data->NumExtraClippingTriangles = 1;
153
154     }
155     break;
156     case WINED3DQUERYTYPE_TIMESTAMP:
157     {
158         UINT64* data = pData;
159         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMP\n", This);
160         if(pData == NULL || dwSize == 0) break;
161         *data = 1; /*Don't know what this is supposed to be*/
162     }
163     break;
164     case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
165     {
166         BOOL* data = pData;
167         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMPDISJOINT\n", This);
168         if(pData == NULL || dwSize == 0) break;
169         *data = FALSE; /*Don't know what this is supposed to be*/
170     }
171     break;
172     case WINED3DQUERYTYPE_TIMESTAMPFREQ:
173     {
174         UINT64* data = pData;
175         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMPFREQ\n", This);
176         if(pData == NULL || dwSize == 0) break;
177         *data = 1; /*Don't know what this is supposed to be*/
178     }
179     break;
180     case WINED3DQUERYTYPE_PIPELINETIMINGS:
181     {
182         WINED3DDEVINFO_PIPELINETIMINGS *data = pData;
183         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
184         if(pData == NULL || dwSize == 0) break;
185
186         data->VertexProcessingTimePercent    =   1.0f;
187         data->PixelProcessingTimePercent     =   1.0f;
188         data->OtherGPUProcessingTimePercent  =  97.0f;
189         data->GPUIdleTimePercent             =   1.0f;
190     }
191     break;
192     case WINED3DQUERYTYPE_INTERFACETIMINGS:
193     {
194         WINED3DDEVINFO_INTERFACETIMINGS *data = pData;
195         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
196
197         if(pData == NULL || dwSize == 0) break;
198         data->WaitingForGPUToUseApplicationResourceTimePercent =   1.0f;
199         data->WaitingForGPUToAcceptMoreCommandsTimePercent     =   1.0f;
200         data->WaitingForGPUToStayWithinLatencyTimePercent      =   1.0f;
201         data->WaitingForGPUExclusiveResourceTimePercent        =   1.0f;
202         data->WaitingForGPUOtherTimePercent                    =  96.0f;
203     }
204
205     break;
206     case WINED3DQUERYTYPE_VERTEXTIMINGS:
207     {
208         WINED3DDEVINFO_STAGETIMINGS *data = pData;
209         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
210
211         if(pData == NULL || dwSize == 0) break;
212         data->MemoryProcessingPercent      = 50.0f;
213         data->ComputationProcessingPercent = 50.0f;
214
215     }
216     break;
217     case WINED3DQUERYTYPE_PIXELTIMINGS:
218     {
219         WINED3DDEVINFO_STAGETIMINGS *data = pData;
220         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
221
222         if(pData == NULL || dwSize == 0) break;
223         data->MemoryProcessingPercent      = 50.0f;
224         data->ComputationProcessingPercent = 50.0f;
225     }
226     break;
227     case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
228     {
229         WINED3DDEVINFO_BANDWIDTHTIMINGS *data = pData;
230         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
231
232         if(pData == NULL || dwSize == 0) break;
233         data->MaxBandwidthUtilized                =  1.0f;
234         data->FrontEndUploadMemoryUtilizedPercent =  1.0f;
235         data->VertexRateUtilizedPercent           =  1.0f;
236         data->TriangleSetupRateUtilizedPercent    =  1.0f;
237         data->FillRateUtilizedPercent             = 97.0f;
238     }
239     break;
240     case WINED3DQUERYTYPE_CACHEUTILIZATION:
241     {
242         WINED3DDEVINFO_CACHEUTILIZATION *data = pData;
243         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
244
245         if(pData == NULL || dwSize == 0) break;
246         data->TextureCacheHitRate             = 1.0f;
247         data->PostTransformVertexCacheHitRate = 1.0f;
248     }
249
250
251     break;
252     default:
253         FIXME("(%p) Unhandled query type %d\n",This , This->type);
254
255     };
256
257     /*dwGetDataFlags = 0 || D3DGETDATA_FLUSH
258     D3DGETDATA_FLUSH may return WINED3DERR_DEVICELOST if the device is lost
259     */
260     return res; /* S_OK if the query data is available*/
261 }
262
263 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
264     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
265     struct wined3d_occlusion_query *query = This->extendedData;
266     IWineD3DDeviceImpl *device = This->wineD3DDevice;
267     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
268     struct wined3d_context *context;
269     DWORD* data = pData;
270     GLuint available;
271     GLuint samples;
272     HRESULT res;
273
274     TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
275
276     if (!query->context) This->state = QUERY_CREATED;
277
278     if (This->state == QUERY_CREATED)
279     {
280         /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
281         TRACE("Query wasn't yet started, returning S_OK\n");
282         if(data) *data = 0;
283         return S_OK;
284     }
285
286     if (This->state == QUERY_BUILDING)
287     {
288         /* Msdn says this returns an error, but our tests show that S_FALSE is returned */
289         TRACE("Query is building, returning S_FALSE\n");
290         return S_FALSE;
291     }
292
293     if (!gl_info->supported[ARB_OCCLUSION_QUERY])
294     {
295         WARN("(%p) : Occlusion queries not supported. Returning 1.\n", This);
296         *data = 1;
297         return S_OK;
298     }
299
300     if (query->context->tid != GetCurrentThreadId())
301     {
302         FIXME("%p Wrong thread, returning 1.\n", This);
303         *data = 1;
304         return S_OK;
305     }
306
307     context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
308
309     ENTER_GL();
310
311     GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
312     checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
313     TRACE("(%p) : available %d.\n", This, available);
314
315     if (available)
316     {
317         if (data)
318         {
319             GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_ARB, &samples));
320             checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
321             TRACE("(%p) : Returning %d samples.\n", This, samples);
322             *data = samples;
323         }
324         res = S_OK;
325     }
326     else
327     {
328         res = S_FALSE;
329     }
330
331     LEAVE_GL();
332
333     context_release(context);
334
335     return res;
336 }
337
338 static HRESULT  WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
339     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
340     struct wined3d_event_query *query = This->extendedData;
341     struct wined3d_context *context;
342     BOOL *data = pData;
343
344     TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
345
346     if (!pData || !dwSize) return S_OK;
347
348     if (!query->context)
349     {
350         ERR("Query not started, returning TRUE.\n");
351         *data = TRUE;
352
353         return S_OK;
354     }
355
356     if (query->context->tid != GetCurrentThreadId())
357     {
358         /* See comment in IWineD3DQuery::Issue, event query codeblock */
359         FIXME("Wrong thread, reporting GPU idle.\n");
360         *data = TRUE;
361
362         return S_OK;
363     }
364
365     context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
366
367     ENTER_GL();
368
369     if (context->gl_info->supported[APPLE_FENCE])
370     {
371         *data = GL_EXTCALL(glTestFenceAPPLE(query->id));
372         checkGLcall("glTestFenceAPPLE");
373     }
374     else if (context->gl_info->supported[NV_FENCE])
375     {
376         *data = GL_EXTCALL(glTestFenceNV(query->id));
377         checkGLcall("glTestFenceNV");
378     }
379     else
380     {
381         WARN("(%p): reporting GPU idle\n", This);
382         *data = TRUE;
383     }
384
385     LEAVE_GL();
386
387     context_release(context);
388
389     return S_OK;
390 }
391
392 static DWORD  WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){
393     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
394     int dataSize = 0;
395     TRACE("(%p) : type %#x\n", This, This->type);
396     switch(This->type){
397     case WINED3DQUERYTYPE_VCACHE:
398         dataSize = sizeof(WINED3DDEVINFO_VCACHE);
399         break;
400     case WINED3DQUERYTYPE_RESOURCEMANAGER:
401         dataSize = sizeof(WINED3DDEVINFO_RESOURCEMANAGER);
402         break;
403     case WINED3DQUERYTYPE_VERTEXSTATS:
404         dataSize = sizeof(WINED3DDEVINFO_VERTEXSTATS);
405         break;
406     case WINED3DQUERYTYPE_EVENT:
407         dataSize = sizeof(BOOL);
408         break;
409     case WINED3DQUERYTYPE_TIMESTAMP:
410         dataSize = sizeof(UINT64);
411         break;
412     case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
413         dataSize = sizeof(BOOL);
414         break;
415     case WINED3DQUERYTYPE_TIMESTAMPFREQ:
416         dataSize = sizeof(UINT64);
417         break;
418     case WINED3DQUERYTYPE_PIPELINETIMINGS:
419         dataSize = sizeof(WINED3DDEVINFO_PIPELINETIMINGS);
420         break;
421     case WINED3DQUERYTYPE_INTERFACETIMINGS:
422         dataSize = sizeof(WINED3DDEVINFO_INTERFACETIMINGS);
423         break;
424     case WINED3DQUERYTYPE_VERTEXTIMINGS:
425         dataSize = sizeof(WINED3DDEVINFO_STAGETIMINGS);
426         break;
427     case WINED3DQUERYTYPE_PIXELTIMINGS:
428         dataSize = sizeof(WINED3DDEVINFO_STAGETIMINGS);
429         break;
430     case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
431         dataSize = sizeof(WINED3DQUERYTYPE_BANDWIDTHTIMINGS);
432         break;
433     case WINED3DQUERYTYPE_CACHEUTILIZATION:
434         dataSize = sizeof(WINED3DDEVINFO_CACHEUTILIZATION);
435         break;
436     default:
437        FIXME("(%p) Unhandled query type %d\n",This , This->type);
438        dataSize = 0;
439     }
440     return dataSize;
441 }
442
443 static DWORD  WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){
444     TRACE("(%p) : type D3DQUERY_EVENT\n", iface);
445
446     return sizeof(BOOL);
447 }
448
449 static DWORD  WINAPI IWineD3DOcclusionQueryImpl_GetDataSize(IWineD3DQuery* iface){
450     TRACE("(%p) : type D3DQUERY_OCCLUSION\n", iface);
451
452     return sizeof(DWORD);
453 }
454
455 static WINED3DQUERYTYPE  WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
456     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
457     return This->type;
458 }
459
460
461 static HRESULT  WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIssueFlags) {
462     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
463
464     TRACE("(%p) : dwIssueFlags %#x, type D3DQUERY_EVENT\n", This, dwIssueFlags);
465     if (dwIssueFlags & WINED3DISSUE_END)
466     {
467         struct wined3d_event_query *query = This->extendedData;
468         struct wined3d_context *context;
469
470         if (query->context)
471         {
472             if (query->context->tid != GetCurrentThreadId())
473             {
474                 context_free_event_query(query);
475                 context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
476                 context_alloc_event_query(context, query);
477             }
478             else
479             {
480                 context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
481             }
482         }
483         else
484         {
485             context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
486             context_alloc_event_query(context, query);
487         }
488
489         ENTER_GL();
490
491         if (context->gl_info->supported[APPLE_FENCE])
492         {
493             GL_EXTCALL(glSetFenceAPPLE(query->id));
494             checkGLcall("glSetFenceAPPLE");
495         }
496         else if (context->gl_info->supported[NV_FENCE])
497         {
498             GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
499             checkGLcall("glSetFenceNV");
500         }
501
502         LEAVE_GL();
503
504         context_release(context);
505     }
506     else if(dwIssueFlags & WINED3DISSUE_BEGIN)
507     {
508         /* Started implicitly at device creation */
509         ERR("Event query issued with START flag - what to do?\n");
510     }
511
512     if(dwIssueFlags & WINED3DISSUE_BEGIN) {
513         This->state = QUERY_BUILDING;
514     } else {
515         This->state = QUERY_SIGNALLED;
516     }
517
518     return WINED3D_OK;
519 }
520
521 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIssueFlags) {
522     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
523     IWineD3DDeviceImpl *device = This->wineD3DDevice;
524     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
525
526     if (gl_info->supported[ARB_OCCLUSION_QUERY])
527     {
528         struct wined3d_occlusion_query *query = This->extendedData;
529         struct wined3d_context *context;
530
531         /* This is allowed according to msdn and our tests. Reset the query and restart */
532         if (dwIssueFlags & WINED3DISSUE_BEGIN)
533         {
534             if (This->state == QUERY_BUILDING)
535             {
536                 if (query->context->tid != GetCurrentThreadId())
537                 {
538                     FIXME("Wrong thread, can't restart query.\n");
539
540                     context_free_occlusion_query(query);
541                     context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
542                     context_alloc_occlusion_query(context, query);
543                 }
544                 else
545                 {
546                     context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
547
548                     ENTER_GL();
549                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
550                     checkGLcall("glEndQuery()");
551                     LEAVE_GL();
552                 }
553             }
554             else
555             {
556                 if (query->context) context_free_occlusion_query(query);
557                 context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
558                 context_alloc_occlusion_query(context, query);
559             }
560
561             ENTER_GL();
562             GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id));
563             checkGLcall("glBeginQuery()");
564             LEAVE_GL();
565
566             context_release(context);
567         }
568         if (dwIssueFlags & WINED3DISSUE_END) {
569             /* Msdn says _END on a non-building occlusion query returns an error, but
570              * our tests show that it returns OK. But OpenGL doesn't like it, so avoid
571              * generating an error
572              */
573             if (This->state == QUERY_BUILDING)
574             {
575                 if (query->context->tid != GetCurrentThreadId())
576                 {
577                     FIXME("Wrong thread, can't end query.\n");
578                 }
579                 else
580                 {
581                     context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
582
583                     ENTER_GL();
584                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
585                     checkGLcall("glEndQuery()");
586                     LEAVE_GL();
587
588                     context_release(context);
589                 }
590             }
591         }
592     } else {
593         FIXME("(%p) : Occlusion queries not supported\n", This);
594     }
595
596     if(dwIssueFlags & WINED3DISSUE_BEGIN) {
597         This->state = QUERY_BUILDING;
598     } else {
599         This->state = QUERY_SIGNALLED;
600     }
601     return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL.    */
602 }
603
604 static HRESULT  WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIssueFlags){
605     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
606
607     TRACE("(%p) : dwIssueFlags %#x, type %#x\n", This, dwIssueFlags, This->type);
608
609     /* The fixme is printed when the app asks for the resulting data */
610     WARN("(%p) : Unhandled query type %#x\n", This, This->type);
611
612     if(dwIssueFlags & WINED3DISSUE_BEGIN) {
613         This->state = QUERY_BUILDING;
614     } else {
615         This->state = QUERY_SIGNALLED;
616     }
617
618     return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL.    */
619 }
620
621
622 /**********************************************************
623  * IWineD3DQuery VTbl follows
624  **********************************************************/
625
626 const IWineD3DQueryVtbl IWineD3DQuery_Vtbl =
627 {
628     /*** IUnknown methods ***/
629     IWineD3DQueryImpl_QueryInterface,
630     IWineD3DQueryImpl_AddRef,
631     IWineD3DQueryImpl_Release,
632      /*** IWineD3Dquery methods ***/
633     IWineD3DQueryImpl_GetParent,
634     IWineD3DQueryImpl_GetData,
635     IWineD3DQueryImpl_GetDataSize,
636     IWineD3DQueryImpl_GetType,
637     IWineD3DQueryImpl_Issue
638 };
639
640 const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
641 {
642     /*** IUnknown methods ***/
643     IWineD3DQueryImpl_QueryInterface,
644     IWineD3DQueryImpl_AddRef,
645     IWineD3DQueryImpl_Release,
646     /*** IWineD3Dquery methods ***/
647     IWineD3DQueryImpl_GetParent,
648     IWineD3DEventQueryImpl_GetData,
649     IWineD3DEventQueryImpl_GetDataSize,
650     IWineD3DQueryImpl_GetType,
651     IWineD3DEventQueryImpl_Issue
652 };
653
654 const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
655 {
656     /*** IUnknown methods ***/
657     IWineD3DQueryImpl_QueryInterface,
658     IWineD3DQueryImpl_AddRef,
659     IWineD3DQueryImpl_Release,
660     /*** IWineD3Dquery methods ***/
661     IWineD3DQueryImpl_GetParent,
662     IWineD3DOcclusionQueryImpl_GetData,
663     IWineD3DOcclusionQueryImpl_GetDataSize,
664     IWineD3DQueryImpl_GetType,
665     IWineD3DOcclusionQueryImpl_Issue
666 };