d3d9/tests: Fix a typo.
[wine] / dlls / d3d9 / tests / stateblock.c
1 /*
2  * Copyright (C) 2005 Henri Verbeet
3  * Copyright (C) 2006 Ivan Gyurdiev
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #define COBJMACROS
21 #include <d3d9.h>
22 #include "wine/test.h"
23
24 static HMODULE d3d9_handle = 0;
25
26 static DWORD texture_stages;
27
28 static HWND create_window(void)
29 {
30     WNDCLASS wc = {0};
31     wc.lpfnWndProc = DefWindowProc;
32     wc.lpszClassName = "d3d9_test_wc";
33     RegisterClass(&wc);
34
35     return CreateWindow("d3d9_test_wc", "d3d9_test",
36             0, 0, 0, 0, 0, 0, 0, 0, 0);
37 }
38
39 static HRESULT init_d3d9(
40     IDirect3DDevice9** device,
41     D3DPRESENT_PARAMETERS* device_pparams)
42 {
43     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
44     IDirect3D9 *d3d9_ptr = 0;
45     HRESULT hres;
46     HWND window;
47
48     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
49     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
50     if (!d3d9_create) return E_FAIL;
51
52     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
53     if (!d3d9_ptr)
54     {
55         skip("could not create D3D9\n");
56         return E_FAIL;
57     }
58
59     window = create_window();
60
61     ZeroMemory(device_pparams, sizeof(D3DPRESENT_PARAMETERS));
62     device_pparams->Windowed = TRUE;
63     device_pparams->hDeviceWindow = window;
64     device_pparams->SwapEffect = D3DSWAPEFFECT_DISCARD;
65
66     hres = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
67         D3DCREATE_SOFTWARE_VERTEXPROCESSING, device_pparams, device);
68     ok(hres == D3D_OK || hres == D3DERR_NOTAVAILABLE,
69         "IDirect3D_CreateDevice returned: 0x%x\n", hres);
70     return hres;
71 }
72
73 static void test_begin_end_state_block(IDirect3DDevice9 *device_ptr)
74 {
75     HRESULT hret = 0;
76     IDirect3DStateBlock9 *state_block_ptr = 0;
77
78     /* Should succeed */
79     hret = IDirect3DDevice9_BeginStateBlock(device_ptr);
80     ok(hret == D3D_OK, "BeginStateBlock returned: hret 0x%x. Expected hret 0x%x. Aborting.\n", hret, D3D_OK);
81     if (hret != D3D_OK) return;
82
83     /* Calling BeginStateBlock while recording should return D3DERR_INVALIDCALL */
84     hret = IDirect3DDevice9_BeginStateBlock(device_ptr);
85     ok(hret == D3DERR_INVALIDCALL, "BeginStateBlock returned: hret 0x%x. Expected hret 0x%x. Aborting.\n", hret, D3DERR_INVALIDCALL);
86     if (hret != D3DERR_INVALIDCALL) return;
87
88     /* Should succeed */
89     state_block_ptr = (IDirect3DStateBlock9 *)0xdeadbeef;
90     hret = IDirect3DDevice9_EndStateBlock(device_ptr, &state_block_ptr);
91     ok(hret == D3D_OK && state_block_ptr != 0 && state_block_ptr != (IDirect3DStateBlock9 *)0xdeadbeef,
92         "EndStateBlock returned: hret 0x%x, state_block_ptr %p. "
93         "Expected hret 0x%x, state_block_ptr != %p, state_block_ptr != 0xdeadbeef.\n", hret, state_block_ptr, D3D_OK, NULL);
94     IDirect3DStateBlock9_Release(state_block_ptr);
95
96     /* Calling EndStateBlock while not recording should return D3DERR_INVALIDCALL. state_block_ptr should not be touched. */
97     state_block_ptr = (IDirect3DStateBlock9 *)0xdeadbeef;
98     hret = IDirect3DDevice9_EndStateBlock(device_ptr, &state_block_ptr);
99     ok(hret == D3DERR_INVALIDCALL && state_block_ptr == (IDirect3DStateBlock9 *)0xdeadbeef,
100         "EndStateBlock returned: hret 0x%x, state_block_ptr %p. "
101         "Expected hret 0x%x, state_block_ptr 0xdeadbeef.\n", hret, state_block_ptr, D3DERR_INVALIDCALL);
102 }
103
104 /* ============================ State Testing Framework ========================== */
105
106 struct state_test
107 {
108     const char* test_name;
109
110     /* The initial data is usually the same
111      * as the default data, but a write can have side effects.
112      * The initial data is tested first, before any writes take place
113      * The default data can be tested after a write */
114     const void* initial_data;
115
116     /* The default data is the standard state to compare
117      * against, and restore to */
118     const void* default_data;
119
120     /* The test data is the experiment data to try
121      * in - what we want to write
122      * out - what windows will actually write (not necessarily the same)  */
123     const void *test_data_in;
124     const void *test_data_out_all;
125     const void *test_data_out_vertex;
126     const void *test_data_out_pixel;
127
128     HRESULT (*init)(IDirect3DDevice9 *device, struct state_test *test);
129     void (*cleanup)(IDirect3DDevice9 *device, struct state_test *test);
130     void (*apply_data)(IDirect3DDevice9 *device, const struct state_test *test,
131             const void *data);
132     void (*check_data)(IDirect3DDevice9 *device, const struct state_test *test,
133             const void *expected_data, unsigned int chain_stage, DWORD quirk);
134
135     /* Test arguments */
136     const void* test_arg;
137
138     /* Test-specific context data */
139     void* test_context;
140 };
141
142 #define EVENT_OK    0
143 #define EVENT_ERROR -1
144
145 /* Apparently recorded stateblocks record and apply vertex declarations,
146  * but don't capture them */
147 #define SB_QUIRK_RECORDED_VDECL_CAPTURE  0x00000001
148
149 struct event_data
150 {
151     IDirect3DStateBlock9 *stateblock;
152     IDirect3DSurface9 *original_render_target;
153     IDirect3DSwapChain9 *new_swap_chain;
154 };
155
156 enum stateblock_data
157 {
158     SB_DATA_NONE = 0,
159     SB_DATA_DEFAULT,
160     SB_DATA_INITIAL,
161     SB_DATA_TEST_IN,
162     SB_DATA_TEST_ALL,
163     SB_DATA_TEST_VERTEX,
164     SB_DATA_TEST_PIXEL,
165 };
166
167 struct event
168 {
169     int (*event_fn)(IDirect3DDevice9 *device, struct event_data *event_data);
170     enum stateblock_data check;
171     enum stateblock_data apply;
172     DWORD quirk;
173 };
174
175 static const void *get_event_data(const struct state_test *test, enum stateblock_data data)
176 {
177     switch (data)
178     {
179         case SB_DATA_DEFAULT:
180             return test->default_data;
181
182         case SB_DATA_INITIAL:
183             return test->initial_data;
184
185         case SB_DATA_TEST_IN:
186             return test->test_data_in;
187
188         case SB_DATA_TEST_ALL:
189             return test->test_data_out_all;
190
191         case SB_DATA_TEST_VERTEX:
192             return test->test_data_out_vertex;
193
194         case SB_DATA_TEST_PIXEL:
195             return test->test_data_out_pixel;
196
197         default:
198             return NULL;
199     }
200 }
201
202 /* This is an event-machine, which tests things.
203  * It tests get and set operations for a batch of states, based on
204  * results from the event function, which directs what's to be done */
205
206 static void execute_test_chain(IDirect3DDevice9 *device, struct state_test *test,
207         unsigned int ntests, struct event *event, unsigned int nevents, struct event_data *event_data)
208 {
209     unsigned int i, j;
210
211     /* For each queued event */
212     for (j = 0; j < nevents; ++j)
213     {
214         const void *data;
215
216         /* Execute the next event handler (if available). */
217         if (event[j].event_fn)
218         {
219             if (event[j].event_fn(device, event_data) == EVENT_ERROR)
220             {
221                 trace("Stage %u in error state, aborting.\n", j);
222                 break;
223             }
224         }
225
226         if (event[j].check != SB_DATA_NONE)
227         {
228             for (i = 0; i < ntests; ++i)
229             {
230                 data = get_event_data(&test[i], event[j].check);
231                 test[i].check_data(device, &test[i], data, j, event[j].quirk);
232             }
233         }
234
235         if (event[j].apply != SB_DATA_NONE)
236         {
237             for (i = 0; i < ntests; ++i)
238             {
239                 data = get_event_data(&test[i], event[j].apply);
240                 test[i].apply_data(device, &test[i], data);
241             }
242         }
243     }
244
245     /* Attempt to reset any changes made. */
246     for (i = 0; i < ntests; ++i)
247     {
248         test[i].apply_data(device, &test[i], test[i].default_data);
249     }
250 }
251
252 static int switch_render_target(IDirect3DDevice9 *device, struct event_data *event_data)
253 {
254     HRESULT hret;
255     D3DPRESENT_PARAMETERS present_parameters;
256     IDirect3DSwapChain9* swapchain = NULL;
257     IDirect3DSurface9* backbuffer = NULL;
258
259     /* Parameters for new swapchain */
260     ZeroMemory(&present_parameters, sizeof(present_parameters));
261     present_parameters.Windowed = TRUE;
262     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
263
264     /* Create new swapchain */
265     hret = IDirect3DDevice9_CreateAdditionalSwapChain(device, &present_parameters, &swapchain);
266     ok (hret == D3D_OK, "CreateAdditionalSwapChain returned %#x.\n", hret);
267     if (hret != D3D_OK) goto error;
268
269     /* Get its backbuffer */
270     hret = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
271     ok (hret == D3D_OK, "GetBackBuffer returned %#x.\n", hret);
272     if (hret != D3D_OK) goto error;
273
274     /* Save the current render target */
275     hret = IDirect3DDevice9_GetRenderTarget(device, 0, &event_data->original_render_target);
276     ok (hret == D3D_OK, "GetRenderTarget returned %#x.\n", hret);
277     if (hret != D3D_OK) goto error;
278
279     /* Set the new swapchain's backbuffer as a render target */
280     hret = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
281     ok (hret == D3D_OK, "SetRenderTarget returned %#x.\n", hret);
282     if (hret != D3D_OK) goto error;
283
284     IUnknown_Release(backbuffer);
285     event_data->new_swap_chain = swapchain;
286     return EVENT_OK;
287
288     error:
289     if (backbuffer) IUnknown_Release(backbuffer);
290     if (swapchain) IUnknown_Release(swapchain);
291     return EVENT_ERROR;
292 }
293
294 static int revert_render_target(IDirect3DDevice9 *device, struct event_data *event_data)
295 {
296     HRESULT hret;
297
298     /* Reset the old render target */
299     hret = IDirect3DDevice9_SetRenderTarget(device, 0, event_data->original_render_target);
300     ok (hret == D3D_OK, "SetRenderTarget returned %#x.\n", hret);
301     if (hret != D3D_OK) {
302         IUnknown_Release(event_data->original_render_target);
303         return EVENT_ERROR;
304     }
305
306     IUnknown_Release(event_data->original_render_target);
307     IUnknown_Release(event_data->new_swap_chain);
308
309     return EVENT_OK;
310 }
311
312 static int create_stateblock_all(IDirect3DDevice9 *device, struct event_data *event_data)
313 {
314     HRESULT hr;
315
316     hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &event_data->stateblock);
317     ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
318     if (FAILED(hr)) return EVENT_ERROR;
319     return EVENT_OK;
320 }
321
322 static int create_stateblock_vertex(IDirect3DDevice9 *device, struct event_data *event_data)
323 {
324     HRESULT hr;
325
326     hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &event_data->stateblock);
327     ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
328     if (FAILED(hr)) return EVENT_ERROR;
329     return EVENT_OK;
330 }
331
332 static int create_stateblock_pixel(IDirect3DDevice9 *device, struct event_data *event_data)
333 {
334     HRESULT hr;
335
336     hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_PIXELSTATE, &event_data->stateblock);
337     ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
338     if (FAILED(hr)) return EVENT_ERROR;
339     return EVENT_OK;
340 }
341
342 static int begin_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
343 {
344     HRESULT hret;
345
346     hret = IDirect3DDevice9_BeginStateBlock(device);
347     ok(hret == D3D_OK, "BeginStateBlock returned %#x.\n", hret);
348     if (hret != D3D_OK) return EVENT_ERROR;
349     return EVENT_OK;
350 }
351
352 static int end_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
353 {
354     HRESULT hret;
355
356     hret = IDirect3DDevice9_EndStateBlock(device, &event_data->stateblock);
357     ok(hret == D3D_OK, "EndStateBlock returned %#x.\n", hret);
358     if (hret != D3D_OK) return EVENT_ERROR;
359     return EVENT_OK;
360 }
361
362 static int release_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
363 {
364     IUnknown_Release(event_data->stateblock);
365     return EVENT_OK;
366 }
367
368 static int apply_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
369 {
370     HRESULT hret;
371
372     hret = IDirect3DStateBlock9_Apply(event_data->stateblock);
373     ok(hret == D3D_OK, "Apply returned %#x.\n", hret);
374     if (hret != D3D_OK) {
375         IUnknown_Release(event_data->stateblock);
376         return EVENT_ERROR;
377     }
378
379     IUnknown_Release(event_data->stateblock);
380
381     return EVENT_OK;
382 }
383
384 static int capture_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
385 {
386     HRESULT hret;
387
388     hret = IDirect3DStateBlock9_Capture(event_data->stateblock);
389     ok(hret == D3D_OK, "Capture returned %#x.\n", hret);
390     if (hret != D3D_OK)
391         return EVENT_ERROR;
392
393     return EVENT_OK;
394 }
395
396 static void execute_test_chain_all(IDirect3DDevice9 *device, struct state_test *test, unsigned int ntests)
397 {
398     struct event_data arg;
399     unsigned int i;
400     HRESULT hr;
401
402     struct event read_events[] =
403     {
404         {NULL,                      SB_DATA_INITIAL,        SB_DATA_NONE},
405     };
406
407     struct event write_read_events[] =
408     {
409         {NULL,                      SB_DATA_NONE,           SB_DATA_TEST_IN},
410         {NULL,                      SB_DATA_TEST_ALL,       SB_DATA_NONE},
411     };
412
413     struct event abort_stateblock_events[] =
414     {
415         {begin_stateblock,          SB_DATA_NONE,           SB_DATA_TEST_IN},
416         {end_stateblock,            SB_DATA_NONE,           SB_DATA_NONE},
417         {release_stateblock,        SB_DATA_DEFAULT,        SB_DATA_NONE},
418     };
419
420     struct event apply_stateblock_events[] =
421     {
422         {begin_stateblock,          SB_DATA_NONE,           SB_DATA_TEST_IN},
423         {end_stateblock,            SB_DATA_NONE,           SB_DATA_NONE},
424         {apply_stateblock,          SB_DATA_TEST_ALL,       SB_DATA_NONE},
425     };
426
427     struct event capture_reapply_stateblock_events[] =
428     {
429         {begin_stateblock,          SB_DATA_NONE,           SB_DATA_TEST_IN},
430         {end_stateblock,            SB_DATA_NONE,           SB_DATA_NONE},
431         {capture_stateblock,        SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
432         {apply_stateblock,          SB_DATA_DEFAULT,        SB_DATA_NONE,       SB_QUIRK_RECORDED_VDECL_CAPTURE},
433     };
434
435     struct event create_stateblock_capture_apply_all_events[] =
436     {
437         {create_stateblock_all,     SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
438         {capture_stateblock,        SB_DATA_TEST_ALL,       SB_DATA_DEFAULT},
439         {apply_stateblock,          SB_DATA_TEST_ALL,       SB_DATA_NONE},
440     };
441
442     struct event create_stateblock_apply_all_events[] =
443     {
444         {NULL,                      SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
445         {create_stateblock_all,     SB_DATA_TEST_ALL,       SB_DATA_DEFAULT},
446         {apply_stateblock,          SB_DATA_TEST_ALL,       SB_DATA_NONE},
447     };
448
449     struct event create_stateblock_capture_apply_vertex_events[] =
450     {
451         {create_stateblock_vertex,  SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
452         {capture_stateblock,        SB_DATA_TEST_ALL,       SB_DATA_DEFAULT},
453         {apply_stateblock,          SB_DATA_TEST_VERTEX,    SB_DATA_NONE},
454     };
455
456     struct event create_stateblock_apply_vertex_events[] =
457     {
458         {NULL,                      SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
459         {create_stateblock_vertex,  SB_DATA_TEST_ALL,       SB_DATA_DEFAULT},
460         {apply_stateblock,          SB_DATA_TEST_VERTEX,    SB_DATA_NONE},
461     };
462
463     struct event create_stateblock_capture_apply_pixel_events[] =
464     {
465         {create_stateblock_pixel,   SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
466         {capture_stateblock,        SB_DATA_TEST_ALL,       SB_DATA_DEFAULT},
467         {apply_stateblock,          SB_DATA_TEST_PIXEL,     SB_DATA_NONE},
468     };
469
470     struct event create_stateblock_apply_pixel_events[] =
471     {
472         {NULL,                      SB_DATA_DEFAULT,        SB_DATA_TEST_IN},
473         {create_stateblock_pixel,   SB_DATA_TEST_ALL,       SB_DATA_DEFAULT},
474         {apply_stateblock,          SB_DATA_TEST_PIXEL,     SB_DATA_NONE},
475     };
476
477     struct event rendertarget_switch_events[] =
478     {
479         {NULL,                      SB_DATA_NONE,           SB_DATA_TEST_IN},
480         {switch_render_target,      SB_DATA_TEST_ALL,       SB_DATA_NONE},
481         {revert_render_target,      SB_DATA_NONE,           SB_DATA_NONE},
482     };
483
484     struct event rendertarget_stateblock_events[] =
485     {
486         {begin_stateblock,          SB_DATA_NONE,           SB_DATA_TEST_IN},
487         {switch_render_target,      SB_DATA_DEFAULT,        SB_DATA_NONE},
488         {end_stateblock,            SB_DATA_NONE,           SB_DATA_NONE},
489         {revert_render_target,      SB_DATA_NONE,           SB_DATA_NONE},
490         {apply_stateblock,          SB_DATA_TEST_ALL,       SB_DATA_NONE},
491     };
492
493     /* Setup each test for execution */
494     for (i = 0; i < ntests; ++i)
495     {
496         hr = test[i].init(device, &test[i]);
497         ok(SUCCEEDED(hr), "Test \"%s\" failed setup, aborting\n", test[i].test_name);
498         if (FAILED(hr)) return;
499     }
500
501     trace("Running initial read state tests\n");
502     execute_test_chain(device, test, ntests, read_events, 1, NULL);
503
504     trace("Running write-read state tests\n");
505     execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
506
507     trace("Running stateblock abort state tests\n");
508     execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
509
510     trace("Running stateblock apply state tests\n");
511     execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
512
513     trace("Running stateblock capture/reapply state tests\n");
514     execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
515
516     trace("Running create stateblock capture/apply all state tests\n");
517     execute_test_chain(device, test, ntests, create_stateblock_capture_apply_all_events, 3, &arg);
518
519     trace("Running create stateblock apply state all tests\n");
520     execute_test_chain(device, test, ntests, create_stateblock_apply_all_events, 3, &arg);
521
522     trace("Running create stateblock capture/apply vertex state tests\n");
523     execute_test_chain(device, test, ntests, create_stateblock_capture_apply_vertex_events, 3, &arg);
524
525     trace("Running create stateblock apply vertex state tests\n");
526     execute_test_chain(device, test, ntests, create_stateblock_apply_vertex_events, 3, &arg);
527
528     trace("Running create stateblock capture/apply pixel state tests\n");
529     execute_test_chain(device, test, ntests, create_stateblock_capture_apply_pixel_events, 3, &arg);
530
531     trace("Running create stateblock apply pixel state tests\n");
532     execute_test_chain(device, test, ntests, create_stateblock_apply_pixel_events, 3, &arg);
533
534     trace("Running rendertarget switch state tests\n");
535     execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
536
537     trace("Running stateblock apply over rendertarget switch interrupt tests\n");
538     execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
539
540     /* Cleanup resources */
541     for (i = 0; i < ntests; ++i)
542     {
543         if (test[i].cleanup) test[i].cleanup(device, &test[i]);
544     }
545 }
546
547 /* =================== State test: Pixel and Vertex Shader constants ============ */
548
549 struct shader_constant_data
550 {
551     int int_constant[4];     /* 1x4 integer constant */
552     float float_constant[4]; /* 1x4 float constant */
553     BOOL bool_constant[4];   /* 4x1 boolean constants */
554 };
555
556 struct shader_constant_arg
557 {
558     unsigned int idx;
559     BOOL pshader;
560 };
561
562 static const struct shader_constant_data shader_constant_poison_data =
563 {
564     {0x1337c0de, 0x1337c0de, 0x1337c0de, 0x1337c0de},
565     {1.0f, 2.0f, 3.0f, 4.0f},
566     {FALSE, TRUE, FALSE, TRUE},
567 };
568
569 static const struct shader_constant_data shader_constant_default_data =
570 {
571     {0, 0, 0, 0},
572     {0.0f, 0.0f, 0.0f, 0.0f},
573     {0, 0, 0, 0},
574 };
575
576 static const struct shader_constant_data shader_constant_test_data =
577 {
578     {0xdead0000, 0xdead0001, 0xdead0002, 0xdead0003},
579     {5.0f, 6.0f, 7.0f, 8.0f},
580     {TRUE, FALSE, FALSE, TRUE},
581 };
582
583 static void shader_constant_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
584 {
585     const struct shader_constant_arg *scarg = test->test_arg;
586     const struct shader_constant_data *scdata = data;
587     HRESULT hret;
588     unsigned int index = scarg->idx;
589
590     if (!scarg->pshader) {
591         hret = IDirect3DDevice9_SetVertexShaderConstantI(device, index, scdata->int_constant, 1);
592         ok(hret == D3D_OK, "SetVertexShaderConstantI returned %#x.\n", hret);
593         hret = IDirect3DDevice9_SetVertexShaderConstantF(device, index, scdata->float_constant, 1);
594         ok(hret == D3D_OK, "SetVertexShaderConstantF returned %#x.\n", hret);
595         hret = IDirect3DDevice9_SetVertexShaderConstantB(device, index, scdata->bool_constant, 4);
596         ok(hret == D3D_OK, "SetVertexShaderConstantB returned %#x.\n", hret);
597
598     } else {
599         hret = IDirect3DDevice9_SetPixelShaderConstantI(device, index, scdata->int_constant, 1);
600         ok(hret == D3D_OK, "SetPixelShaderConstantI returned %#x.\n", hret);
601         hret = IDirect3DDevice9_SetPixelShaderConstantF(device, index, scdata->float_constant, 1);
602         ok(hret == D3D_OK, "SetPixelShaderConstantF returned %#x.\n", hret);
603         hret = IDirect3DDevice9_SetPixelShaderConstantB(device, index, scdata->bool_constant, 4);
604         ok(hret == D3D_OK, "SetPixelShaderConstantB returned %#x.\n", hret);
605     }
606 }
607
608 static void shader_constant_check_data(IDirect3DDevice9 *device, const struct state_test *test,
609         const void *expected_data, unsigned int chain_stage, DWORD quirk)
610 {
611     struct shader_constant_data value = shader_constant_poison_data;
612     const struct shader_constant_data *scdata = expected_data;
613     const struct shader_constant_arg *scarg = test->test_arg;
614     HRESULT hr;
615
616     if (!scarg->pshader)
617     {
618         hr = IDirect3DDevice9_GetVertexShaderConstantI(device, scarg->idx, value.int_constant, 1);
619         ok(SUCCEEDED(hr), "GetVertexShaderConstantI returned %#x.\n", hr);
620         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, scarg->idx, value.float_constant, 1);
621         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x.\n", hr);
622         hr = IDirect3DDevice9_GetVertexShaderConstantB(device, scarg->idx, value.bool_constant, 4);
623         ok(SUCCEEDED(hr), "GetVertexShaderConstantB returned %#x.\n", hr);
624     }
625     else
626     {
627         hr = IDirect3DDevice9_GetPixelShaderConstantI(device, scarg->idx, value.int_constant, 1);
628         ok(SUCCEEDED(hr), "GetPixelShaderConstantI returned %#x.\n", hr);
629         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, scarg->idx, value.float_constant, 1);
630         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x.\n", hr);
631         hr = IDirect3DDevice9_GetPixelShaderConstantB(device, scarg->idx, value.bool_constant, 4);
632         ok(SUCCEEDED(hr), "GetPixelShaderConstantB returned %#x.\n", hr);
633     }
634
635     ok(!memcmp(scdata->int_constant, value.int_constant, sizeof(scdata->int_constant)),
636             "Chain stage %u, %s integer constant:\n"
637             "\t{%#x, %#x, %#x, %#x} expected\n"
638             "\t{%#x, %#x, %#x, %#x} received\n",
639             chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
640             scdata->int_constant[0], scdata->int_constant[1],
641             scdata->int_constant[2], scdata->int_constant[3],
642             value.int_constant[0], value.int_constant[1],
643             value.int_constant[2], value.int_constant[3]);
644
645     ok(!memcmp(scdata->float_constant, value.float_constant, sizeof(scdata->float_constant)),
646             "Chain stage %u, %s float constant:\n"
647             "\t{%.8e, %.8e, %.8e, %.8e} expected\n"
648             "\t{%.8e, %.8e, %.8e, %.8e} received\n",
649             chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
650             scdata->float_constant[0], scdata->float_constant[1],
651             scdata->float_constant[2], scdata->float_constant[3],
652             value.float_constant[0], value.float_constant[1],
653             value.float_constant[2], value.float_constant[3]);
654
655     ok(!memcmp(scdata->bool_constant, value.bool_constant, sizeof(scdata->bool_constant)),
656             "Chain stage %u, %s boolean constant:\n"
657             "\t{%#x, %#x, %#x, %#x} expected\n"
658             "\t{%#x, %#x, %#x, %#x} received\n",
659             chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
660             scdata->bool_constant[0], scdata->bool_constant[1],
661             scdata->bool_constant[2], scdata->bool_constant[3],
662             value.bool_constant[0], value.bool_constant[1],
663             value.bool_constant[2], value.bool_constant[3]);
664 }
665
666 static HRESULT shader_constant_test_init(IDirect3DDevice9 *device, struct state_test *test)
667 {
668     const struct shader_constant_arg *test_arg = test->test_arg;
669
670     test->test_context = NULL;
671     test->test_data_in = &shader_constant_test_data;
672     test->test_data_out_all = &shader_constant_test_data;
673     if (test_arg->pshader)
674     {
675         test->test_data_out_vertex = &shader_constant_default_data;
676         test->test_data_out_pixel = &shader_constant_test_data;
677     }
678     else
679     {
680         test->test_data_out_vertex = &shader_constant_test_data;
681         test->test_data_out_pixel = &shader_constant_default_data;
682     }
683     test->default_data = &shader_constant_default_data;
684     test->initial_data = &shader_constant_default_data;
685
686     return D3D_OK;
687 }
688
689 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
690 {
691     test->init = shader_constant_test_init;
692     test->cleanup = NULL;
693     test->apply_data = shader_constant_apply_data;
694     test->check_data = shader_constant_check_data;
695     test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
696     test->test_arg = test_arg;
697 }
698
699 /* =================== State test: Lights ===================================== */
700
701 struct light_data
702 {
703     D3DLIGHT9 light;
704     BOOL enabled;
705     HRESULT get_light_result;
706     HRESULT get_enabled_result;
707 };
708
709 struct light_arg
710 {
711     unsigned int idx;
712 };
713
714 static const struct light_data light_poison_data =
715 {
716     {
717         0x1337c0de,
718         {7.0f, 4.0f, 2.0f, 1.0f},
719         {7.0f, 4.0f, 2.0f, 1.0f},
720         {7.0f, 4.0f, 2.0f, 1.0f},
721         {3.3f, 4.4f, 5.5f},
722         {6.6f, 7.7f, 8.8f},
723         12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
724     },
725     TRUE,
726     0x1337c0de,
727     0x1337c0de,
728 };
729
730 static const struct light_data light_default_data =
731 {
732     {
733         D3DLIGHT_DIRECTIONAL,
734         {1.0f, 1.0f, 1.0f, 0.0f},
735         {0.0f, 0.0f, 0.0f, 0.0f},
736         {0.0f, 0.0f, 0.0f, 0.0f},
737         {0.0f, 0.0f, 0.0f},
738         {0.0f, 0.0f, 1.0f},
739         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
740     },
741     FALSE,
742     D3D_OK,
743     D3D_OK,
744 };
745
746 /* This is used for the initial read state (before a write causes side effects).
747  * The proper return status is D3DERR_INVALIDCALL. */
748 static const struct light_data light_initial_data =
749 {
750     {
751         0x1337c0de,
752         {7.0f, 4.0f, 2.0f, 1.0f},
753         {7.0f, 4.0f, 2.0f, 1.0f},
754         {7.0f, 4.0f, 2.0f, 1.0f},
755         {3.3f, 4.4f, 5.5f},
756         {6.6f, 7.7f, 8.8f},
757         12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
758     },
759     TRUE,
760     D3DERR_INVALIDCALL,
761     D3DERR_INVALIDCALL,
762 };
763
764 static const struct light_data light_test_data_in =
765 {
766     {
767         1,
768         {2.0f, 2.0f, 2.0f, 2.0f},
769         {3.0f, 3.0f, 3.0f, 3.0f},
770         {4.0f, 4.0f, 4.0f, 4.0f},
771         {5.0f, 5.0f, 5.0f},
772         {6.0f, 6.0f, 6.0f},
773         7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
774     },
775     TRUE,
776     D3D_OK,
777     D3D_OK
778 };
779
780 /* SetLight will use 128 as the "enabled" value */
781 static const struct light_data light_test_data_out =
782 {
783     {
784         1,
785         {2.0f, 2.0f, 2.0f, 2.0f},
786         {3.0f, 3.0f, 3.0f, 3.0f},
787         {4.0f, 4.0f, 4.0f, 4.0f},
788         {5.0f, 5.0f, 5.0f},
789         {6.0f, 6.0f, 6.0f},
790         7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
791     },
792     128,
793     D3D_OK,
794     D3D_OK,
795 };
796
797 static void light_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
798 {
799     const struct light_arg *larg = test->test_arg;
800     const struct light_data *ldata = data;
801     HRESULT hret;
802     unsigned int index = larg->idx;
803
804     hret = IDirect3DDevice9_SetLight(device, index, &ldata->light);
805     ok(hret == D3D_OK, "SetLight returned %#x.\n", hret);
806
807     hret = IDirect3DDevice9_LightEnable(device, index, ldata->enabled);
808     ok(hret == D3D_OK, "SetLightEnable returned %#x.\n", hret);
809 }
810
811 static void light_check_data(IDirect3DDevice9 *device, const struct state_test *test,
812         const void *expected_data, unsigned int chain_stage, DWORD quirk)
813 {
814     const struct light_arg *larg = test->test_arg;
815     const struct light_data *ldata = expected_data;
816     struct light_data value;
817
818     value = light_poison_data;
819
820     value.get_enabled_result = IDirect3DDevice9_GetLightEnable(device, larg->idx, &value.enabled);
821     value.get_light_result = IDirect3DDevice9_GetLight(device, larg->idx, &value.light);
822
823     ok(value.get_enabled_result == ldata->get_enabled_result,
824             "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
825             chain_stage, ldata->get_enabled_result, value.get_enabled_result);
826     ok(value.get_light_result == ldata->get_light_result,
827             "Chain stage %u: expected get_light_result %#x, got %#x.\n",
828             chain_stage, ldata->get_light_result, value.get_light_result);
829
830     ok(value.enabled == ldata->enabled,
831             "Chain stage %u: expected enabled %#x, got %#x.\n",
832             chain_stage, ldata->enabled, value.enabled);
833     ok(value.light.Type == ldata->light.Type,
834             "Chain stage %u: expected light.Type %#x, got %#x.\n",
835             chain_stage, ldata->light.Type, value.light.Type);
836     ok(!memcmp(&value.light.Diffuse, &ldata->light.Diffuse, sizeof(value.light.Diffuse)),
837             "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
838             "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
839             ldata->light.Diffuse.r, ldata->light.Diffuse.g,
840             ldata->light.Diffuse.b, ldata->light.Diffuse.a,
841             value.light.Diffuse.r, value.light.Diffuse.g,
842             value.light.Diffuse.b, value.light.Diffuse.a);
843     ok(!memcmp(&value.light.Specular, &ldata->light.Specular, sizeof(value.light.Specular)),
844             "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
845             "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
846             ldata->light.Specular.r, ldata->light.Specular.g,
847             ldata->light.Specular.b, ldata->light.Specular.a,
848             value.light.Specular.r, value.light.Specular.g,
849             value.light.Specular.b, value.light.Specular.a);
850     ok(!memcmp(&value.light.Ambient, &ldata->light.Ambient, sizeof(value.light.Ambient)),
851             "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
852             "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
853             ldata->light.Ambient.r, ldata->light.Ambient.g,
854             ldata->light.Ambient.b, ldata->light.Ambient.a,
855             value.light.Ambient.r, value.light.Ambient.g,
856             value.light.Ambient.b, value.light.Ambient.a);
857     ok(!memcmp(&value.light.Position, &ldata->light.Position, sizeof(value.light.Position)),
858             "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
859             chain_stage, ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z,
860             value.light.Position.x, value.light.Position.y, value.light.Position.z);
861     ok(!memcmp(&value.light.Direction, &ldata->light.Direction, sizeof(value.light.Direction)),
862             "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
863             chain_stage, ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z,
864             value.light.Direction.x, value.light.Direction.y, value.light.Direction.z);
865     ok(value.light.Range == ldata->light.Range,
866             "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
867             chain_stage, ldata->light.Range, value.light.Range);
868     ok(value.light.Falloff == ldata->light.Falloff,
869             "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
870             chain_stage, ldata->light.Falloff, value.light.Falloff);
871     ok(value.light.Attenuation0 == ldata->light.Attenuation0,
872             "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
873             chain_stage, ldata->light.Attenuation0, value.light.Attenuation0);
874     ok(value.light.Attenuation1 == ldata->light.Attenuation1,
875             "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
876             chain_stage, ldata->light.Attenuation1, value.light.Attenuation1);
877     ok(value.light.Attenuation2 == ldata->light.Attenuation2,
878             "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
879             chain_stage, ldata->light.Attenuation2, value.light.Attenuation2);
880     ok(value.light.Theta == ldata->light.Theta,
881             "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
882             chain_stage, ldata->light.Theta, value.light.Theta);
883     ok(value.light.Phi == ldata->light.Phi,
884             "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
885             chain_stage, ldata->light.Phi, value.light.Phi);
886 }
887
888 static HRESULT light_test_init(IDirect3DDevice9 *device, struct state_test *test)
889 {
890     test->test_context = NULL;
891     test->test_data_in = &light_test_data_in;
892     test->test_data_out_all = &light_test_data_out;
893     test->test_data_out_vertex = &light_test_data_out;
894     test->test_data_out_pixel = &light_default_data;
895     test->default_data = &light_default_data;
896     test->initial_data = &light_initial_data;
897
898     return D3D_OK;
899 }
900
901 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
902 {
903     test->init = light_test_init;
904     test->cleanup = NULL;
905     test->apply_data = light_apply_data;
906     test->check_data = light_check_data;
907     test->test_name = "set_get_light";
908     test->test_arg = test_arg;
909 }
910
911 /* =================== State test: Transforms ===================================== */
912
913 struct transform_data
914 {
915     D3DMATRIX view;
916     D3DMATRIX projection;
917     D3DMATRIX texture0;
918     D3DMATRIX texture7;
919     D3DMATRIX world0;
920     D3DMATRIX world255;
921 };
922
923 static const struct transform_data transform_default_data =
924 {
925     {{{
926         1.0f, 0.0f, 0.0f, 0.0f,
927         0.0f, 1.0f, 0.0f, 0.0f,
928         0.0f, 0.0f, 1.0f, 0.0f,
929         0.0f, 0.0f, 0.0f, 1.0f,
930     }}},
931     {{{
932         1.0f, 0.0f, 0.0f, 0.0f,
933         0.0f, 1.0f, 0.0f, 0.0f,
934         0.0f, 0.0f, 1.0f, 0.0f,
935         0.0f, 0.0f, 0.0f, 1.0f,
936     }}},
937     {{{
938         1.0f, 0.0f, 0.0f, 0.0f,
939         0.0f, 1.0f, 0.0f, 0.0f,
940         0.0f, 0.0f, 1.0f, 0.0f,
941         0.0f, 0.0f, 0.0f, 1.0f,
942     }}},
943     {{{
944         1.0f, 0.0f, 0.0f, 0.0f,
945         0.0f, 1.0f, 0.0f, 0.0f,
946         0.0f, 0.0f, 1.0f, 0.0f,
947         0.0f, 0.0f, 0.0f, 1.0f,
948     }}},
949     {{{
950         1.0f, 0.0f, 0.0f, 0.0f,
951         0.0f, 1.0f, 0.0f, 0.0f,
952         0.0f, 0.0f, 1.0f, 0.0f,
953         0.0f, 0.0f, 0.0f, 1.0f,
954     }}},
955     {{{
956         1.0f, 0.0f, 0.0f, 0.0f,
957         0.0f, 1.0f, 0.0f, 0.0f,
958         0.0f, 0.0f, 1.0f, 0.0f,
959         0.0f, 0.0f, 0.0f, 1.0f,
960     }}},
961 };
962
963 static const struct transform_data transform_poison_data =
964 {
965     {{{
966          1.0f,  2.0f,  3.0f,  4.0f,
967          5.0f,  6.0f,  7.0f,  8.0f,
968          9.0f, 10.0f, 11.0f, 12.0f,
969         13.0f, 14.0f, 15.0f, 16.0f,
970     }}},
971     {{{
972         17.0f, 18.0f, 19.0f, 20.0f,
973         21.0f, 22.0f, 23.0f, 24.0f,
974         25.0f, 26.0f, 27.0f, 28.0f,
975         29.0f, 30.0f, 31.0f, 32.0f,
976     }}},
977     {{{
978         33.0f, 34.0f, 35.0f, 36.0f,
979         37.0f, 38.0f, 39.0f, 40.0f,
980         41.0f, 42.0f, 43.0f, 44.0f,
981         45.0f, 46.0f, 47.0f, 48.0f
982     }}},
983     {{{
984         49.0f, 50.0f, 51.0f, 52.0f,
985         53.0f, 54.0f, 55.0f, 56.0f,
986         57.0f, 58.0f, 59.0f, 60.0f,
987         61.0f, 62.0f, 63.0f, 64.0f,
988     }}},
989     {{{
990         64.0f, 66.0f, 67.0f, 68.0f,
991         69.0f, 70.0f, 71.0f, 72.0f,
992         73.0f, 74.0f, 75.0f, 76.0f,
993         77.0f, 78.0f, 79.0f, 80.0f,
994     }}},
995     {{{
996         81.0f, 82.0f, 83.0f, 84.0f,
997         85.0f, 86.0f, 87.0f, 88.0f,
998         89.0f, 90.0f, 91.0f, 92.0f,
999         93.0f, 94.0f, 95.0f, 96.0f,
1000     }}},
1001 };
1002
1003 static const struct transform_data transform_test_data =
1004 {
1005     {{{
1006           1.2f,     3.4f,  -5.6f,  7.2f,
1007         10.11f,  -12.13f, 14.15f, -1.5f,
1008         23.56f,   12.89f, 44.56f, -1.0f,
1009           2.3f,     0.0f,   4.4f,  5.5f,
1010     }}},
1011     {{{
1012           9.2f,    38.7f,  -6.6f,  7.2f,
1013         10.11f,  -12.13f, 77.15f, -1.5f,
1014         23.56f,   12.89f, 14.56f, -1.0f,
1015          12.3f,     0.0f,   4.4f,  5.5f,
1016     }}},
1017     {{{
1018          10.2f,     3.4f,   0.6f,  7.2f,
1019         10.11f,  -12.13f, 14.15f, -1.5f,
1020         23.54f,    12.9f, 44.56f, -1.0f,
1021           2.3f,     0.0f,   4.4f,  5.5f,
1022     }}},
1023     {{{
1024           1.2f,     3.4f,  -5.6f,  7.2f,
1025         10.11f,  -12.13f, -14.5f, -1.5f,
1026          2.56f,   12.89f, 23.56f, -1.0f,
1027         112.3f,     0.0f,   4.4f,  2.5f,
1028     }}},
1029     {{{
1030           1.2f,   31.41f,  58.6f,  7.2f,
1031         10.11f,  -12.13f, -14.5f, -1.5f,
1032          2.56f,   12.89f, 11.56f, -1.0f,
1033         112.3f,     0.0f,  44.4f,  2.5f,
1034     }}},
1035     {{{
1036          1.20f,     3.4f,  -5.6f,  7.0f,
1037         10.11f, -12.156f, -14.5f, -1.5f,
1038          2.56f,   1.829f,  23.6f, -1.0f,
1039         112.3f,     0.0f,  41.4f,  2.5f,
1040     }}},
1041 };
1042
1043 static void transform_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1044 {
1045     const struct transform_data *tdata = data;
1046     HRESULT hret;
1047
1048     hret = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &tdata->view);
1049     ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1050
1051     hret = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
1052     ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1053
1054     hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
1055     ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1056
1057     hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
1058     ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1059
1060     hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &tdata->world0);
1061     ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1062
1063     hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
1064     ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1065 }
1066
1067 static void compare_matrix(const char *name, unsigned int chain_stage,
1068         const D3DMATRIX *received, const D3DMATRIX *expected)
1069 {
1070     ok(!memcmp(expected, received, sizeof(*expected)),
1071             "Chain stage %u, matrix %s:\n"
1072             "\t{\n"
1073             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1074             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1075             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1076             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1077             "\t} expected\n"
1078             "\t{\n"
1079             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1080             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1081             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1082             "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1083             "\t} received\n",
1084             chain_stage, name,
1085             U(*expected).m[0][0], U(*expected).m[1][0], U(*expected).m[2][0], U(*expected).m[3][0],
1086             U(*expected).m[0][1], U(*expected).m[1][1], U(*expected).m[2][1], U(*expected).m[3][1],
1087             U(*expected).m[0][2], U(*expected).m[1][2], U(*expected).m[2][2], U(*expected).m[3][2],
1088             U(*expected).m[0][3], U(*expected).m[1][3], U(*expected).m[2][3], U(*expected).m[3][3],
1089             U(*received).m[0][0], U(*received).m[1][0], U(*received).m[2][0], U(*received).m[3][0],
1090             U(*received).m[0][1], U(*received).m[1][1], U(*received).m[2][1], U(*received).m[3][1],
1091             U(*received).m[0][2], U(*received).m[1][2], U(*received).m[2][2], U(*received).m[3][2],
1092             U(*received).m[0][3], U(*received).m[1][3], U(*received).m[2][3], U(*received).m[3][3]);
1093 }
1094
1095 static void transform_check_data(IDirect3DDevice9 *device, const struct state_test *test,
1096         const void *expected_data, unsigned int chain_stage, DWORD quirk)
1097 {
1098     const struct transform_data *tdata = expected_data;
1099     D3DMATRIX value;
1100     HRESULT hr;
1101
1102     value = transform_poison_data.view;
1103     hr = IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &value);
1104     ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1105     compare_matrix("View", chain_stage, &value, &tdata->view);
1106
1107     value = transform_poison_data.projection;
1108     hr = IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &value);
1109     ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1110     compare_matrix("Projection", chain_stage, &value, &tdata->projection);
1111
1112     value = transform_poison_data.texture0;
1113     hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0, &value);
1114     ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1115     compare_matrix("Texture0", chain_stage, &value, &tdata->texture0);
1116
1117     value = transform_poison_data.texture7;
1118     hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &value);
1119     ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1120     compare_matrix("Texture7", chain_stage, &value, &tdata->texture7);
1121
1122     value = transform_poison_data.world0;
1123     hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &value);
1124     ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1125     compare_matrix("World0", chain_stage, &value, &tdata->world0);
1126
1127     value = transform_poison_data.world255;
1128     hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(255), &value);
1129     ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1130     compare_matrix("World255", chain_stage, &value, &tdata->world255);
1131 }
1132
1133 static HRESULT transform_test_init(IDirect3DDevice9 *device, struct state_test *test)
1134 {
1135     test->test_context = NULL;
1136     test->test_data_in = &transform_test_data;
1137     test->test_data_out_all = &transform_test_data;
1138     test->test_data_out_vertex = &transform_default_data;
1139     test->test_data_out_pixel = &transform_default_data;
1140     test->default_data = &transform_default_data;
1141     test->initial_data = &transform_default_data;
1142
1143     return D3D_OK;
1144 }
1145
1146 static void transform_queue_test(struct state_test *test)
1147 {
1148     test->init = transform_test_init;
1149     test->cleanup = NULL;
1150     test->apply_data = transform_apply_data;
1151     test->check_data = transform_check_data;
1152     test->test_name = "set_get_transforms";
1153     test->test_arg = NULL;
1154 }
1155
1156 /* =================== State test: Render States ===================================== */
1157
1158 const D3DRENDERSTATETYPE render_state_indices[] =
1159 {
1160     D3DRS_ZENABLE,
1161     D3DRS_FILLMODE,
1162     D3DRS_SHADEMODE,
1163     D3DRS_ZWRITEENABLE,
1164     D3DRS_ALPHATESTENABLE,
1165     D3DRS_LASTPIXEL,
1166     D3DRS_SRCBLEND,
1167     D3DRS_DESTBLEND,
1168     D3DRS_CULLMODE,
1169     D3DRS_ZFUNC,
1170     D3DRS_ALPHAREF,
1171     D3DRS_ALPHAFUNC,
1172     D3DRS_DITHERENABLE,
1173     D3DRS_ALPHABLENDENABLE,
1174     D3DRS_FOGENABLE,
1175     D3DRS_SPECULARENABLE,
1176     D3DRS_FOGCOLOR,
1177     D3DRS_FOGTABLEMODE,
1178     D3DRS_FOGSTART,
1179     D3DRS_FOGEND,
1180     D3DRS_FOGDENSITY,
1181     D3DRS_RANGEFOGENABLE,
1182     D3DRS_STENCILENABLE,
1183     D3DRS_STENCILFAIL,
1184     D3DRS_STENCILZFAIL,
1185     D3DRS_STENCILPASS,
1186     D3DRS_STENCILFUNC,
1187     D3DRS_STENCILREF,
1188     D3DRS_STENCILMASK,
1189     D3DRS_STENCILWRITEMASK,
1190     D3DRS_TEXTUREFACTOR,
1191     D3DRS_WRAP0,
1192     D3DRS_WRAP1,
1193     D3DRS_WRAP2,
1194     D3DRS_WRAP3,
1195     D3DRS_WRAP4,
1196     D3DRS_WRAP5,
1197     D3DRS_WRAP6,
1198     D3DRS_WRAP7,
1199     D3DRS_CLIPPING,
1200     D3DRS_LIGHTING,
1201     D3DRS_AMBIENT,
1202     D3DRS_FOGVERTEXMODE,
1203     D3DRS_COLORVERTEX,
1204     D3DRS_LOCALVIEWER,
1205     D3DRS_NORMALIZENORMALS,
1206     D3DRS_DIFFUSEMATERIALSOURCE,
1207     D3DRS_SPECULARMATERIALSOURCE,
1208     D3DRS_AMBIENTMATERIALSOURCE,
1209     D3DRS_EMISSIVEMATERIALSOURCE,
1210     D3DRS_VERTEXBLEND,
1211     D3DRS_CLIPPLANEENABLE,
1212 #if 0 /* Driver dependent */
1213     D3DRS_POINTSIZE,
1214 #endif
1215     D3DRS_POINTSIZE_MIN,
1216     D3DRS_POINTSPRITEENABLE,
1217     D3DRS_POINTSCALEENABLE,
1218     D3DRS_POINTSCALE_A,
1219     D3DRS_POINTSCALE_B,
1220     D3DRS_POINTSCALE_C,
1221     D3DRS_MULTISAMPLEANTIALIAS,
1222     D3DRS_MULTISAMPLEMASK,
1223     D3DRS_PATCHEDGESTYLE,
1224 #if 0 /* Apparently not recorded in the stateblock */
1225     D3DRS_DEBUGMONITORTOKEN,
1226 #endif
1227     D3DRS_POINTSIZE_MAX,
1228     D3DRS_INDEXEDVERTEXBLENDENABLE,
1229     D3DRS_COLORWRITEENABLE,
1230     D3DRS_TWEENFACTOR,
1231     D3DRS_BLENDOP,
1232     D3DRS_POSITIONDEGREE,
1233     D3DRS_NORMALDEGREE,
1234     D3DRS_SCISSORTESTENABLE,
1235     D3DRS_SLOPESCALEDEPTHBIAS,
1236     D3DRS_ANTIALIASEDLINEENABLE,
1237     D3DRS_MINTESSELLATIONLEVEL,
1238     D3DRS_MAXTESSELLATIONLEVEL,
1239     D3DRS_ADAPTIVETESS_X,
1240     D3DRS_ADAPTIVETESS_Y,
1241     D3DRS_ADAPTIVETESS_Z,
1242     D3DRS_ADAPTIVETESS_W,
1243     D3DRS_ENABLEADAPTIVETESSELLATION,
1244     D3DRS_TWOSIDEDSTENCILMODE,
1245     D3DRS_CCW_STENCILFAIL,
1246     D3DRS_CCW_STENCILZFAIL,
1247     D3DRS_CCW_STENCILPASS,
1248     D3DRS_CCW_STENCILFUNC,
1249     D3DRS_COLORWRITEENABLE1,
1250     D3DRS_COLORWRITEENABLE2,
1251     D3DRS_COLORWRITEENABLE3,
1252     D3DRS_BLENDFACTOR,
1253     D3DRS_SRGBWRITEENABLE,
1254     D3DRS_DEPTHBIAS,
1255     D3DRS_WRAP8,
1256     D3DRS_WRAP9,
1257     D3DRS_WRAP10,
1258     D3DRS_WRAP11,
1259     D3DRS_WRAP12,
1260     D3DRS_WRAP13,
1261     D3DRS_WRAP14,
1262     D3DRS_WRAP15,
1263     D3DRS_SEPARATEALPHABLENDENABLE,
1264     D3DRS_SRCBLENDALPHA,
1265     D3DRS_DESTBLENDALPHA,
1266     D3DRS_BLENDOPALPHA,
1267 };
1268
1269 struct render_state_data
1270 {
1271     DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1272 };
1273
1274 struct render_state_arg
1275 {
1276     D3DPRESENT_PARAMETERS *device_pparams;
1277     float pointsize_max;
1278 };
1279
1280 struct render_state_context
1281 {
1282     struct render_state_data default_data_buffer;
1283     struct render_state_data test_data_all_buffer;
1284     struct render_state_data test_data_vertex_buffer;
1285     struct render_state_data test_data_pixel_buffer;
1286     struct render_state_data poison_data_buffer;
1287 };
1288
1289 static void render_state_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1290 {
1291     const struct render_state_data *rsdata = data;
1292     HRESULT hret;
1293     unsigned int i;
1294
1295     for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1296     {
1297         hret = IDirect3DDevice9_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1298         ok(hret == D3D_OK, "SetRenderState returned %#x.\n", hret);
1299     }
1300 }
1301
1302 static void render_state_check_data(IDirect3DDevice9 *device, const struct state_test *test,
1303         const void *expected_data, unsigned int chain_stage, DWORD quirk)
1304 {
1305     const struct render_state_context *ctx = test->test_context;
1306     const struct render_state_data *rsdata = expected_data;
1307     unsigned int i;
1308     HRESULT hr;
1309
1310     for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1311     {
1312         DWORD value = ctx->poison_data_buffer.states[i];
1313         hr = IDirect3DDevice9_GetRenderState(device, render_state_indices[i], &value);
1314         ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1315         ok(value == rsdata->states[i], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1316                 chain_stage, render_state_indices[i], rsdata->states[i], value);
1317     }
1318 }
1319
1320 static inline DWORD to_dword(float fl) {
1321     return *((DWORD*) &fl);
1322 }
1323
1324 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1325 {
1326    DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1327    unsigned int idx = 0;
1328
1329    data->states[idx++] = zenable;               /* ZENABLE */
1330    data->states[idx++] = D3DFILL_SOLID;         /* FILLMODE */
1331    data->states[idx++] = D3DSHADE_GOURAUD;      /* SHADEMODE */
1332    data->states[idx++] = TRUE;                  /* ZWRITEENABLE */
1333    data->states[idx++] = FALSE;                 /* ALPHATESTENABLE */
1334    data->states[idx++] = TRUE;                  /* LASTPIXEL */
1335    data->states[idx++] = D3DBLEND_ONE;          /* SRCBLEND */
1336    data->states[idx++] = D3DBLEND_ZERO;         /* DESTBLEND */
1337    data->states[idx++] = D3DCULL_CCW;           /* CULLMODE */
1338    data->states[idx++] = D3DCMP_LESSEQUAL;      /* ZFUNC */
1339    data->states[idx++] = 0;                     /* ALPHAREF */
1340    data->states[idx++] = D3DCMP_ALWAYS;         /* ALPHAFUNC */
1341    data->states[idx++] = FALSE;                 /* DITHERENABLE */
1342    data->states[idx++] = FALSE;                 /* ALPHABLENDENABLE */
1343    data->states[idx++] = FALSE;                 /* FOGENABLE */
1344    data->states[idx++] = FALSE;                 /* SPECULARENABLE */
1345    data->states[idx++] = 0;                     /* FOGCOLOR */
1346    data->states[idx++] = D3DFOG_NONE;           /* FOGTABLEMODE */
1347    data->states[idx++] = to_dword(0.0f);        /* FOGSTART */
1348    data->states[idx++] = to_dword(1.0f);        /* FOGEND */
1349    data->states[idx++] = to_dword(1.0f);        /* FOGDENSITY */
1350    data->states[idx++] = FALSE;                 /* RANGEFOGENABLE */
1351    data->states[idx++] = FALSE;                 /* STENCILENABLE */
1352    data->states[idx++] = D3DSTENCILOP_KEEP;     /* STENCILFAIL */
1353    data->states[idx++] = D3DSTENCILOP_KEEP;     /* STENCILZFAIL */
1354    data->states[idx++] = D3DSTENCILOP_KEEP;     /* STENCILPASS */
1355    data->states[idx++] = D3DCMP_ALWAYS;         /* STENCILFUNC */
1356    data->states[idx++] = 0;                     /* STENCILREF */
1357    data->states[idx++] = 0xFFFFFFFF;            /* STENCILMASK */
1358    data->states[idx++] = 0xFFFFFFFF;            /* STENCILWRITEMASK */
1359    data->states[idx++] = 0xFFFFFFFF;            /* TEXTUREFACTOR */
1360    data->states[idx++] = 0;                     /* WRAP 0 */
1361    data->states[idx++] = 0;                     /* WRAP 1 */
1362    data->states[idx++] = 0;                     /* WRAP 2 */
1363    data->states[idx++] = 0;                     /* WRAP 3 */
1364    data->states[idx++] = 0;                     /* WRAP 4 */
1365    data->states[idx++] = 0;                     /* WRAP 5 */
1366    data->states[idx++] = 0;                     /* WRAP 6 */
1367    data->states[idx++] = 0;                     /* WRAP 7 */
1368    data->states[idx++] = TRUE;                  /* CLIPPING */
1369    data->states[idx++] = TRUE;                  /* LIGHTING */
1370    data->states[idx++] = 0;                     /* AMBIENT */
1371    data->states[idx++] = D3DFOG_NONE;           /* FOGVERTEXMODE */
1372    data->states[idx++] = TRUE;                  /* COLORVERTEX */
1373    data->states[idx++] = TRUE;                  /* LOCALVIEWER */
1374    data->states[idx++] = FALSE;                 /* NORMALIZENORMALS */
1375    data->states[idx++] = D3DMCS_COLOR1;         /* DIFFUSEMATERIALSOURCE */
1376    data->states[idx++] = D3DMCS_COLOR2;         /* SPECULARMATERIALSOURCE */
1377    data->states[idx++] = D3DMCS_MATERIAL;       /* AMBIENTMATERIALSOURCE */
1378    data->states[idx++] = D3DMCS_MATERIAL;       /* EMISSIVEMATERIALSOURCE */
1379    data->states[idx++] = D3DVBF_DISABLE;        /* VERTEXBLEND */
1380    data->states[idx++] = 0;                     /* CLIPPLANEENABLE */
1381 #if 0 /* Driver dependent, increase array size to enable */
1382    data->states[idx++] = to_dword(1.0f);       /* POINTSIZE */
1383 #endif
1384    data->states[idx++] = to_dword(1.0f);        /* POINTSIZEMIN */
1385    data->states[idx++] = FALSE;                 /* POINTSPRITEENABLE */
1386    data->states[idx++] = FALSE;                 /* POINTSCALEENABLE */
1387    data->states[idx++] = to_dword(1.0f);        /* POINTSCALE_A */
1388    data->states[idx++] = to_dword(0.0f);        /* POINTSCALE_B */
1389    data->states[idx++] = to_dword(0.0f);        /* POINTSCALE_C */
1390    data->states[idx++] = TRUE;                  /* MULTISAMPLEANTIALIAS */
1391    data->states[idx++] = 0xFFFFFFFF;            /* MULTISAMPLEMASK */
1392    data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1393    if (0) data->states[idx++] = 0xbaadcafe;     /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1394    data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1395    data->states[idx++] = FALSE;                 /* INDEXEDVERTEXBLENDENABLE */
1396    data->states[idx++] = 0x0000000F;            /* COLORWRITEENABLE */
1397    data->states[idx++] = to_dword(0.0f);        /* TWEENFACTOR */
1398    data->states[idx++] = D3DBLENDOP_ADD;        /* BLENDOP */
1399    data->states[idx++] = D3DDEGREE_CUBIC;       /* POSITIONDEGREE */
1400    data->states[idx++] = D3DDEGREE_LINEAR;      /* NORMALDEGREE */
1401    data->states[idx++] = FALSE;                 /* SCISSORTESTENABLE */
1402    data->states[idx++] = to_dword(0.0f);        /* SLOPESCALEDEPTHBIAS */
1403    data->states[idx++] = FALSE;                 /* ANTIALIASEDLINEENABLE */
1404    data->states[idx++] = to_dword(1.0f);        /* MINTESSELATIONLEVEL */
1405    data->states[idx++] = to_dword(1.0f);        /* MAXTESSELATIONLEVEL */
1406    data->states[idx++] = to_dword(0.0f);        /* ADAPTIVETESS_X */
1407    data->states[idx++] = to_dword(0.0f);        /* ADAPTIVETESS_Y */
1408    data->states[idx++] = to_dword(1.0f);        /* ADAPTIVETESS_Z */
1409    data->states[idx++] = to_dword(0.0f);        /* ADAPTIVETESS_W */
1410    data->states[idx++] = FALSE;                 /* ENABLEADAPTIVETESSELATION */
1411    data->states[idx++] = FALSE;                 /* TWOSIDEDSTENCILMODE */
1412    data->states[idx++] = D3DSTENCILOP_KEEP;     /* CCW_STENCILFAIL */
1413    data->states[idx++] = D3DSTENCILOP_KEEP;     /* CCW_STENCILZFAIL */
1414    data->states[idx++] = D3DSTENCILOP_KEEP;     /* CCW_STENCILPASS */
1415    data->states[idx++] = D3DCMP_ALWAYS;         /* CCW_STENCILFUNC */
1416    data->states[idx++] = 0x0000000F;            /* COLORWRITEENABLE1 */
1417    data->states[idx++] = 0x0000000F;            /* COLORWRITEENABLE2 */
1418    data->states[idx++] = 0x0000000F;            /* COLORWRITEENABLE3 */
1419    data->states[idx++] = 0xFFFFFFFF;            /* BLENDFACTOR */
1420    data->states[idx++] = 0;                     /* SRGBWRITEENABLE */
1421    data->states[idx++] = to_dword(0.0f);        /* DEPTHBIAS */
1422    data->states[idx++] = 0;                     /* WRAP8 */
1423    data->states[idx++] = 0;                     /* WRAP9 */
1424    data->states[idx++] = 0;                     /* WRAP10 */
1425    data->states[idx++] = 0;                     /* WRAP11 */
1426    data->states[idx++] = 0;                     /* WRAP12 */
1427    data->states[idx++] = 0;                     /* WRAP13 */
1428    data->states[idx++] = 0;                     /* WRAP14 */
1429    data->states[idx++] = 0;                     /* WRAP15 */
1430    data->states[idx++] = FALSE;                 /* SEPARATEALPHABLENDENABLE */
1431    data->states[idx++] = D3DBLEND_ONE;          /* SRCBLENDALPHA */
1432    data->states[idx++] = D3DBLEND_ZERO;         /* DESTBLENDALPHA */
1433    data->states[idx++] = TRUE;                  /* BLENDOPALPHA */
1434 }
1435
1436 static void render_state_poison_data_init(struct render_state_data *data)
1437 {
1438     unsigned int i;
1439
1440     for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1441     {
1442        data->states[i] = 0x1337c0de;
1443     }
1444 }
1445
1446 static void render_state_test_data_init(struct render_state_data *data)
1447 {
1448    unsigned int idx = 0;
1449    data->states[idx++] = D3DZB_USEW;            /* ZENABLE */
1450    data->states[idx++] = D3DFILL_WIREFRAME;     /* FILLMODE */
1451    data->states[idx++] = D3DSHADE_PHONG;        /* SHADEMODE */
1452    data->states[idx++] = FALSE;                 /* ZWRITEENABLE */
1453    data->states[idx++] = TRUE;                  /* ALPHATESTENABLE */
1454    data->states[idx++] = FALSE;                 /* LASTPIXEL */
1455    data->states[idx++] = D3DBLEND_SRCALPHASAT;  /* SRCBLEND */
1456    data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1457    data->states[idx++] = D3DCULL_CW;            /* CULLMODE */
1458    data->states[idx++] = D3DCMP_NOTEQUAL;       /* ZFUNC */
1459    data->states[idx++] = 10;                    /* ALPHAREF */
1460    data->states[idx++] = D3DCMP_GREATER;        /* ALPHAFUNC */
1461    data->states[idx++] = TRUE;                  /* DITHERENABLE */
1462    data->states[idx++] = TRUE;                  /* ALPHABLENDENABLE */
1463    data->states[idx++] = TRUE;                  /* FOGENABLE */
1464    data->states[idx++] = TRUE;                  /* SPECULARENABLE */
1465    data->states[idx++] = 255 << 31;             /* FOGCOLOR */
1466    data->states[idx++] = D3DFOG_EXP;            /* FOGTABLEMODE */
1467    data->states[idx++] = to_dword(0.1f);        /* FOGSTART */
1468    data->states[idx++] = to_dword(0.8f);        /* FOGEND */
1469    data->states[idx++] = to_dword(0.5f);        /* FOGDENSITY */
1470    data->states[idx++] = TRUE;                  /* RANGEFOGENABLE */
1471    data->states[idx++] = TRUE;                  /* STENCILENABLE */
1472    data->states[idx++] = D3DSTENCILOP_INCRSAT;  /* STENCILFAIL */
1473    data->states[idx++] = D3DSTENCILOP_REPLACE;  /* STENCILZFAIL */
1474    data->states[idx++] = D3DSTENCILOP_INVERT;   /* STENCILPASS */
1475    data->states[idx++] = D3DCMP_LESS;           /* STENCILFUNC */
1476    data->states[idx++] = 10;                    /* STENCILREF */
1477    data->states[idx++] = 0xFF00FF00;            /* STENCILMASK */
1478    data->states[idx++] = 0x00FF00FF;            /* STENCILWRITEMASK */
1479    data->states[idx++] = 0xF0F0F0F0;            /* TEXTUREFACTOR */
1480    data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2;                                   /* WRAP 0 */
1481    data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3;                                   /* WRAP 1 */
1482    data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3;                                   /* WRAP 2 */
1483    data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0;                                   /* WRAP 4 */
1484    data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2;                  /* WRAP 5 */
1485    data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2;                  /* WRAP 6 */
1486    data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0;                  /* WRAP 7 */
1487    data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1488    data->states[idx++] = FALSE;                 /* CLIPPING */
1489    data->states[idx++] = FALSE;                 /* LIGHTING */
1490    data->states[idx++] = 255 << 16;             /* AMBIENT */
1491    data->states[idx++] = D3DFOG_EXP2;           /* FOGVERTEXMODE */
1492    data->states[idx++] = FALSE;                 /* COLORVERTEX */
1493    data->states[idx++] = FALSE;                 /* LOCALVIEWER */
1494    data->states[idx++] = TRUE;                  /* NORMALIZENORMALS */
1495    data->states[idx++] = D3DMCS_COLOR2;         /* DIFFUSEMATERIALSOURCE */
1496    data->states[idx++] = D3DMCS_MATERIAL;       /* SPECULARMATERIALSOURCE */
1497    data->states[idx++] = D3DMCS_COLOR1;         /* AMBIENTMATERIALSOURCE */
1498    data->states[idx++] = D3DMCS_COLOR2;         /* EMISSIVEMATERIALSOURCE */
1499    data->states[idx++] = D3DVBF_3WEIGHTS;       /* VERTEXBLEND */
1500    data->states[idx++] = 0xf1f1f1f1;            /* CLIPPLANEENABLE */
1501 #if 0 /* Driver dependent, increase array size to enable */
1502    data->states[idx++] = to_dword(32.0f);       /* POINTSIZE */
1503 #endif
1504    data->states[idx++] = to_dword(0.7f);        /* POINTSIZEMIN */
1505    data->states[idx++] = TRUE;                  /* POINTSPRITEENABLE */
1506    data->states[idx++] = TRUE;                  /* POINTSCALEENABLE */
1507    data->states[idx++] = to_dword(0.7f);        /* POINTSCALE_A */
1508    data->states[idx++] = to_dword(0.5f);        /* POINTSCALE_B */
1509    data->states[idx++] = to_dword(0.4f);        /* POINTSCALE_C */
1510    data->states[idx++] = FALSE;                 /* MULTISAMPLEANTIALIAS */
1511    data->states[idx++] = 0xABCDDBCA;            /* MULTISAMPLEMASK */
1512    data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1513    if (0) data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1514    data->states[idx++] = to_dword(77.0f);       /* POINTSIZE_MAX */
1515    data->states[idx++] = TRUE;                  /* INDEXEDVERTEXBLENDENABLE */
1516    data->states[idx++] = 0x00000009;            /* COLORWRITEENABLE */
1517    data->states[idx++] = to_dword(0.2f);        /* TWEENFACTOR */
1518    data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1519    data->states[idx++] = D3DDEGREE_LINEAR;      /* POSITIONDEGREE */
1520    data->states[idx++] = D3DDEGREE_CUBIC;       /* NORMALDEGREE */
1521    data->states[idx++] = TRUE;                  /* SCISSORTESTENABLE */
1522    data->states[idx++] = to_dword(0.33f);       /* SLOPESCALEDEPTHBIAS */
1523    data->states[idx++] = TRUE;                  /* ANTIALIASEDLINEENABLE */
1524    data->states[idx++] = to_dword(0.8f);        /* MINTESSELATIONLEVEL */
1525    data->states[idx++] = to_dword(0.8f);        /* MAXTESSELATIONLEVEL */
1526    data->states[idx++] = to_dword(0.2f);        /* ADAPTIVETESS_X */
1527    data->states[idx++] = to_dword(0.3f);        /* ADAPTIVETESS_Y */
1528    data->states[idx++] = to_dword(0.6f);        /* ADAPTIVETESS_Z */
1529    data->states[idx++] = to_dword(0.4f);        /* ADAPTIVETESS_W */
1530    data->states[idx++] = TRUE;                  /* ENABLEADAPTIVETESSELATION */
1531    data->states[idx++] = TRUE;                  /* TWOSIDEDSTENCILMODE */
1532    data->states[idx++] = D3DSTENCILOP_ZERO;     /* CCW_STENCILFAIL */
1533    data->states[idx++] = D3DSTENCILOP_DECR;     /* CCW_STENCILZFAIL */
1534    data->states[idx++] = D3DSTENCILOP_INCR;     /* CCW_STENCILPASS */
1535    data->states[idx++] = D3DCMP_ALWAYS;         /* CCW_STENCILFUNC */
1536    data->states[idx++] = 0x00000007;            /* COLORWRITEENABLE1 */
1537    data->states[idx++] = 0x00000008;            /* COLORWRITEENABLE2 */
1538    data->states[idx++] = 0x00000004;            /* COLORWRITEENABLE3 */
1539    data->states[idx++] = 0xF0F1F2F3;            /* BLENDFACTOR */
1540    data->states[idx++] = 1;                     /* SRGBWRITEENABLE */
1541    data->states[idx++] = to_dword(0.3f);        /* DEPTHBIAS */
1542    data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2;                                   /* WRAP 8 */
1543    data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3;                                   /* WRAP 9 */
1544    data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3;                                   /* WRAP 10 */
1545    data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0;                                   /* WRAP 11 */
1546    data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2;                  /* WRAP 12 */
1547    data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2;                  /* WRAP 13 */
1548    data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0;                  /* WRAP 14 */
1549    data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 15 */
1550    data->states[idx++] = TRUE;                  /* SEPARATEALPHABLENDENABLE */
1551    data->states[idx++] = D3DBLEND_ZERO;         /* SRCBLENDALPHA */
1552    data->states[idx++] = D3DBLEND_ONE;          /* DESTBLENDALPHA */
1553    data->states[idx++] = FALSE;                 /* BLENDOPALPHA */
1554 }
1555
1556 static HRESULT render_state_test_init(IDirect3DDevice9 *device, struct state_test *test)
1557 {
1558     static const DWORD states_vertex[] =
1559     {
1560         D3DRS_ADAPTIVETESS_W,
1561         D3DRS_ADAPTIVETESS_X,
1562         D3DRS_ADAPTIVETESS_Y,
1563         D3DRS_ADAPTIVETESS_Z,
1564         D3DRS_AMBIENT,
1565         D3DRS_AMBIENTMATERIALSOURCE,
1566         D3DRS_CLIPPING,
1567         D3DRS_CLIPPLANEENABLE,
1568         D3DRS_COLORVERTEX,
1569         D3DRS_CULLMODE,
1570         D3DRS_DIFFUSEMATERIALSOURCE,
1571         D3DRS_EMISSIVEMATERIALSOURCE,
1572         D3DRS_ENABLEADAPTIVETESSELLATION,
1573         D3DRS_FOGCOLOR,
1574         D3DRS_FOGDENSITY,
1575         D3DRS_FOGENABLE,
1576         D3DRS_FOGEND,
1577         D3DRS_FOGSTART,
1578         D3DRS_FOGTABLEMODE,
1579         D3DRS_FOGVERTEXMODE,
1580         D3DRS_INDEXEDVERTEXBLENDENABLE,
1581         D3DRS_LIGHTING,
1582         D3DRS_LOCALVIEWER,
1583         D3DRS_MAXTESSELLATIONLEVEL,
1584         D3DRS_MINTESSELLATIONLEVEL,
1585         D3DRS_MULTISAMPLEANTIALIAS,
1586         D3DRS_MULTISAMPLEMASK,
1587         D3DRS_NORMALDEGREE,
1588         D3DRS_NORMALIZENORMALS,
1589         D3DRS_PATCHEDGESTYLE,
1590         D3DRS_POINTSCALE_A,
1591         D3DRS_POINTSCALE_B,
1592         D3DRS_POINTSCALE_C,
1593         D3DRS_POINTSCALEENABLE,
1594         D3DRS_POINTSIZE,
1595         D3DRS_POINTSIZE_MAX,
1596         D3DRS_POINTSIZE_MIN,
1597         D3DRS_POINTSPRITEENABLE,
1598         D3DRS_POSITIONDEGREE,
1599         D3DRS_RANGEFOGENABLE,
1600         D3DRS_SHADEMODE,
1601         D3DRS_SPECULARENABLE,
1602         D3DRS_SPECULARMATERIALSOURCE,
1603         D3DRS_TWEENFACTOR,
1604         D3DRS_VERTEXBLEND,
1605     };
1606
1607     static const DWORD states_pixel[] =
1608     {
1609         D3DRS_ALPHABLENDENABLE,
1610         D3DRS_ALPHAFUNC,
1611         D3DRS_ALPHAREF,
1612         D3DRS_ALPHATESTENABLE,
1613         D3DRS_ANTIALIASEDLINEENABLE,
1614         D3DRS_BLENDFACTOR,
1615         D3DRS_BLENDOP,
1616         D3DRS_BLENDOPALPHA,
1617         D3DRS_CCW_STENCILFAIL,
1618         D3DRS_CCW_STENCILPASS,
1619         D3DRS_CCW_STENCILZFAIL,
1620         D3DRS_COLORWRITEENABLE,
1621         D3DRS_COLORWRITEENABLE1,
1622         D3DRS_COLORWRITEENABLE2,
1623         D3DRS_COLORWRITEENABLE3,
1624         D3DRS_DEPTHBIAS,
1625         D3DRS_DESTBLEND,
1626         D3DRS_DESTBLENDALPHA,
1627         D3DRS_DITHERENABLE,
1628         D3DRS_FILLMODE,
1629         D3DRS_FOGDENSITY,
1630         D3DRS_FOGEND,
1631         D3DRS_FOGSTART,
1632         D3DRS_LASTPIXEL,
1633         D3DRS_SCISSORTESTENABLE,
1634         D3DRS_SEPARATEALPHABLENDENABLE,
1635         D3DRS_SHADEMODE,
1636         D3DRS_SLOPESCALEDEPTHBIAS,
1637         D3DRS_SRCBLEND,
1638         D3DRS_SRCBLENDALPHA,
1639         D3DRS_SRGBWRITEENABLE,
1640         D3DRS_STENCILENABLE,
1641         D3DRS_STENCILFAIL,
1642         D3DRS_STENCILFUNC,
1643         D3DRS_STENCILMASK,
1644         D3DRS_STENCILPASS,
1645         D3DRS_STENCILREF,
1646         D3DRS_STENCILWRITEMASK,
1647         D3DRS_STENCILZFAIL,
1648         D3DRS_TEXTUREFACTOR,
1649         D3DRS_TWOSIDEDSTENCILMODE,
1650         D3DRS_WRAP0,
1651         D3DRS_WRAP1,
1652         D3DRS_WRAP10,
1653         D3DRS_WRAP11,
1654         D3DRS_WRAP12,
1655         D3DRS_WRAP13,
1656         D3DRS_WRAP14,
1657         D3DRS_WRAP15,
1658         D3DRS_WRAP2,
1659         D3DRS_WRAP3,
1660         D3DRS_WRAP4,
1661         D3DRS_WRAP5,
1662         D3DRS_WRAP6,
1663         D3DRS_WRAP7,
1664         D3DRS_WRAP8,
1665         D3DRS_WRAP9,
1666         D3DRS_ZENABLE,
1667         D3DRS_ZFUNC,
1668         D3DRS_ZWRITEENABLE,
1669     };
1670
1671     const struct render_state_arg *rsarg = test->test_arg;
1672     unsigned int i, j;
1673
1674     struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1675     if (ctx == NULL) return E_FAIL;
1676     test->test_context = ctx;
1677
1678     test->default_data = &ctx->default_data_buffer;
1679     test->initial_data = &ctx->default_data_buffer;
1680     test->test_data_in = &ctx->test_data_all_buffer;
1681     test->test_data_out_all = &ctx->test_data_all_buffer;
1682     test->test_data_out_vertex = &ctx->test_data_vertex_buffer;
1683     test->test_data_out_pixel = &ctx->test_data_pixel_buffer;
1684
1685     render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1686     render_state_test_data_init(&ctx->test_data_all_buffer);
1687     render_state_poison_data_init(&ctx->poison_data_buffer);
1688
1689     for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1690     {
1691         ctx->test_data_vertex_buffer.states[i] = ctx->default_data_buffer.states[i];
1692         for (j = 0; j < sizeof(states_vertex) / sizeof(*states_vertex); ++j)
1693         {
1694             if (render_state_indices[i] == states_vertex[j])
1695             {
1696                 ctx->test_data_vertex_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1697                 break;
1698             }
1699         }
1700
1701         ctx->test_data_pixel_buffer.states[i] = ctx->default_data_buffer.states[i];
1702         for (j = 0; j < sizeof(states_pixel) / sizeof(*states_pixel); ++j)
1703         {
1704             if (render_state_indices[i] == states_pixel[j])
1705             {
1706                 ctx->test_data_pixel_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1707                 break;
1708             }
1709         }
1710     }
1711
1712     return D3D_OK;
1713 }
1714
1715 static void render_state_test_cleanup(IDirect3DDevice9 *device, struct state_test *test)
1716 {
1717     HeapFree(GetProcessHeap(), 0, test->test_context);
1718 }
1719
1720 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1721 {
1722     test->init = render_state_test_init;
1723     test->cleanup = render_state_test_cleanup;
1724     test->apply_data = render_state_apply_data;
1725     test->check_data = render_state_check_data;
1726     test->test_name = "set_get_render_states";
1727     test->test_arg = test_arg;
1728 }
1729
1730 /* resource tests */
1731
1732 struct resource_test_arg
1733 {
1734     DWORD vs_version;
1735     DWORD ps_version;
1736     UINT stream_count;
1737     UINT tex_count;
1738 };
1739
1740 struct resource_test_data
1741 {
1742     IDirect3DVertexDeclaration9 *decl;
1743     IDirect3DVertexShader9 *vs;
1744     IDirect3DPixelShader9 *ps;
1745     IDirect3DIndexBuffer9 *ib;
1746     IDirect3DVertexBuffer9 **vb;
1747     IDirect3DTexture9 **tex;
1748 };
1749
1750 struct resource_test_context
1751 {
1752     struct resource_test_data default_data;
1753     struct resource_test_data test_data_all;
1754     struct resource_test_data test_data_vertex;
1755     struct resource_test_data test_data_pixel;
1756     struct resource_test_data poison_data;
1757 };
1758
1759 static void resource_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1760 {
1761     const struct resource_test_arg *arg = test->test_arg;
1762     const struct resource_test_data *d = data;
1763     unsigned int i;
1764     HRESULT hr;
1765
1766     hr = IDirect3DDevice9_SetVertexDeclaration(device, d->decl);
1767     ok(SUCCEEDED(hr), "SetVertexDeclaration (%p) returned %#x.\n", d->decl, hr);
1768
1769     hr = IDirect3DDevice9_SetVertexShader(device, d->vs);
1770     ok(SUCCEEDED(hr), "SetVertexShader (%p) returned %#x.\n", d->vs, hr);
1771
1772     hr = IDirect3DDevice9_SetPixelShader(device, d->ps);
1773     ok(SUCCEEDED(hr), "SetPixelShader (%p) returned %#x.\n", d->ps, hr);
1774
1775     hr = IDirect3DDevice9_SetIndices(device, d->ib);
1776     ok(SUCCEEDED(hr), "SetIndices (%p) returned %#x.\n", d->ib, hr);
1777
1778     for (i = 0; i < arg->stream_count; ++i)
1779     {
1780         hr = IDirect3DDevice9_SetStreamSource(device, i, d->vb[i], 0, 64);
1781         ok(SUCCEEDED(hr), "SetStreamSource (%u, %p, 0, 64) returned %#x.\n",
1782                 i, d->vb[i], hr);
1783     }
1784
1785     for (i = 0; i < arg->tex_count; ++i)
1786     {
1787         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)d->tex[i]);
1788         ok(SUCCEEDED(hr), "SetTexture (%u, %p) returned %#x.\n", i, d->tex[i], hr);
1789     }
1790 }
1791
1792 static void resource_check_data(IDirect3DDevice9 *device, const struct state_test *test,
1793         const void *expected_data, unsigned int chain_stage, DWORD quirk)
1794 {
1795     const struct resource_test_context *ctx = test->test_context;
1796     const struct resource_test_data *poison = &ctx->poison_data;
1797     const struct resource_test_arg *arg = test->test_arg;
1798     const struct resource_test_data *d = expected_data;
1799     unsigned int i;
1800     HRESULT hr;
1801     void *ptr;
1802     DWORD v, w;
1803
1804     ptr = poison->decl;
1805     hr = IDirect3DDevice9_GetVertexDeclaration(device, (IDirect3DVertexDeclaration9 **)&ptr);
1806     ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x.\n", hr);
1807     if (quirk & SB_QUIRK_RECORDED_VDECL_CAPTURE)
1808     {
1809         ok(ptr == ctx->test_data_all.decl, "Chain stage %u, expected vertex declaration %p, received %p.\n",
1810                 chain_stage, ctx->test_data_all.decl, ptr);
1811     }
1812     else
1813     {
1814         ok(ptr == d->decl, "Chain stage %u, expected vertex declaration %p, received %p.\n",
1815                 chain_stage, d->decl, ptr);
1816     }
1817     if (SUCCEEDED(hr) && ptr)
1818     {
1819         IDirect3DVertexDeclaration9_Release((IDirect3DVertexDeclaration9 *)ptr);
1820     }
1821
1822     ptr = poison->vs;
1823     hr = IDirect3DDevice9_GetVertexShader(device, (IDirect3DVertexShader9 **)&ptr);
1824     ok(SUCCEEDED(hr), "GetVertexShader returned %#x.\n", hr);
1825     ok(ptr == d->vs, "Chain stage %u, expected vertex shader %p, received %p.\n",
1826             chain_stage, d->vs, ptr);
1827     if (SUCCEEDED(hr) && ptr)
1828     {
1829         IDirect3DVertexShader9_Release((IDirect3DVertexShader9 *)ptr);
1830     }
1831
1832     ptr = poison->ps;
1833     hr = IDirect3DDevice9_GetPixelShader(device, (IDirect3DPixelShader9 **)&ptr);
1834     ok(SUCCEEDED(hr), "GetPixelShader returned %#x.\n", hr);
1835     ok(ptr == d->ps, "Chain stage %u, expected pixel shader %p, received %p.\n",
1836             chain_stage, d->ps, ptr);
1837     if (SUCCEEDED(hr) && ptr)
1838     {
1839         IDirect3DPixelShader9_Release((IDirect3DPixelShader9 *)ptr);
1840     }
1841
1842     ptr = poison->ib;
1843     hr = IDirect3DDevice9_GetIndices(device, (IDirect3DIndexBuffer9 **)&ptr);
1844     ok(SUCCEEDED(hr), "GetIndices returned %#x.\n", hr);
1845     ok(ptr == d->ib, "Chain stage %u, expected index buffer %p, received %p.\n",
1846             chain_stage, d->ib, ptr);
1847     if (SUCCEEDED(hr) && ptr)
1848     {
1849         IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)ptr);
1850     }
1851
1852     for (i = 0; i < arg->stream_count; ++i)
1853     {
1854         ptr = poison->vb[i];
1855         hr = IDirect3DDevice9_GetStreamSource(device, i, (IDirect3DVertexBuffer9 **)&ptr, &v, &w);
1856         ok(SUCCEEDED(hr), "GetStreamSource (%u) returned %#x.\n", i, hr);
1857         ok(ptr == d->vb[i], "Chain stage %u, stream %u, expected vertex buffer %p, received %p.\n",
1858                 chain_stage, i, d->vb[i], ptr);
1859         if (SUCCEEDED(hr) && ptr)
1860         {
1861             IDirect3DIndexBuffer9_Release((IDirect3DVertexBuffer9 *)ptr);
1862         }
1863     }
1864
1865     for (i = 0; i < arg->tex_count; ++i)
1866     {
1867         ptr = poison->tex[i];
1868         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **)&ptr);
1869         ok(SUCCEEDED(hr), "SetTexture (%u) returned %#x.\n", i, hr);
1870         ok(ptr == d->tex[i], "Chain stage %u, texture stage %u, expected texture %p, received %p.\n",
1871                 chain_stage, i, d->tex[i], ptr);
1872         if (SUCCEEDED(hr) && ptr)
1873         {
1874             IDirect3DBaseTexture9_Release((IDirect3DBaseTexture9 *)ptr);
1875         }
1876     }
1877 }
1878
1879 static void resource_default_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1880 {
1881     unsigned int i;
1882
1883     data->decl = NULL;
1884     data->vs = NULL;
1885     data->ps = NULL;
1886     data->ib = NULL;
1887     data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1888     for (i = 0; i < arg->stream_count; ++i)
1889     {
1890         data->vb[i] = NULL;
1891     }
1892     data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1893     for (i = 0; i < arg->tex_count; ++i)
1894     {
1895         data->tex[i] = NULL;
1896     }
1897 }
1898
1899 static void resource_test_data_init(IDirect3DDevice9 *device,
1900         struct resource_test_data *data, const struct resource_test_arg *arg)
1901 {
1902     static const DWORD vs_code[] =
1903     {
1904         0xfffe0101,                                                             /* vs_1_1                       */
1905         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position0 v0             */
1906         0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000,                         /* dp4 oPos.x, v0, c0           */
1907         0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001,                         /* dp4 oPos.y, v0, c1           */
1908         0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002,                         /* dp4 oPos.z, v0, c2           */
1909         0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003,                         /* dp4 oPos.w, v0, c3           */
1910         0x0000ffff,                                                             /* END                          */
1911     };
1912     static const DWORD ps_code[] =
1913     {
1914         0xffff0101,                                                             /* ps_1_1                       */
1915         0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
1916         0x00000042, 0xb00f0000,                                                 /* tex t0                       */
1917         0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000,                         /* dp3 r0, c1, c0               */
1918         0x00000005, 0x800f0000, 0x90e40000, 0x80e40000,                         /* mul r0, v0, r0               */
1919         0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000,                         /* mul r0, t0, r0               */
1920         0x0000ffff,                                                             /* END                          */
1921     };
1922     static const D3DVERTEXELEMENT9 decl[] =
1923     {
1924         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1925         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1926         D3DDECL_END(),
1927     };
1928
1929     unsigned int i;
1930     HRESULT hr;
1931
1932     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &data->decl);
1933     ok(SUCCEEDED(hr), "CreateVertexDeclaration returned %#x.\n", hr);
1934
1935     if (arg->vs_version)
1936     {
1937         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &data->vs);
1938         ok(SUCCEEDED(hr), "CreateVertexShader returned %#x.\n", hr);
1939     }
1940     else
1941     {
1942         data->vs = NULL;
1943     }
1944
1945     if (arg->ps_version)
1946     {
1947         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &data->ps);
1948         ok(SUCCEEDED(hr), "CreatePixelShader returned %#x.\n", hr);
1949     }
1950     else
1951     {
1952         data->ps = NULL;
1953     }
1954
1955     hr = IDirect3DDevice9_CreateIndexBuffer(device, 64, D3DUSAGE_DYNAMIC,
1956             D3DFMT_INDEX32, D3DPOOL_DEFAULT, &data->ib, NULL);
1957     ok(SUCCEEDED(hr), "CreateIndexBuffer returned %#x.\n", hr);
1958
1959     data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1960     for (i = 0; i < arg->stream_count; ++i)
1961     {
1962         hr = IDirect3DDevice9_CreateVertexBuffer(device, 64, D3DUSAGE_DYNAMIC,
1963                 0, D3DPOOL_DEFAULT, &data->vb[i], NULL);
1964         ok(SUCCEEDED(hr), "CreateVertexBuffer (%u) returned %#x.\n", i, hr);
1965     }
1966     data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1967     for (i = 0; i < arg->tex_count; ++i)
1968     {
1969         hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
1970                 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &data->tex[i], NULL);
1971         ok(SUCCEEDED(hr), "CreateTexture (%u) returned %#x.\n", i, hr);
1972     }
1973 }
1974
1975 static void resource_poison_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1976 {
1977     DWORD_PTR poison = 0xdeadbeef;
1978     unsigned int i;
1979
1980     data->decl = (IDirect3DVertexDeclaration9 *)poison++;
1981     data->vs = (IDirect3DVertexShader9 *)poison++;
1982     data->ps = (IDirect3DPixelShader9 *)poison++;
1983     data->ib = (IDirect3DIndexBuffer9 *)poison++;
1984     data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1985     for (i = 0; i < arg->stream_count; ++i)
1986     {
1987         data->vb[i] = (IDirect3DVertexBuffer9 *)poison++;
1988     }
1989     data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1990     for (i = 0; i < arg->tex_count; ++i)
1991     {
1992         data->tex[i] = (IDirect3DTexture9 *)poison++;
1993     }
1994 }
1995
1996 static HRESULT resource_test_init(IDirect3DDevice9 *device, struct state_test *test)
1997 {
1998     const struct resource_test_arg *arg = test->test_arg;
1999     struct resource_test_context *ctx;
2000
2001     ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
2002     if (!ctx) return E_OUTOFMEMORY;
2003
2004     test->test_context = ctx;
2005     test->test_data_in = &ctx->test_data_all;
2006     test->test_data_out_all = &ctx->test_data_all;
2007     test->test_data_out_vertex = &ctx->test_data_vertex;
2008     test->test_data_out_pixel = &ctx->test_data_pixel;
2009     test->default_data = &ctx->default_data;
2010     test->initial_data = &ctx->default_data;
2011
2012     resource_default_data_init(&ctx->default_data, arg);
2013     resource_test_data_init(device, &ctx->test_data_all, arg);
2014     resource_default_data_init(&ctx->test_data_vertex, arg);
2015     resource_default_data_init(&ctx->test_data_pixel, arg);
2016     resource_poison_data_init(&ctx->poison_data, arg);
2017
2018     ctx->test_data_vertex.decl = ctx->test_data_all.decl;
2019     ctx->test_data_vertex.vs = ctx->test_data_all.vs;
2020     ctx->test_data_pixel.ps = ctx->test_data_all.ps;
2021
2022     return D3D_OK;
2023 }
2024
2025 static void resource_test_cleanup(IDirect3DDevice9 *device, struct state_test *test)
2026 {
2027     struct resource_test_context *ctx = test->test_context;
2028     const struct resource_test_arg *arg = test->test_arg;
2029     unsigned int i;
2030
2031     resource_apply_data(device, test, &ctx->default_data);
2032
2033     IDirect3DVertexDeclaration9_Release(ctx->test_data_all.decl);
2034     if (ctx->test_data_all.vs) IDirect3DVertexShader9_Release(ctx->test_data_all.vs);
2035     if (ctx->test_data_all.ps) IDirect3DPixelShader9_Release(ctx->test_data_all.ps);
2036     IDirect3DIndexBuffer9_Release(ctx->test_data_all.ib);
2037     for (i = 0; i < arg->stream_count; ++i)
2038     {
2039         IDirect3DVertexBuffer9_Release(ctx->test_data_all.vb[i]);
2040     }
2041
2042     for (i = 0; i < arg->tex_count; ++i)
2043     {
2044         IDirect3DBaseTexture9_Release(ctx->test_data_all.tex[i]);
2045     }
2046
2047     HeapFree(GetProcessHeap(), 0, ctx->default_data.vb);
2048     HeapFree(GetProcessHeap(), 0, ctx->default_data.tex);
2049     HeapFree(GetProcessHeap(), 0, ctx->test_data_all.vb);
2050     HeapFree(GetProcessHeap(), 0, ctx->test_data_all.tex);
2051     HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.vb);
2052     HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.tex);
2053     HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.vb);
2054     HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.tex);
2055     HeapFree(GetProcessHeap(), 0, ctx->poison_data.vb);
2056     HeapFree(GetProcessHeap(), 0, ctx->poison_data.tex);
2057     HeapFree(GetProcessHeap(), 0, ctx);
2058 }
2059
2060 static void resource_test_queue(struct state_test *test, const struct resource_test_arg *test_arg)
2061 {
2062     test->init = resource_test_init;
2063     test->cleanup = resource_test_cleanup;
2064     test->apply_data = resource_apply_data;
2065     test->check_data = resource_check_data;
2066     test->test_name = "set_get_resources";
2067     test->test_arg = test_arg;
2068 }
2069
2070 /* =================== Main state tests function =============================== */
2071
2072 static void test_state_management(IDirect3DDevice9 *device, D3DPRESENT_PARAMETERS *device_pparams)
2073 {
2074     struct shader_constant_arg pshader_constant_arg;
2075     struct shader_constant_arg vshader_constant_arg;
2076     struct resource_test_arg resource_test_arg;
2077     struct render_state_arg render_state_arg;
2078     struct light_arg light_arg;
2079     HRESULT hret;
2080     D3DCAPS9 caps;
2081
2082     /* Test count: 2 for shader constants
2083                    1 for lights
2084                    1 for transforms
2085                    1 for render states
2086                    1 for resources
2087      */
2088     struct state_test tests[6];
2089     unsigned int tcount = 0;
2090
2091     hret = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2092     ok(hret == D3D_OK, "GetDeviceCaps returned %#x.\n", hret);
2093     if (hret != D3D_OK) return;
2094
2095     texture_stages = caps.MaxTextureBlendStages;
2096
2097     /* Zero test memory */
2098     memset(tests, 0, sizeof(tests));
2099
2100     if (caps.VertexShaderVersion & 0xffff) {
2101         vshader_constant_arg.idx = 0;
2102         vshader_constant_arg.pshader = FALSE;
2103         shader_constants_queue_test(&tests[tcount], &vshader_constant_arg);
2104         tcount++;
2105     }
2106
2107     if (caps.PixelShaderVersion & 0xffff) {
2108         pshader_constant_arg.idx = 0;
2109         pshader_constant_arg.pshader = TRUE;
2110         shader_constants_queue_test(&tests[tcount], &pshader_constant_arg);
2111         tcount++;
2112     }
2113
2114     light_arg.idx = 0;
2115     lights_queue_test(&tests[tcount], &light_arg);
2116     tcount++;
2117
2118     transform_queue_test(&tests[tcount]);
2119     tcount++;
2120
2121     render_state_arg.device_pparams = device_pparams;
2122     render_state_arg.pointsize_max = caps.MaxPointSize;
2123     render_states_queue_test(&tests[tcount], &render_state_arg);
2124     tcount++;
2125
2126     resource_test_arg.vs_version = caps.VertexShaderVersion & 0xffff;
2127     resource_test_arg.ps_version = caps.PixelShaderVersion & 0xffff;
2128     resource_test_arg.stream_count = caps.MaxStreams;
2129     resource_test_arg.tex_count = caps.MaxTextureBlendStages;
2130     resource_test_queue(&tests[tcount], &resource_test_arg);
2131     tcount++;
2132
2133     execute_test_chain_all(device, tests, tcount);
2134 }
2135
2136 static void test_shader_constant_apply(IDirect3DDevice9 *device)
2137 {
2138     static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
2139     static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
2140     static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
2141     IDirect3DStateBlock9 *stateblock;
2142     DWORD vs_version, ps_version;
2143     D3DCAPS9 caps;
2144     float ret[4];
2145     HRESULT hr;
2146
2147     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2148     ok(SUCCEEDED(hr), "GetDeviceCaps returned %#x.\n", hr);
2149     vs_version = caps.VertexShaderVersion & 0xffff;
2150     ps_version = caps.PixelShaderVersion & 0xffff;
2151
2152     if (vs_version)
2153     {
2154         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
2155         ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2156         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
2157         ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2158
2159         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
2160         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2161         ok(!memcmp(ret, initial, sizeof(initial)),
2162                 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2163                 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2164         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
2165         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2166         ok(!memcmp(ret, initial, sizeof(initial)),
2167                 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2168                 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2169
2170         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
2171         ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2172     }
2173     if (ps_version)
2174     {
2175         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
2176         ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2177         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
2178         ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2179
2180         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
2181         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2182         ok(!memcmp(ret, initial, sizeof(initial)),
2183                 "GetpixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2184                 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2185         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
2186         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2187         ok(!memcmp(ret, initial, sizeof(initial)),
2188                 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2189                 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2190
2191         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
2192         ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2193     }
2194
2195     hr = IDirect3DDevice9_BeginStateBlock(device);
2196     ok(SUCCEEDED(hr), "BeginStateBlock returned %#x\n", hr);
2197
2198     if (vs_version)
2199     {
2200         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
2201         ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2202     }
2203     if (ps_version)
2204     {
2205         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
2206         ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2207     }
2208
2209     hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
2210     ok(SUCCEEDED(hr), "EndStateBlock returned %#x\n", hr);
2211
2212     if (vs_version)
2213     {
2214         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
2215         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2216         ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2217                 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2218                 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2219         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
2220         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2221         ok(!memcmp(ret, initial, sizeof(initial)),
2222                 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2223                 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2224     }
2225     if (ps_version)
2226     {
2227         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
2228         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2229         ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2230                 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2231                 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2232         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
2233         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2234         ok(!memcmp(ret, initial, sizeof(initial)),
2235                 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2236                 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2237     }
2238
2239     /* Apply doesn't overwrite constants that aren't explicitly set on the source stateblock. */
2240     hr = IDirect3DStateBlock9_Apply(stateblock);
2241     ok(SUCCEEDED(hr), "Apply returned %#x\n", hr);
2242
2243     if (vs_version)
2244     {
2245         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
2246         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2247         ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2248                 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2249                 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2250         hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
2251         ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2252         ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2253                 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2254                 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2255     }
2256     if (ps_version)
2257     {
2258         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
2259         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2260         ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2261                 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2262                 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2263         hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
2264         ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2265         ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2266                 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2267                 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2268     }
2269
2270     IDirect3DStateBlock9_Release(stateblock);
2271 }
2272
2273 static void test_vdecl_apply(IDirect3DDevice9 *device)
2274 {
2275     static const D3DVERTEXELEMENT9 decl1[] =
2276     {
2277         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2278         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2279         D3DDECL_END(),
2280     };
2281
2282     static const D3DVERTEXELEMENT9 decl2[] =
2283     {
2284         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2285         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2286         {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
2287         D3DDECL_END(),
2288     };
2289
2290     IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
2291     IDirect3DStateBlock9 *stateblock;
2292     HRESULT hr;
2293
2294     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
2295     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
2296
2297     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
2298     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
2299
2300     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2301     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2302     hr = IDirect3DDevice9_BeginStateBlock(device);
2303     ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
2304     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
2305     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2306     hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
2307     ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#x.\n", hr);
2308     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2309     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2310     hr = IDirect3DStateBlock9_Apply(stateblock);
2311     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2312     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2313     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2314     ok(declaration == declaration1, "Expected vertex declaration %p, received %p.\n",
2315             declaration1, declaration);
2316     IDirect3DVertexDeclaration9_Release(declaration);
2317
2318     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2319     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2320     hr = IDirect3DStateBlock9_Capture(stateblock);
2321     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2322     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2323     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2324     hr = IDirect3DStateBlock9_Apply(stateblock);
2325     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2326     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2327     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2328     ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2329             declaration2, declaration);
2330     IDirect3DVertexDeclaration9_Release(declaration);
2331
2332     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2333     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2334     hr = IDirect3DStateBlock9_Capture(stateblock);
2335     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2336     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2337     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2338     hr = IDirect3DStateBlock9_Apply(stateblock);
2339     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2340     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2341     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2342     ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2343             declaration2, declaration);
2344     IDirect3DVertexDeclaration9_Release(declaration);
2345
2346     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2347     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2348     hr = IDirect3DStateBlock9_Capture(stateblock);
2349     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2350     hr = IDirect3DStateBlock9_Apply(stateblock);
2351     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2352     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2353     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2354     ok(declaration == NULL, "Expected vertex declaration %p, received %p.\n",
2355             NULL, declaration);
2356
2357     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2358     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2359     hr = IDirect3DStateBlock9_Capture(stateblock);
2360     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2361     hr = IDirect3DStateBlock9_Apply(stateblock);
2362     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2363     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2364     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2365     ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2366             declaration2, declaration);
2367     IDirect3DVertexDeclaration9_Release(declaration);
2368
2369     IDirect3DStateBlock9_Release(stateblock);
2370     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
2371     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2372     hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
2373     ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#x.\n", hr);
2374     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2375     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2376     hr = IDirect3DStateBlock9_Apply(stateblock);
2377     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2378     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2379     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2380     ok(declaration == declaration1, "Expected vertex declaration %p, received %p.\n",
2381             declaration1, declaration);
2382     IDirect3DVertexDeclaration9_Release(declaration);
2383
2384     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2385     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2386     hr = IDirect3DStateBlock9_Capture(stateblock);
2387     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2388     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2389     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2390     hr = IDirect3DStateBlock9_Apply(stateblock);
2391     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2392     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2393     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2394     ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2395             declaration2, declaration);
2396     IDirect3DVertexDeclaration9_Release(declaration);
2397
2398     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2399     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2400     hr = IDirect3DStateBlock9_Capture(stateblock);
2401     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2402     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2403     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2404     hr = IDirect3DStateBlock9_Apply(stateblock);
2405     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2406     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2407     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2408     ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2409             declaration2, declaration);
2410     IDirect3DVertexDeclaration9_Release(declaration);
2411
2412     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2413     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2414     hr = IDirect3DStateBlock9_Capture(stateblock);
2415     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2416     hr = IDirect3DStateBlock9_Apply(stateblock);
2417     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2418     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2419     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2420     ok(declaration == NULL, "Expected vertex declaration %p, received %p.\n",
2421             NULL, declaration);
2422
2423     hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2424     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2425     hr = IDirect3DStateBlock9_Capture(stateblock);
2426     ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2427     hr = IDirect3DStateBlock9_Apply(stateblock);
2428     ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2429     hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2430     ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2431     ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2432             declaration2, declaration);
2433     IDirect3DVertexDeclaration9_Release(declaration);
2434
2435     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2436     ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2437     IDirect3DVertexDeclaration9_Release(declaration1);
2438     IDirect3DVertexDeclaration9_Release(declaration2);
2439     IDirect3DStateBlock9_Release(stateblock);
2440 }
2441
2442 START_TEST(stateblock)
2443 {
2444     IDirect3DDevice9 *device_ptr = NULL;
2445     D3DPRESENT_PARAMETERS device_pparams;
2446     HRESULT hret;
2447     ULONG refcount;
2448
2449     d3d9_handle = LoadLibraryA("d3d9.dll");
2450     if (!d3d9_handle)
2451     {
2452         skip("Could not load d3d9.dll\n");
2453         return;
2454     }
2455
2456     hret = init_d3d9(&device_ptr, &device_pparams);
2457     if (hret != D3D_OK) return;
2458
2459     test_begin_end_state_block(device_ptr);
2460     test_state_management(device_ptr, &device_pparams);
2461     test_shader_constant_apply(device_ptr);
2462     test_vdecl_apply(device_ptr);
2463
2464     refcount = IDirect3DDevice9_Release(device_ptr);
2465     ok(!refcount, "Device has %u references left\n", refcount);
2466 }