static void test_iface_refcnt(void) { HRESULT hr; IDirectDraw *DDraw1; IDirectDraw2 *DDraw2; IDirectDraw4 *DDraw4; IDirectDraw7 *DDraw7; IDirect3D7 *D3D7; IDirect3D3 *D3D3; IDirect3D2 *D3D2; IDirect3D *D3D1; long ref; hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL); ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr); if(!DDraw7) { trace("Couldn't create DDraw interface, skipping tests\n"); return; } ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref); hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4); ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr); hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2); ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08x\n", hr); hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1); ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr); /* All interfaces now have refcount 1! */ ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 1, "IDirectDraw reference count is %ld\n", ref); hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7); ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr); /* Apparently IDirectDrawX and IDirect3DX are linked together */ ref = getRefcount( (IUnknown *) D3D7); ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); IDirectDraw7_AddRef(DDraw7); ref = getRefcount( (IUnknown *) D3D7); ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref); IDirect3D7_Release(D3D7); ref = getRefcount( (IUnknown *) D3D7); ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* Can't get older d3d interfaces. WHY????? */ hr = IDirectDraw7_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3); hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3); hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2); hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2); hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1); hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1); hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1); todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08x\n", hr); if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1); /* Try an AddRef, it only affects the AddRefed interface */ IDirectDraw4_AddRef(DDraw4); ref = getRefcount( (IUnknown *) DDraw7); ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */ ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */ ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 1, "IDirectDraw reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) D3D7); ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */ IDirectDraw4_Release(DDraw4); /* Make sure that they are one object, not different ones */ hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08x\n", hr); /* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */ hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW); ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08x\n", hr); /* All done, release all interfaces */ IDirectDraw7_Release(DDraw7); IDirectDraw4_Release(DDraw4); IDirectDraw2_Release(DDraw2); IDirectDraw_Release(DDraw1); IDirect3D7_Release(D3D7); }
static void test_d3d_ifaces(void) { IDirectDraw *DDraw1; IDirectDraw2 *DDraw2; IDirectDraw4 *DDraw4; IDirect3D *D3D1; IDirect3D2 *D3D2; IDirect3D3 *D3D3; IDirect3D7 *D3D7; HRESULT hr; long ref; hr = DirectDrawCreate(NULL, &DDraw1, NULL); ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr); if(!DDraw1) { trace("DirectDrawCreate failed with %08x\n", hr); return; } hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 1, "IDirectDraw reference count is %ld\n", ref); hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 2, "IDirectDraw reference count is %ld\n", ref); IDirect3D_Release(D3D1); hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 2, "IDirectDraw reference count is %ld\n", ref); IDirect3D2_Release(D3D2); hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 2, "IDirectDraw reference count is %ld\n", ref); IDirect3D3_Release(D3D3); /* Try to AddRef the D3D3 interface that has been released already */ IDirect3D3_AddRef(D3D3); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 2, "IDirectDraw reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) D3D3); ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref); /* The newer interfaces remain untouched */ ref = getRefcount( (IUnknown *) DDraw4); ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw2); ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref); IDirect3D3_Release(D3D3); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 1, "IDirectDraw reference count is %ld\n", ref); ref = getRefcount( (IUnknown *) DDraw1); ok(ref == 1, "IDirectDraw reference count is %ld\n", ref); /* It is possible to query any IDirect3D interfaces from any IDirectDraw interface, * Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces) */ hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1); ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr); IDirect3D_Release(D3D1); hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1); ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr); IDirect3D_Release(D3D1); hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); IDirect3D_Release(D3D2); hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2); ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr); IDirect3D_Release(D3D2); hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3); ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); IDirect3D_Release(D3D3); hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3); ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr); IDirect3D_Release(D3D3); /* This does NOT work */ hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr); if(D3D7) IDirect3D_Release(D3D7); hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr); if(D3D7) IDirect3D_Release(D3D7); hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7); todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr); if(D3D7) IDirect3D_Release(D3D7); /* Release the interfaces */ IDirectDraw4_Release(DDraw4); IDirectDraw2_Release(DDraw2); IDirectDraw_Release(DDraw1); }
HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw *ddraw, IDirectDrawSurface *surface, BOOL create_z_surface) { DDSCAPS caps = { DDSCAPS_ZBUFFER }; IDirectDrawSurface *ds = NULL; IDirect3DDevice *device1 = NULL; IDirect3DDevice2 *device2 = NULL; IDirect3D2 *d3d2 = NULL; DDSURFACEDESC desc, surface_desc; HRESULT hr; device->ddraw = ddraw; IDirectDraw_AddRef(ddraw); IDirect3DRM_AddRef(device->d3drm); device->render_target = surface; IDirectDrawSurface_AddRef(surface); desc.dwSize = sizeof(desc); hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc); if (FAILED(hr)) return hr; if (!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) return DDERR_INVALIDCAPS; hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds); if (SUCCEEDED(hr)) { create_z_surface = FALSE; IDirectDrawSurface_Release(ds); ds = NULL; } if (create_z_surface) { memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; surface_desc.u2.dwZBufferBitDepth = 16; surface_desc.dwWidth = desc.dwWidth; surface_desc.dwHeight = desc.dwHeight; hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &ds, NULL); if (FAILED(hr)) return hr; hr = IDirectDrawSurface_AddAttachedSurface(surface, ds); IDirectDrawSurface_Release(ds); if (FAILED(hr)) return hr; } if (version == 1) hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DRGBDevice, (void **)&device1); else { IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D2, (void**)&d3d2); hr = IDirect3D2_CreateDevice(d3d2, &IID_IDirect3DRGBDevice, surface, &device2); IDirect3D2_Release(d3d2); } if (FAILED(hr)) { IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); return hr; } if (version != 1) { hr = IDirect3DDevice2_QueryInterface(device2, &IID_IDirect3DDevice, (void**)&device1); IDirect3DDevice2_Release(device2); if (FAILED(hr)) { IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); return hr; } } device->device = device1; device->width = desc.dwWidth; device->height = desc.dwHeight; return hr; }