ddraw/tests: Not all GPUs support dwZBufferBitDepth=24 on Windows.
[wine] / dlls / ddraw / tests / refcount.c
1 /*
2  * Some unit tests for ddraw reference counting
3  *
4  * Copyright (C) 2006 Stefan Dösinger
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 #define COBJMACROS
21
22 #include <assert.h>
23 #include "wine/test.h"
24 #include "ddraw.h"
25 #include "d3d.h"
26 #include "unknwn.h"
27
28 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
29
30 static void init_function_pointers(void)
31 {
32     HMODULE hmod = GetModuleHandleA("ddraw.dll");
33     pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
34 }
35
36 static ULONG getRefcount(IUnknown *iface)
37 {
38     IUnknown_AddRef(iface);
39     return IUnknown_Release(iface);
40 }
41
42 static void test_ddraw_objects(void)
43 {
44     HRESULT hr;
45     ULONG ref;
46     IDirectDraw7 *DDraw7;
47     IDirectDraw4 *DDraw4;
48     IDirectDraw2 *DDraw2;
49     IDirectDraw  *DDraw1;
50     IDirectDrawPalette *palette;
51     IDirectDrawSurface7 *surface = NULL;
52     IDirectDrawSurface *surface1;
53     IDirectDrawSurface4 *surface4;
54     PALETTEENTRY Table[256];
55     DDSURFACEDESC2 ddsd;
56
57     hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
58     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
59     if(!DDraw7)
60     {
61         trace("Couldn't create DDraw interface, skipping tests\n");
62         return;
63     }
64
65     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
66     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
67     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
68     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
69     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
70     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
71
72     ref = getRefcount( (IUnknown *) DDraw7);
73     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
74
75     /* Fails without a cooplevel */
76     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
77     ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreatePalette returned %08x\n", hr);
78
79     /* This check is before the cooplevel check */
80     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, (void *) 0xdeadbeef);
81     ok(hr == CLASS_E_NOAGGREGATION, "CreatePalette returned %08x\n", hr);
82
83     hr = IDirectDraw7_SetCooperativeLevel(DDraw7, 0, DDSCL_NORMAL);
84     ok(hr == DD_OK, "SetCooperativeLevel failed with %08x\n", hr);
85
86     memset(&ddsd, 0, sizeof(ddsd));
87     ddsd.dwSize = sizeof(ddsd);
88     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
89     ddsd.dwWidth = 64;
90     ddsd.dwHeight = 64;
91     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
92     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
93     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
94     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
95
96     hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd, &surface, NULL);
97     if (!surface)
98     {
99         win_skip("Could not create surface : %08x\n", hr);
100         IDirectDraw7_Release(DDraw7);
101         return;
102     }
103     ok(hr == DD_OK, "CreateSurface failed with %08x\n", hr);
104
105     /* DDraw refcount increased by 1 */
106     ref = getRefcount( (IUnknown *) DDraw7);
107     ok(ref == 2, "Got refcount %d, expected 2\n", ref);
108
109     /* Surface refcount starts with 1 */
110     ref = getRefcount( (IUnknown *) surface);
111     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
112
113     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
114     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
115
116     /* DDraw refcount increased by 1 */
117     ref = getRefcount( (IUnknown *) DDraw7);
118     ok(ref == 3, "Got refcount %d, expected 3\n", ref);
119
120     /* Palette starts with 1 */
121     ref = getRefcount( (IUnknown *) palette);
122     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
123
124     /* Test attaching a palette to a surface */
125     hr = IDirectDrawSurface7_SetPalette(surface, palette);
126     ok(hr == DD_OK, "IDirectDrawSurface_SetPalette failed with %08x\n", hr);
127
128     /* Palette refcount increased, surface stays the same */
129     ref = getRefcount( (IUnknown *) palette);
130     ok(ref == 2, "Got refcount %d, expected 2\n", ref);
131     ref = getRefcount( (IUnknown *) surface);
132     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
133
134     IDirectDrawSurface7_Release(surface);
135     /* Increased before - decrease now */
136     ref = getRefcount( (IUnknown *) DDraw7);
137     ok(ref == 2, "Got refcount %d, expected 2\n", ref);
138
139     /* Releasing the surface detaches the palette */
140     ref = getRefcount( (IUnknown *) palette);
141     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
142
143     IDirectDrawPalette_Release(palette);
144
145     /* Increased before - decrease now */
146     ref = getRefcount( (IUnknown *) DDraw7);
147     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
148
149     /* Not all interfaces are AddRefed when a palette is created */
150     hr = IDirectDraw4_CreatePalette(DDraw4, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
151     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
152     ref = getRefcount( (IUnknown *) DDraw4);
153     ok(ref == 2, "Got refcount %d, expected 2\n", ref);
154     IDirectDrawPalette_Release(palette);
155
156     /* No addref here */
157     hr = IDirectDraw2_CreatePalette(DDraw2, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
158     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
159     ref = getRefcount( (IUnknown *) DDraw2);
160     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
161     IDirectDrawPalette_Release(palette);
162
163     /* No addref here */
164     hr = IDirectDraw_CreatePalette(DDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
165     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
166     ref = getRefcount( (IUnknown *) DDraw1);
167     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
168     IDirectDrawPalette_Release(palette);
169
170     /* Similar for surfaces */
171     hr = IDirectDraw4_CreateSurface(DDraw4, &ddsd, &surface4, NULL);
172     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
173     ref = getRefcount( (IUnknown *) DDraw4);
174     ok(ref == 2, "Got refcount %d, expected 2\n", ref);
175     IDirectDrawSurface4_Release(surface4);
176
177     ddsd.dwSize = sizeof(DDSURFACEDESC);
178     hr = IDirectDraw2_CreateSurface(DDraw2, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
179     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
180     ref = getRefcount( (IUnknown *) DDraw2);
181     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
182     IDirectDrawSurface_Release(surface1);
183
184     hr = IDirectDraw_CreateSurface(DDraw1, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
185     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
186     ref = getRefcount( (IUnknown *) DDraw1);
187     ok(ref == 1, "Got refcount %d, expected 1\n", ref);
188     IDirectDrawSurface_Release(surface1);
189
190     IDirectDraw7_Release(DDraw7);
191     IDirectDraw4_Release(DDraw4);
192     IDirectDraw2_Release(DDraw2);
193     IDirectDraw_Release(DDraw1);
194 }
195
196 static void test_iface_refcnt(void)
197 {
198     HRESULT hr;
199     IDirectDraw  *DDraw1;
200     IDirectDraw2 *DDraw2;
201     IDirectDraw4 *DDraw4;
202     IDirectDraw7 *DDraw7;
203     IDirect3D7   *D3D7;
204     IDirect3D3   *D3D3;
205     IDirect3D2   *D3D2;
206     IDirect3D    *D3D1;
207     long ref;
208
209     hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
210     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
211     if(!DDraw7)
212     {
213         trace("Couldn't create DDraw interface, skipping tests\n");
214         return;
215     }
216
217     ref = getRefcount( (IUnknown *) DDraw7);
218     ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref);
219
220     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
221     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
222     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
223     ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08x\n", hr);
224     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
225     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
226
227     /* All interfaces now have refcount 1! */
228     ref = getRefcount( (IUnknown *) DDraw7);
229     ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
230     ref = getRefcount( (IUnknown *) DDraw7);
231     ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
232     ref = getRefcount( (IUnknown *) DDraw4);
233     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
234     ref = getRefcount( (IUnknown *) DDraw2);
235     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
236     ref = getRefcount( (IUnknown *) DDraw1);
237     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
238
239     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7);
240     ok(hr == DD_OK || hr == E_NOINTERFACE, /* win64 */
241        "IDirectDraw7_QueryInterface returned %08x\n", hr);
242     if (FAILED(hr))
243     {
244         IDirectDraw7_Release(DDraw7);
245         IDirectDraw4_Release(DDraw4);
246         IDirectDraw2_Release(DDraw2);
247         IDirectDraw_Release(DDraw1);
248         skip( "no IDirect3D7 support\n" );
249         return;
250     }
251
252     /* Apparently IDirectDrawX and IDirect3DX are linked together */
253     ref = getRefcount( (IUnknown *) D3D7);
254     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
255     ref = getRefcount( (IUnknown *) DDraw7);
256     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
257
258     IDirectDraw7_AddRef(DDraw7);
259     ref = getRefcount( (IUnknown *) D3D7);
260     ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref);
261     ref = getRefcount( (IUnknown *) DDraw7);
262     ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref);
263
264     IDirect3D7_Release(D3D7);
265     ref = getRefcount( (IUnknown *) D3D7);
266     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
267     ref = getRefcount( (IUnknown *) DDraw7);
268     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
269
270     /* Can't get older d3d interfaces. WHY????? */
271     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D3, (void **) &D3D3);
272     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
273     if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
274
275     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
276     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
277     if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
278
279     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2);
280     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
281     if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
282
283     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
284     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
285     if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
286
287     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1);
288     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
289     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
290
291     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
292     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
293     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
294
295     hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1);
296     todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08x\n", hr);
297     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
298
299     /* Try an AddRef, it only affects the AddRefed interface */
300     IDirectDraw4_AddRef(DDraw4);
301     ref = getRefcount( (IUnknown *) DDraw7);
302     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */
303     ref = getRefcount( (IUnknown *) DDraw4);
304     ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */
305     ref = getRefcount( (IUnknown *) DDraw2);
306     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
307     ref = getRefcount( (IUnknown *) DDraw1);
308     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
309     ref = getRefcount( (IUnknown *) D3D7);
310     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */
311     IDirectDraw4_Release(DDraw4);
312
313     /* Make sure that they are one object, not different ones */
314     hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
315     ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08x\n", hr);
316     /* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */
317     hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW);
318     ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08x\n", hr);
319
320     /* All done, release all interfaces */
321     IDirectDraw7_Release(DDraw7);
322     IDirectDraw4_Release(DDraw4);
323     IDirectDraw2_Release(DDraw2);
324     IDirectDraw_Release(DDraw1);
325     IDirect3D7_Release(D3D7);
326 }
327
328 static void test_d3d_ifaces(void)
329 {
330     IDirectDraw *DDraw1;
331     IDirectDraw2 *DDraw2;
332     IDirectDraw4 *DDraw4;
333     IDirect3D *D3D1;
334     IDirect3D2 *D3D2;
335     IDirect3D3 *D3D3;
336     IDirect3D7 *D3D7;
337     HRESULT hr;
338     long ref;
339
340     hr = DirectDrawCreate(NULL, &DDraw1, NULL);
341     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
342     if(!DDraw1)
343     {
344         trace("DirectDrawCreate failed with %08x\n", hr);
345         return;
346     }
347
348     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2);
349     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
350     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4);
351     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
352
353     ref = getRefcount( (IUnknown *) DDraw4);
354     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
355     ref = getRefcount( (IUnknown *) DDraw2);
356     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
357     ref = getRefcount( (IUnknown *) DDraw1);
358     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
359
360     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
361     if (hr == E_NOINTERFACE)  /* win64 */
362     {
363         IDirectDraw4_Release(DDraw4);
364         IDirectDraw2_Release(DDraw2);
365         IDirectDraw_Release(DDraw1);
366         skip( "no IDirect3D support\n" );
367         return;
368     }
369     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
370     ref = getRefcount( (IUnknown *) DDraw4);
371     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
372     ref = getRefcount( (IUnknown *) DDraw2);
373     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
374     ref = getRefcount( (IUnknown *) DDraw1);
375     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
376     IDirect3D_Release(D3D1);
377
378     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
379     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
380     ref = getRefcount( (IUnknown *) DDraw4);
381     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
382     ref = getRefcount( (IUnknown *) DDraw2);
383     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
384     ref = getRefcount( (IUnknown *) DDraw1);
385     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
386     IDirect3D2_Release(D3D2);
387
388     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
389     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
390     ref = getRefcount( (IUnknown *) DDraw4);
391     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
392     ref = getRefcount( (IUnknown *) DDraw2);
393     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
394     ref = getRefcount( (IUnknown *) DDraw1);
395     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
396     IDirect3D3_Release(D3D3);
397
398     /* Try to AddRef the D3D3 interface that has been released already */
399     IDirect3D3_AddRef(D3D3);
400     ref = getRefcount( (IUnknown *) DDraw1);
401     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
402     ref = getRefcount( (IUnknown *) D3D3);
403     ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref);
404     /* The newer interfaces remain untouched */
405     ref = getRefcount( (IUnknown *) DDraw4);
406     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
407     ref = getRefcount( (IUnknown *) DDraw2);
408     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
409     IDirect3D3_Release(D3D3);
410     ref = getRefcount( (IUnknown *) DDraw1);
411     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
412     ref = getRefcount( (IUnknown *) DDraw1);
413     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
414
415     /* It is possible to query any IDirect3D interfaces from any IDirectDraw interface,
416      * Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces)
417      */
418     hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1);
419     ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
420     IDirect3D_Release(D3D1);
421     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1);
422     ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
423     IDirect3D_Release(D3D1);
424
425     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2);
426     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
427     IDirect3D_Release(D3D2);
428     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2);
429     ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
430     IDirect3D_Release(D3D2);
431
432     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3);
433     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
434     IDirect3D_Release(D3D3);
435     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3);
436     ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
437     IDirect3D_Release(D3D3);
438
439     /* This does NOT work */
440     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7);
441     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
442     if(D3D7) IDirect3D_Release(D3D7);
443     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7);
444     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
445     if(D3D7) IDirect3D_Release(D3D7);
446     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7);
447     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
448     if(D3D7) IDirect3D_Release(D3D7);
449
450     /* Release the interfaces */
451     IDirectDraw4_Release(DDraw4);
452     IDirectDraw2_Release(DDraw2);
453     IDirectDraw_Release(DDraw1);
454 }
455
456 START_TEST(refcount)
457 {
458     init_function_pointers();
459     if(!pDirectDrawCreateEx)
460     {
461         win_skip("function DirectDrawCreateEx not available\n");
462         return;
463     }
464     test_ddraw_objects();
465     test_iface_refcnt();
466     test_d3d_ifaces();
467 }