Ejemplo n.º 1
0
void release_test_d3d_device ( void )
{
	HRESULT
		ddrval;

	destroy_d3d_vertex_buffers ();

	if ( d3d.d3d )
	{
		if ( d3d.device )
		{
			ddrval = IDirect3DDevice7_Release ( d3d.device );
			if ( ddrval < DD_OK )
			{
				debug_log ( "Unable to release d3d device: %s", get_d3d_error_message ( ddrval ) );
			}
			d3d.device = NULL;
		}

		if ( d3d.d3d )
		{
			ddrval = IDirect3D7_Release ( d3d.d3d );
			if ( ddrval < DD_OK )
			{
				debug_log ( "Unable to release d3d: %s", get_d3d_error_message ( ddrval ) );
			}
			d3d.d3d = NULL;
		}
	}
}
Ejemplo n.º 2
0
static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
{
    IDirect3DDevice7 *device = NULL;
    IDirectDrawSurface7 *surface;
    DDSURFACEDESC2 surface_desc;
    IDirectDraw7 *ddraw;
    IDirect3D7 *d3d7;
    HRESULT hr;

    if (!(ddraw = create_ddraw()))
        return NULL;

    hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, coop_level);
    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);

    memset(&surface_desc, 0, sizeof(surface_desc));
    surface_desc.dwSize = sizeof(surface_desc);
    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
    surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
    surface_desc.dwWidth = 640;
    surface_desc.dwHeight = 480;

    hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);

    if (coop_level & DDSCL_NORMAL)
    {
        IDirectDrawClipper *clipper;

        hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
        ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
        hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
        ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
        hr = IDirectDrawSurface7_SetClipper(surface, clipper);
        ok(SUCCEEDED(hr), "Failed to set surface clipper, hr %#x.\n", hr);
        IDirectDrawClipper_Release(clipper);
    }

    hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7);
    IDirectDraw7_Release(ddraw);
    if (FAILED(hr))
    {
        IDirectDrawSurface7_Release(surface);
        return NULL;
    }

    hr = IDirect3D7_CreateDevice(d3d7, &IID_IDirect3DTnLHalDevice, surface, &device);
    IDirect3D7_Release(d3d7);
    IDirectDrawSurface7_Release(surface);
    if (FAILED(hr))
        return NULL;

    return device;
}
Ejemplo n.º 3
0
void release_test_d3d_device ( void )
{

	unsigned int
		ddrval;

	destroy_d3d_vertex_buffers ();

	if ( d3d.d3d )
	{

		if ( d3d.device )
		{
#ifdef _WIN32
			ddrval = IDirect3DDevice7_Release ( d3d.device );

			if ( ddrval < DD_OK )
			{

				debug_log ( "Unable to release d3d device: %s", get_d3d_error_message ( ddrval ) );
			}
#endif
			d3d.device = NULL;
		}

		if ( d3d.d3d )
		{
#ifdef _WIN32
			ddrval = IDirect3D7_Release ( d3d.d3d );

			if ( ddrval < DD_OK )
			{

				debug_log ( "Unable to release d3d: %s", get_d3d_error_message ( ddrval ) );
			}
#endif
			d3d.d3d = NULL;
		}
	}
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
static void test_process_vertices(void)
{
    IDirect3DVertexBuffer7 *src_vb, *dst_vb1, *dst_vb2;
    D3DVERTEXBUFFERDESC vb_desc;
    IDirect3DDevice7 *device;
    struct vec4 *dst_data;
    struct vec3 *dst_data2;
    struct vec3 *src_data;
    IDirect3D7 *d3d7;
    D3DVIEWPORT7 vp;
    HWND window;
    HRESULT hr;

    static D3DMATRIX world =
    {
        0.0f,  1.0f, 0.0f, 0.0f,
        1.0f,  0.0f, 0.0f, 0.0f,
        0.0f,  0.0f, 0.0f, 1.0f,
        0.0f,  1.0f, 1.0f, 1.0f,
    };
    static D3DMATRIX view =
    {
        2.0f,  0.0f, 0.0f, 0.0f,
        0.0f, -1.0f, 0.0f, 0.0f,
        0.0f,  0.0f, 1.0f, 0.0f,
        0.0f,  0.0f, 0.0f, 3.0f,
    };
    static D3DMATRIX proj =
    {
        1.0f,  0.0f, 0.0f, 1.0f,
        0.0f,  1.0f, 1.0f, 0.0f,
        0.0f,  1.0f, 1.0f, 0.0f,
        1.0f,  0.0f, 0.0f, 1.0f,
    };

    window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
            0, 0, 640, 480, 0, 0, 0, 0);
    if (!(device = create_device(window, DDSCL_NORMAL)))
    {
        skip("Failed to create a ddraw object, skipping test.\n");
        DestroyWindow(window);
        return;
    }

    hr = IDirect3DDevice7_GetDirect3D(device, &d3d7);
    ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr);

    memset(&vb_desc, 0, sizeof(vb_desc));
    vb_desc.dwSize = sizeof(vb_desc);
    vb_desc.dwFVF = D3DFVF_XYZ;
    vb_desc.dwNumVertices = 4;
    hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &src_vb, 0);
    ok(SUCCEEDED(hr), "Failed to create source vertex buffer, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_Lock(src_vb, 0, (void **)&src_data, NULL);
    ok(SUCCEEDED(hr), "Failed to lock source vertex buffer, hr %#x.\n", hr);
    src_data[0].x = 0.0f;
    src_data[0].y = 0.0f;
    src_data[0].z = 0.0f;
    src_data[1].x = 1.0f;
    src_data[1].y = 1.0f;
    src_data[1].z = 1.0f;
    src_data[2].x = -1.0f;
    src_data[2].y = -1.0f;
    src_data[2].z = 0.5f;
    src_data[3].x = 0.5f;
    src_data[3].y = -0.5f;
    src_data[3].z = 0.25f;
    hr = IDirect3DVertexBuffer7_Unlock(src_vb);
    ok(SUCCEEDED(hr), "Failed to unlock source vertex buffer, hr %#x.\n", hr);

    memset(&vb_desc, 0, sizeof(vb_desc));
    vb_desc.dwSize = sizeof(vb_desc);
    vb_desc.dwFVF = D3DFVF_XYZRHW;
    vb_desc.dwNumVertices = 4;
    /* MSDN says that the last parameter must be 0 - check that. */
    hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &dst_vb1, 4);
    ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);

    memset(&vb_desc, 0, sizeof(vb_desc));
    vb_desc.dwSize = sizeof(vb_desc);
    vb_desc.dwFVF = D3DFVF_XYZ;
    vb_desc.dwNumVertices = 5;
    /* MSDN says that the last parameter must be 0 - check that. */
    hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &dst_vb2, 12345678);
    ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);

    memset(&vp, 0, sizeof(vp));
    vp.dwX = 64;
    vp.dwY = 64;
    vp.dwWidth = 128;
    vp.dwHeight = 128;
    vp.dvMinZ = 0.0f;
    vp.dvMaxZ = 1.0f;
    hr = IDirect3DDevice7_SetViewport(device, &vp);
    ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
    ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
    hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb2, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
    ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
    ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
    ok(compare_vec4(&dst_data[0], +1.280e+2f, +1.280e+2f, +0.000e+0f, +1.000e+0f, 4096),
            "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
    ok(compare_vec4(&dst_data[1], +1.920e+2f, +6.400e+1f, +1.000e+0f, +1.000e+0f, 4096),
            "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
    ok(compare_vec4(&dst_data[2], +6.400e+1f, +1.920e+2f, +5.000e-1f, +1.000e+0f, 4096),
            "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
    ok(compare_vec4(&dst_data[3], +1.600e+2f, +1.600e+2f, +2.500e-1f, +1.000e+0f, 4096),
            "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
    hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
    ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_Lock(dst_vb2, 0, (void **)&dst_data2, NULL);
    ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
    /* Small thing without much practical meaning, but I stumbled upon it,
     * so let's check for it: If the output vertex buffer has no RHW value,
     * the RHW value of the last vertex is written into the next vertex. */
    ok(compare_vec3(&dst_data2[4], +1.000e+0f, +0.000e+0f, +0.000e+0f, 4096),
            "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
            dst_data2[4].x, dst_data2[4].y, dst_data2[4].z);
    hr = IDirect3DVertexBuffer7_Unlock(dst_vb2);
    ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);

    /* Try a more complicated viewport, same vertices. */
    memset(&vp, 0, sizeof(vp));
    vp.dwX = 10;
    vp.dwY = 5;
    vp.dwWidth = 246;
    vp.dwHeight = 130;
    vp.dvMinZ = -2.0f;
    vp.dvMaxZ = 4.0f;
    hr = IDirect3DDevice7_SetViewport(device, &vp);
    ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
    ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
    ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
    ok(compare_vec4(&dst_data[0], +1.330e+2f, +7.000e+1f, -2.000e+0f, +1.000e+0f, 4096),
            "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
    ok(compare_vec4(&dst_data[1], +2.560e+2f, +5.000e+0f, +4.000e+0f, +1.000e+0f, 4096),
            "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
    ok(compare_vec4(&dst_data[2], +1.000e+1f, +1.350e+2f, +1.000e+0f, +1.000e+0f, 4096),
            "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
    ok(compare_vec4(&dst_data[3], +1.945e+2f, +1.025e+2f, -5.000e-1f, +1.000e+0f, 4096),
            "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
    hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
    ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);

    hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &world);
    ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
    hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &view);
    ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
    hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &proj);
    ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
    ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);

    hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
    ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
    ok(compare_vec4(&dst_data[0], +2.560e+2f, +7.000e+1f, -2.000e+0f, +3.333e-1f, 4096),
            "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
    ok(compare_vec4(&dst_data[1], +2.560e+2f, +7.813e+1f, -2.750e+0f, +1.250e-1f, 4096),
            "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
    ok(compare_vec4(&dst_data[2], +2.560e+2f, +4.400e+1f, +4.000e-1f, +4.000e-1f, 4096),
            "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
    ok(compare_vec4(&dst_data[3], +2.560e+2f, +8.182e+1f, -3.091e+0f, +3.636e-1f, 4096),
            "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
            dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
    hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
    ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);

    IDirect3DVertexBuffer7_Release(dst_vb2);
    IDirect3DVertexBuffer7_Release(dst_vb1);
    IDirect3DVertexBuffer7_Release(src_vb);
    IDirect3D7_Release(d3d7);
    IDirect3DDevice7_Release(device);
    DestroyWindow(window);
}