diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index c2012fceefe..328813c948a 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -1367,6 +1367,88 @@ cleanup: if (hwnd) DestroyWindow(hwnd); } +static void test_null_stream(void) +{ + IDirect3DVertexBuffer9 *buffer = NULL; + D3DPRESENT_PARAMETERS present_parameters; + IDirect3DDevice9 *device = NULL; + IDirect3D9 *d3d9; + HWND hwnd; + HRESULT hr; + IDirect3DVertexShader9 *shader; + IDirect3DVertexDeclaration9 *decl; + DWORD shader_code[] = { + 0xfffe0101, /* vs_1_1 */ + 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */ + 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */ + 0x0000ffff /* end */ + }; + static const D3DVERTEXELEMENT9 decl_elements[] = { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + + d3d9 = pDirect3DCreate9( D3D_SDK_VERSION ); + ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n"); + hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL ); + ok(hwnd != NULL, "Failed to create window\n"); + if (!d3d9 || !hwnd) goto cleanup; + + ZeroMemory(&present_parameters, sizeof(present_parameters)); + present_parameters.Windowed = TRUE; + present_parameters.hDeviceWindow = hwnd; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + + hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device ); + ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr)); + if(!device) + { + skip("Failed to create a d3d device\n"); + goto cleanup; + } + + hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader); + if(FAILED(hr)) { + skip("No vertex shader support\n"); + goto cleanup; + } + hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl); + ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr); + hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL); + ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr); + + hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3); + ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr); + hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0); + ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr); + hr = IDirect3DDevice9_SetVertexShader(device, shader); + ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr); + hr = IDirect3DDevice9_SetVertexDeclaration(device, decl); + ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr); + if(SUCCEEDED(hr)) { + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1); + ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr); + + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr); + } + + IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0); + IDirect3DDevice9_SetVertexShader(device, NULL); + IDirect3DDevice9_SetVertexDeclaration(device, NULL); + + cleanup: + if(decl) IDirect3DVertexDeclaration9_Release(decl); + if(shader) IDirect3DVertexShader9_Release(shader); + if(device) IDirect3DDevice9_Release(device); + if(d3d9) IDirect3D9_Release(d3d9); +} + START_TEST(device) { HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" ); @@ -1390,5 +1472,6 @@ START_TEST(device) test_limits(); test_depthstenciltest(); test_draw_indexed(); + test_null_stream(); } } diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index dcfe20ca851..cca8c939ddd 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -246,7 +246,10 @@ void primitiveDeclarationConvertToStridedData( * once in there. */ for(i=0; i < numPreloadStreams; i++) { - IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[streams[i]]); + IWineD3DVertexBuffer *vb = This->stateBlock->streamSource[streams[i]]; + if(vb) { + IWineD3DVertexBuffer_PreLoad(vb); + } } }