diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 17c34432866..87d3f9e0d56 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -4532,6 +4532,101 @@ static void test_set_palette(void) DestroyWindow(window); } +static void test_swvp_buffer(void) +{ + IDirect3DDevice8 *device; + IDirect3D8 *d3d8; + UINT refcount; + HWND window; + HRESULT hr; + unsigned int i; + IDirect3DVertexBuffer8 *buffer; + static const unsigned int bufsize = 1024; + D3DVERTEXBUFFER_DESC desc; + D3DPRESENT_PARAMETERS present_parameters = {0}; + struct + { + float x, y, z; + } *ptr, *ptr2; + + if (!(d3d8 = pDirect3DCreate8(D3D_SDK_VERSION))) + { + skip("Failed to create d3d8 object, skipping tests.\n"); + return; + } + + window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + + present_parameters.Windowed = TRUE; + present_parameters.hDeviceWindow = window; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.BackBufferWidth = screen_width; + present_parameters.BackBufferHeight = screen_height; + present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + present_parameters.EnableAutoDepthStencil = FALSE; + if (FAILED(IDirect3D8_CreateDevice(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D8_Release(d3d8); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice8_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, + D3DPOOL_DEFAULT, &buffer); + ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); + hr = IDirect3DVertexBuffer8_GetDesc(buffer, &desc); + ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr); + ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool); + ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY), + "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage); + + hr = IDirect3DVertexBuffer8_Lock(buffer, 0, bufsize * sizeof(*ptr), (BYTE **)&ptr, D3DLOCK_DISCARD); + ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr); + for (i = 0; i < bufsize; i++) + { + ptr[i].x = i * 1.0f; + ptr[i].y = i * 2.0f; + ptr[i].z = i * 3.0f; + } + hr = IDirect3DVertexBuffer8_Unlock(buffer); + ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ); + ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr); + hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*ptr)); + ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr); + hr = IDirect3DDevice8_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice8_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + hr = IDirect3DVertexBuffer8_Lock(buffer, 0, bufsize * sizeof(*ptr2), (BYTE **)&ptr2, D3DLOCK_DISCARD); + ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr); + ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2); + for (i = 0; i < bufsize; i++) + { + if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f) + { + ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i, + ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f); + break; + } + } + hr = IDirect3DVertexBuffer8_Unlock(buffer); + ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr); + + IDirect3DVertexBuffer8_Release(buffer); + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D8_Release(d3d8); + DestroyWindow(window); +} + START_TEST(device) { HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" ); @@ -4606,6 +4701,7 @@ START_TEST(device) test_surface_double_unlock(); test_surface_lockrect_blocks(); test_set_palette(); + test_swvp_buffer(); } UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL)); }