2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2006 Ivan Gyurdiev
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.
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.
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
22 #include "wine/test.h"
24 static HMODULE d3d9_handle = 0;
26 static DWORD texture_stages;
28 static HWND create_window(void)
31 wc.lpfnWndProc = DefWindowProc;
32 wc.lpszClassName = "d3d9_test_wc";
35 return CreateWindow("d3d9_test_wc", "d3d9_test",
36 0, 0, 0, 0, 0, 0, 0, 0, 0);
39 static HRESULT init_d3d9(
40 IDirect3DDevice9** device,
41 D3DPRESENT_PARAMETERS* device_pparams)
43 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
44 IDirect3D9 *d3d9_ptr = 0;
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;
52 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
55 skip("could not create D3D9\n");
59 window = create_window();
61 ZeroMemory(device_pparams, sizeof(D3DPRESENT_PARAMETERS));
62 device_pparams->Windowed = TRUE;
63 device_pparams->hDeviceWindow = window;
64 device_pparams->SwapEffect = D3DSWAPEFFECT_DISCARD;
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);
73 static void test_begin_end_state_block(IDirect3DDevice9 *device_ptr)
76 IDirect3DStateBlock9 *state_block_ptr = 0;
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;
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;
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);
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);
104 /* ============================ State Testing Framework ========================== */
108 const char* test_name;
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;
116 /* The default data is the standard state to compare
117 * against, and restore to */
118 const void* default_data;
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;
126 /* Test resource management handlers */
127 HRESULT (*setup_handler) (struct state_test* test);
128 void (*teardown_handler) (struct state_test* test);
130 /* Test data handlers */
131 void (*set_handler) (IDirect3DDevice9* device, const struct state_test* test, const void* data_in);
132 void (*check_data)(IDirect3DDevice9 *device, unsigned int chain_stage,
133 const struct state_test *test, const void *expected_data);
136 const void* test_arg;
138 /* Test-specific context data */
143 #define EVENT_ERROR -1
147 IDirect3DStateBlock9 *stateblock;
148 IDirect3DSurface9 *original_render_target;
149 IDirect3DSwapChain9 *new_swap_chain;
163 int (*event_fn)(IDirect3DDevice9 *device, struct event_data *event_data);
164 enum stateblock_data check;
165 enum stateblock_data apply;
168 static const void *get_event_data(const struct state_test *test, enum stateblock_data data)
172 case SB_DATA_DEFAULT:
173 return test->default_data;
175 case SB_DATA_INITIAL:
176 return test->initial_data;
178 case SB_DATA_TEST_IN:
179 return test->test_data_in;
182 return test->test_data_out;
189 /* This is an event-machine, which tests things.
190 * It tests get and set operations for a batch of states, based on
191 * results from the event function, which directs what's to be done */
193 static void execute_test_chain(IDirect3DDevice9 *device, struct state_test *test,
194 unsigned int ntests, struct event *event, unsigned int nevents, struct event_data *event_data)
198 /* For each queued event */
199 for (j = 0; j < nevents; ++j)
203 /* Execute the next event handler (if available). */
204 if (event[j].event_fn)
206 if (event[j].event_fn(device, event_data) == EVENT_ERROR)
208 trace("Stage %u in error state, aborting.\n", j);
213 if (event[j].check != SB_DATA_NONE)
215 for (i = 0; i < ntests; ++i)
217 data = get_event_data(&test[i], event[j].check);
218 test[i].check_data(device, j, &test[i], data);
222 if (event[j].apply != SB_DATA_NONE)
224 for (i = 0; i < ntests; ++i)
226 data = get_event_data(&test[i], event[j].apply);
227 test[i].set_handler(device, &test[i], data);
232 /* Attempt to reset any changes made */
233 for (i=0; i < ntests; i++)
234 test[i].set_handler(device, &test[i], test[i].default_data);
237 static int switch_render_target(IDirect3DDevice9 *device, struct event_data *event_data)
240 D3DPRESENT_PARAMETERS present_parameters;
241 IDirect3DSwapChain9* swapchain = NULL;
242 IDirect3DSurface9* backbuffer = NULL;
244 /* Parameters for new swapchain */
245 ZeroMemory(&present_parameters, sizeof(present_parameters));
246 present_parameters.Windowed = TRUE;
247 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
249 /* Create new swapchain */
250 hret = IDirect3DDevice9_CreateAdditionalSwapChain(device, &present_parameters, &swapchain);
251 ok (hret == D3D_OK, "CreateAdditionalSwapChain returned %#x.\n", hret);
252 if (hret != D3D_OK) goto error;
254 /* Get its backbuffer */
255 hret = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
256 ok (hret == D3D_OK, "GetBackBuffer returned %#x.\n", hret);
257 if (hret != D3D_OK) goto error;
259 /* Save the current render target */
260 hret = IDirect3DDevice9_GetRenderTarget(device, 0, &event_data->original_render_target);
261 ok (hret == D3D_OK, "GetRenderTarget returned %#x.\n", hret);
262 if (hret != D3D_OK) goto error;
264 /* Set the new swapchain's backbuffer as a render target */
265 hret = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
266 ok (hret == D3D_OK, "SetRenderTarget returned %#x.\n", hret);
267 if (hret != D3D_OK) goto error;
269 IUnknown_Release(backbuffer);
270 event_data->new_swap_chain = swapchain;
274 if (backbuffer) IUnknown_Release(backbuffer);
275 if (swapchain) IUnknown_Release(swapchain);
279 static int revert_render_target(IDirect3DDevice9 *device, struct event_data *event_data)
283 /* Reset the old render target */
284 hret = IDirect3DDevice9_SetRenderTarget(device, 0, event_data->original_render_target);
285 ok (hret == D3D_OK, "SetRenderTarget returned %#x.\n", hret);
286 if (hret != D3D_OK) {
287 IUnknown_Release(event_data->original_render_target);
291 IUnknown_Release(event_data->original_render_target);
292 IUnknown_Release(event_data->new_swap_chain);
297 static int create_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
301 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &event_data->stateblock);
302 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
303 if (FAILED(hr)) return EVENT_ERROR;
307 static int begin_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
311 hret = IDirect3DDevice9_BeginStateBlock(device);
312 ok(hret == D3D_OK, "BeginStateBlock returned %#x.\n", hret);
313 if (hret != D3D_OK) return EVENT_ERROR;
317 static int end_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
321 hret = IDirect3DDevice9_EndStateBlock(device, &event_data->stateblock);
322 ok(hret == D3D_OK, "EndStateBlock returned %#x.\n", hret);
323 if (hret != D3D_OK) return EVENT_ERROR;
327 static int release_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
329 IUnknown_Release(event_data->stateblock);
333 static int apply_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
337 hret = IDirect3DStateBlock9_Apply(event_data->stateblock);
338 ok(hret == D3D_OK, "Apply returned %#x.\n", hret);
339 if (hret != D3D_OK) {
340 IUnknown_Release(event_data->stateblock);
344 IUnknown_Release(event_data->stateblock);
349 static int capture_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
353 hret = IDirect3DStateBlock9_Capture(event_data->stateblock);
354 ok(hret == D3D_OK, "Capture returned %#x.\n", hret);
361 static void execute_test_chain_all(IDirect3DDevice9 *device, struct state_test *test, unsigned int ntests)
363 struct event_data arg;
366 struct event read_events[] =
368 {NULL, SB_DATA_INITIAL, SB_DATA_NONE},
371 struct event write_read_events[] =
373 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
374 {NULL, SB_DATA_TEST, SB_DATA_NONE},
377 struct event abort_stateblock_events[] =
379 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
380 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
381 {release_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
384 struct event apply_stateblock_events[] =
386 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
387 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
388 {apply_stateblock, SB_DATA_TEST, SB_DATA_NONE},
391 struct event capture_reapply_stateblock_events[] =
393 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
394 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
395 {capture_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
396 {apply_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
399 struct event create_stateblock_capture_apply_events[] =
401 {create_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
402 {capture_stateblock, SB_DATA_TEST, SB_DATA_DEFAULT},
403 {apply_stateblock, SB_DATA_TEST, SB_DATA_NONE},
406 struct event create_stateblock_apply_events[] =
408 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
409 {create_stateblock, SB_DATA_TEST, SB_DATA_DEFAULT},
410 {apply_stateblock, SB_DATA_TEST, SB_DATA_NONE},
413 struct event rendertarget_switch_events[] =
415 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
416 {switch_render_target, SB_DATA_TEST, SB_DATA_NONE},
417 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
420 struct event rendertarget_stateblock_events[] =
422 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
423 {switch_render_target, SB_DATA_DEFAULT, SB_DATA_NONE},
424 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
425 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
426 {apply_stateblock, SB_DATA_TEST, SB_DATA_NONE},
429 /* Setup each test for execution */
430 for (i=0; i < ntests; i++) {
431 if (test[i].setup_handler(&test[i]) != D3D_OK) {
432 ok(FALSE, "Test \"%s\" failed setup, aborting\n", test[i].test_name);
437 trace("Running initial read state tests\n");
438 execute_test_chain(device, test, ntests, read_events, 1, NULL);
440 trace("Running write-read state tests\n");
441 execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
443 trace("Running stateblock abort state tests\n");
444 execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
446 trace("Running stateblock apply state tests\n");
447 execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
449 trace("Running stateblock capture/reapply state tests\n");
450 execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
452 trace("Running create stateblock capture/apply state tests\n");
453 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_events, 3, &arg);
455 trace("Running create stateblock apply state tests\n");
456 execute_test_chain(device, test, ntests, create_stateblock_apply_events, 3, &arg);
458 trace("Running rendertarget switch state tests\n");
459 execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
461 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
462 execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
464 /* Cleanup resources */
465 for (i=0; i < ntests; i++)
466 test[i].teardown_handler(&test[i]);
469 /* =================== State test: Pixel and Vertex Shader constants ============ */
471 struct shader_constant_data
473 int int_constant[4]; /* 1x4 integer constant */
474 float float_constant[4]; /* 1x4 float constant */
475 BOOL bool_constant[4]; /* 4x1 boolean constants */
478 struct shader_constant_arg
484 static const struct shader_constant_data shader_constant_poison_data =
486 {0x1337c0de, 0x1337c0de, 0x1337c0de, 0x1337c0de},
487 {1.0f, 2.0f, 3.0f, 4.0f},
488 {FALSE, TRUE, FALSE, TRUE},
491 static const struct shader_constant_data shader_constant_default_data =
494 {0.0f, 0.0f, 0.0f, 0.0f},
498 static const struct shader_constant_data shader_constant_test_data =
500 {0xdead0000, 0xdead0001, 0xdead0002, 0xdead0003},
501 {5.0f, 6.0f, 7.0f, 8.0f},
502 {TRUE, FALSE, FALSE, TRUE},
505 static void shader_constant_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
507 const struct shader_constant_arg *scarg = test->test_arg;
508 const struct shader_constant_data *scdata = data;
510 unsigned int index = scarg->idx;
512 if (!scarg->pshader) {
513 hret = IDirect3DDevice9_SetVertexShaderConstantI(device, index, scdata->int_constant, 1);
514 ok(hret == D3D_OK, "SetVertexShaderConstantI returned %#x.\n", hret);
515 hret = IDirect3DDevice9_SetVertexShaderConstantF(device, index, scdata->float_constant, 1);
516 ok(hret == D3D_OK, "SetVertexShaderConstantF returned %#x.\n", hret);
517 hret = IDirect3DDevice9_SetVertexShaderConstantB(device, index, scdata->bool_constant, 4);
518 ok(hret == D3D_OK, "SetVertexShaderConstantB returned %#x.\n", hret);
521 hret = IDirect3DDevice9_SetPixelShaderConstantI(device, index, scdata->int_constant, 1);
522 ok(hret == D3D_OK, "SetPixelShaderConstantI returned %#x.\n", hret);
523 hret = IDirect3DDevice9_SetPixelShaderConstantF(device, index, scdata->float_constant, 1);
524 ok(hret == D3D_OK, "SetPixelShaderConstantF returned %#x.\n", hret);
525 hret = IDirect3DDevice9_SetPixelShaderConstantB(device, index, scdata->bool_constant, 4);
526 ok(hret == D3D_OK, "SetPixelShaderConstantB returned %#x.\n", hret);
530 static void shader_constant_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
531 const struct state_test *test, const void *expected_data)
533 struct shader_constant_data value = shader_constant_poison_data;
534 const struct shader_constant_data *scdata = expected_data;
535 const struct shader_constant_arg *scarg = test->test_arg;
540 hr = IDirect3DDevice9_GetVertexShaderConstantI(device, scarg->idx, value.int_constant, 1);
541 ok(SUCCEEDED(hr), "GetVertexShaderConstantI returned %#x.\n", hr);
542 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, scarg->idx, value.float_constant, 1);
543 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x.\n", hr);
544 hr = IDirect3DDevice9_GetVertexShaderConstantB(device, scarg->idx, value.bool_constant, 4);
545 ok(SUCCEEDED(hr), "GetVertexShaderConstantB returned %#x.\n", hr);
549 hr = IDirect3DDevice9_GetPixelShaderConstantI(device, scarg->idx, value.int_constant, 1);
550 ok(SUCCEEDED(hr), "GetPixelShaderConstantI returned %#x.\n", hr);
551 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, scarg->idx, value.float_constant, 1);
552 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x.\n", hr);
553 hr = IDirect3DDevice9_GetPixelShaderConstantB(device, scarg->idx, value.bool_constant, 4);
554 ok(SUCCEEDED(hr), "GetPixelShaderConstantB returned %#x.\n", hr);
557 ok(!memcmp(scdata->int_constant, value.int_constant, sizeof(scdata->int_constant)),
558 "Chain stage %u, %s integer constant:\n"
559 "\t{%#x, %#x, %#x, %#x} expected\n"
560 "\t{%#x, %#x, %#x, %#x} received\n",
561 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
562 scdata->int_constant[0], scdata->int_constant[1],
563 scdata->int_constant[2], scdata->int_constant[3],
564 value.int_constant[0], value.int_constant[1],
565 value.int_constant[2], value.int_constant[3]);
567 ok(!memcmp(scdata->float_constant, value.float_constant, sizeof(scdata->float_constant)),
568 "Chain stage %u, %s float constant:\n"
569 "\t{%.8e, %.8e, %.8e, %.8e} expected\n"
570 "\t{%.8e, %.8e, %.8e, %.8e} received\n",
571 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
572 scdata->float_constant[0], scdata->float_constant[1],
573 scdata->float_constant[2], scdata->float_constant[3],
574 value.float_constant[0], value.float_constant[1],
575 value.float_constant[2], value.float_constant[3]);
577 ok(!memcmp(scdata->bool_constant, value.bool_constant, sizeof(scdata->bool_constant)),
578 "Chain stage %u, %s boolean constant:\n"
579 "\t{%#x, %#x, %#x, %#x} expected\n"
580 "\t{%#x, %#x, %#x, %#x} received\n",
581 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
582 scdata->bool_constant[0], scdata->bool_constant[1],
583 scdata->bool_constant[2], scdata->bool_constant[3],
584 value.bool_constant[0], value.bool_constant[1],
585 value.bool_constant[2], value.bool_constant[3]);
588 static HRESULT shader_constant_setup_handler(struct state_test *test)
590 test->test_context = NULL;
591 test->test_data_in = &shader_constant_test_data;
592 test->test_data_out = &shader_constant_test_data;
593 test->default_data = &shader_constant_default_data;
594 test->initial_data = &shader_constant_default_data;
599 static void shader_constant_teardown_handler(struct state_test *test)
601 HeapFree(GetProcessHeap(), 0, test->test_context);
604 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
606 test->setup_handler = shader_constant_setup_handler;
607 test->teardown_handler = shader_constant_teardown_handler;
608 test->set_handler = shader_constant_set_handler;
609 test->check_data = shader_constant_check_data;
610 test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
611 test->test_arg = test_arg;
614 /* =================== State test: Lights ===================================== */
620 HRESULT get_light_result;
621 HRESULT get_enabled_result;
629 static const struct light_data light_poison_data =
633 {7.0f, 4.0f, 2.0f, 1.0f},
634 {7.0f, 4.0f, 2.0f, 1.0f},
635 {7.0f, 4.0f, 2.0f, 1.0f},
638 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
645 static const struct light_data light_default_data =
648 D3DLIGHT_DIRECTIONAL,
649 {1.0f, 1.0f, 1.0f, 0.0f},
650 {0.0f, 0.0f, 0.0f, 0.0f},
651 {0.0f, 0.0f, 0.0f, 0.0f},
654 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
661 /* This is used for the initial read state (before a write causes side effects).
662 * The proper return status is D3DERR_INVALIDCALL. */
663 static const struct light_data light_initial_data =
667 {7.0f, 4.0f, 2.0f, 1.0f},
668 {7.0f, 4.0f, 2.0f, 1.0f},
669 {7.0f, 4.0f, 2.0f, 1.0f},
672 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
679 static const struct light_data light_test_data_in =
683 {2.0f, 2.0f, 2.0f, 2.0f},
684 {3.0f, 3.0f, 3.0f, 3.0f},
685 {4.0f, 4.0f, 4.0f, 4.0f},
688 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
695 /* SetLight will use 128 as the "enabled" value */
696 static const struct light_data light_test_data_out =
700 {2.0f, 2.0f, 2.0f, 2.0f},
701 {3.0f, 3.0f, 3.0f, 3.0f},
702 {4.0f, 4.0f, 4.0f, 4.0f},
705 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
712 static void light_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
714 const struct light_arg *larg = test->test_arg;
715 const struct light_data *ldata = data;
717 unsigned int index = larg->idx;
719 hret = IDirect3DDevice9_SetLight(device, index, &ldata->light);
720 ok(hret == D3D_OK, "SetLight returned %#x.\n", hret);
722 hret = IDirect3DDevice9_LightEnable(device, index, ldata->enabled);
723 ok(hret == D3D_OK, "SetLightEnable returned %#x.\n", hret);
726 static void light_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
727 const struct state_test *test, const void *expected_data)
729 const struct light_arg *larg = test->test_arg;
730 const struct light_data *ldata = expected_data;
731 struct light_data value;
733 value = light_poison_data;
735 value.get_enabled_result = IDirect3DDevice9_GetLightEnable(device, larg->idx, &value.enabled);
736 value.get_light_result = IDirect3DDevice9_GetLight(device, larg->idx, &value.light);
738 ok(value.get_enabled_result == ldata->get_enabled_result,
739 "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
740 chain_stage, ldata->get_enabled_result, value.get_enabled_result);
741 ok(value.get_light_result == ldata->get_light_result,
742 "Chain stage %u: expected get_light_result %#x, got %#x.\n",
743 chain_stage, ldata->get_light_result, value.get_light_result);
745 ok(value.enabled == ldata->enabled,
746 "Chain stage %u: expected enabled %#x, got %#x.\n",
747 chain_stage, ldata->enabled, value.enabled);
748 ok(value.light.Type == ldata->light.Type,
749 "Chain stage %u: expected light.Type %#x, got %#x.\n",
750 chain_stage, ldata->light.Type, value.light.Type);
751 ok(!memcmp(&value.light.Diffuse, &ldata->light.Diffuse, sizeof(value.light.Diffuse)),
752 "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
753 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
754 ldata->light.Diffuse.r, ldata->light.Diffuse.g,
755 ldata->light.Diffuse.b, ldata->light.Diffuse.a,
756 value.light.Diffuse.r, value.light.Diffuse.g,
757 value.light.Diffuse.b, value.light.Diffuse.a);
758 ok(!memcmp(&value.light.Specular, &ldata->light.Specular, sizeof(value.light.Specular)),
759 "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
760 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
761 ldata->light.Specular.r, ldata->light.Specular.g,
762 ldata->light.Specular.b, ldata->light.Specular.a,
763 value.light.Specular.r, value.light.Specular.g,
764 value.light.Specular.b, value.light.Specular.a);
765 ok(!memcmp(&value.light.Ambient, &ldata->light.Ambient, sizeof(value.light.Ambient)),
766 "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
767 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
768 ldata->light.Ambient.r, ldata->light.Ambient.g,
769 ldata->light.Ambient.b, ldata->light.Ambient.a,
770 value.light.Ambient.r, value.light.Ambient.g,
771 value.light.Ambient.b, value.light.Ambient.a);
772 ok(!memcmp(&value.light.Position, &ldata->light.Position, sizeof(value.light.Position)),
773 "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
774 chain_stage, ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z,
775 value.light.Position.x, value.light.Position.y, value.light.Position.z);
776 ok(!memcmp(&value.light.Direction, &ldata->light.Direction, sizeof(value.light.Direction)),
777 "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
778 chain_stage, ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z,
779 value.light.Direction.x, value.light.Direction.y, value.light.Direction.z);
780 ok(value.light.Range == ldata->light.Range,
781 "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
782 chain_stage, ldata->light.Range, value.light.Range);
783 ok(value.light.Falloff == ldata->light.Falloff,
784 "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
785 chain_stage, ldata->light.Falloff, value.light.Falloff);
786 ok(value.light.Attenuation0 == ldata->light.Attenuation0,
787 "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
788 chain_stage, ldata->light.Attenuation0, value.light.Attenuation0);
789 ok(value.light.Attenuation1 == ldata->light.Attenuation1,
790 "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
791 chain_stage, ldata->light.Attenuation1, value.light.Attenuation1);
792 ok(value.light.Attenuation2 == ldata->light.Attenuation2,
793 "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
794 chain_stage, ldata->light.Attenuation2, value.light.Attenuation2);
795 ok(value.light.Theta == ldata->light.Theta,
796 "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
797 chain_stage, ldata->light.Theta, value.light.Theta);
798 ok(value.light.Phi == ldata->light.Phi,
799 "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
800 chain_stage, ldata->light.Phi, value.light.Phi);
803 static HRESULT light_setup_handler(struct state_test *test)
805 test->test_context = NULL;
806 test->test_data_in = &light_test_data_in;
807 test->test_data_out = &light_test_data_out;
808 test->default_data = &light_default_data;
809 test->initial_data = &light_initial_data;
814 static void light_teardown_handler(struct state_test *test)
816 HeapFree(GetProcessHeap(), 0, test->test_context);
819 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
821 test->setup_handler = light_setup_handler;
822 test->teardown_handler = light_teardown_handler;
823 test->set_handler = light_set_handler;
824 test->check_data = light_check_data;
825 test->test_name = "set_get_light";
826 test->test_arg = test_arg;
829 /* =================== State test: Transforms ===================================== */
831 struct transform_data
834 D3DMATRIX projection;
841 static const struct transform_data transform_default_data =
844 1.0f, 0.0f, 0.0f, 0.0f,
845 0.0f, 1.0f, 0.0f, 0.0f,
846 0.0f, 0.0f, 1.0f, 0.0f,
847 0.0f, 0.0f, 0.0f, 1.0f,
850 1.0f, 0.0f, 0.0f, 0.0f,
851 0.0f, 1.0f, 0.0f, 0.0f,
852 0.0f, 0.0f, 1.0f, 0.0f,
853 0.0f, 0.0f, 0.0f, 1.0f,
856 1.0f, 0.0f, 0.0f, 0.0f,
857 0.0f, 1.0f, 0.0f, 0.0f,
858 0.0f, 0.0f, 1.0f, 0.0f,
859 0.0f, 0.0f, 0.0f, 1.0f,
862 1.0f, 0.0f, 0.0f, 0.0f,
863 0.0f, 1.0f, 0.0f, 0.0f,
864 0.0f, 0.0f, 1.0f, 0.0f,
865 0.0f, 0.0f, 0.0f, 1.0f,
868 1.0f, 0.0f, 0.0f, 0.0f,
869 0.0f, 1.0f, 0.0f, 0.0f,
870 0.0f, 0.0f, 1.0f, 0.0f,
871 0.0f, 0.0f, 0.0f, 1.0f,
874 1.0f, 0.0f, 0.0f, 0.0f,
875 0.0f, 1.0f, 0.0f, 0.0f,
876 0.0f, 0.0f, 1.0f, 0.0f,
877 0.0f, 0.0f, 0.0f, 1.0f,
881 static const struct transform_data transform_poison_data =
884 1.0f, 2.0f, 3.0f, 4.0f,
885 5.0f, 6.0f, 7.0f, 8.0f,
886 9.0f, 10.0f, 11.0f, 12.0f,
887 13.0f, 14.0f, 15.0f, 16.0f,
890 17.0f, 18.0f, 19.0f, 20.0f,
891 21.0f, 22.0f, 23.0f, 24.0f,
892 25.0f, 26.0f, 27.0f, 28.0f,
893 29.0f, 30.0f, 31.0f, 32.0f,
896 33.0f, 34.0f, 35.0f, 36.0f,
897 37.0f, 38.0f, 39.0f, 40.0f,
898 41.0f, 42.0f, 43.0f, 44.0f,
899 45.0f, 46.0f, 47.0f, 48.0f
902 49.0f, 50.0f, 51.0f, 52.0f,
903 53.0f, 54.0f, 55.0f, 56.0f,
904 57.0f, 58.0f, 59.0f, 60.0f,
905 61.0f, 62.0f, 63.0f, 64.0f,
908 64.0f, 66.0f, 67.0f, 68.0f,
909 69.0f, 70.0f, 71.0f, 72.0f,
910 73.0f, 74.0f, 75.0f, 76.0f,
911 77.0f, 78.0f, 79.0f, 80.0f,
914 81.0f, 82.0f, 83.0f, 84.0f,
915 85.0f, 86.0f, 87.0f, 88.0f,
916 89.0f, 90.0f, 91.0f, 92.0f,
917 93.0f, 94.0f, 95.0f, 96.0f,
921 static const struct transform_data transform_test_data =
924 1.2f, 3.4f, -5.6f, 7.2f,
925 10.11f, -12.13f, 14.15f, -1.5f,
926 23.56f, 12.89f, 44.56f, -1.0f,
927 2.3f, 0.0f, 4.4f, 5.5f,
930 9.2f, 38.7f, -6.6f, 7.2f,
931 10.11f, -12.13f, 77.15f, -1.5f,
932 23.56f, 12.89f, 14.56f, -1.0f,
933 12.3f, 0.0f, 4.4f, 5.5f,
936 10.2f, 3.4f, 0.6f, 7.2f,
937 10.11f, -12.13f, 14.15f, -1.5f,
938 23.54f, 12.9f, 44.56f, -1.0f,
939 2.3f, 0.0f, 4.4f, 5.5f,
942 1.2f, 3.4f, -5.6f, 7.2f,
943 10.11f, -12.13f, -14.5f, -1.5f,
944 2.56f, 12.89f, 23.56f, -1.0f,
945 112.3f, 0.0f, 4.4f, 2.5f,
948 1.2f, 31.41f, 58.6f, 7.2f,
949 10.11f, -12.13f, -14.5f, -1.5f,
950 2.56f, 12.89f, 11.56f, -1.0f,
951 112.3f, 0.0f, 44.4f, 2.5f,
954 1.20f, 3.4f, -5.6f, 7.0f,
955 10.11f, -12.156f, -14.5f, -1.5f,
956 2.56f, 1.829f, 23.6f, -1.0f,
957 112.3f, 0.0f, 41.4f, 2.5f,
961 static void transform_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
963 const struct transform_data *tdata = data;
966 hret = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &tdata->view);
967 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
969 hret = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
970 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
972 hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
973 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
975 hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
976 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
978 hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &tdata->world0);
979 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
981 hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
982 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
985 static void compare_matrix(const char *name, unsigned int chain_stage,
986 const D3DMATRIX *received, const D3DMATRIX *expected)
988 ok(!memcmp(expected, received, sizeof(*expected)),
989 "Chain stage %u, matrix %s:\n"
991 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
992 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
993 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
994 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
997 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
998 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
999 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1000 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1003 U(*expected).m[0][0], U(*expected).m[1][0], U(*expected).m[2][0], U(*expected).m[3][0],
1004 U(*expected).m[0][1], U(*expected).m[1][1], U(*expected).m[2][1], U(*expected).m[3][1],
1005 U(*expected).m[0][2], U(*expected).m[1][2], U(*expected).m[2][2], U(*expected).m[3][2],
1006 U(*expected).m[0][3], U(*expected).m[1][3], U(*expected).m[2][3], U(*expected).m[3][3],
1007 U(*received).m[0][0], U(*received).m[1][0], U(*received).m[2][0], U(*received).m[3][0],
1008 U(*received).m[0][1], U(*received).m[1][1], U(*received).m[2][1], U(*received).m[3][1],
1009 U(*received).m[0][2], U(*received).m[1][2], U(*received).m[2][2], U(*received).m[3][2],
1010 U(*received).m[0][3], U(*received).m[1][3], U(*received).m[2][3], U(*received).m[3][3]);
1013 static void transform_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
1014 const struct state_test *test, const void *expected_data)
1016 const struct transform_data *tdata = expected_data;
1020 value = transform_poison_data.view;
1021 hr = IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &value);
1022 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1023 compare_matrix("View", chain_stage, &value, &tdata->view);
1025 value = transform_poison_data.projection;
1026 hr = IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &value);
1027 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1028 compare_matrix("Projection", chain_stage, &value, &tdata->projection);
1030 value = transform_poison_data.texture0;
1031 hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0, &value);
1032 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1033 compare_matrix("Texture0", chain_stage, &value, &tdata->texture0);
1035 value = transform_poison_data.texture7;
1036 hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &value);
1037 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1038 compare_matrix("Texture7", chain_stage, &value, &tdata->texture7);
1040 value = transform_poison_data.world0;
1041 hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &value);
1042 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1043 compare_matrix("World0", chain_stage, &value, &tdata->world0);
1045 value = transform_poison_data.world255;
1046 hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(255), &value);
1047 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1048 compare_matrix("World255", chain_stage, &value, &tdata->world255);
1051 static HRESULT transform_setup_handler(struct state_test *test)
1053 test->test_context = NULL;
1054 test->test_data_in = &transform_test_data;
1055 test->test_data_out = &transform_test_data;
1056 test->default_data = &transform_default_data;
1057 test->initial_data = &transform_default_data;
1062 static void transform_teardown_handler(struct state_test *test)
1064 HeapFree(GetProcessHeap(), 0, test->test_context);
1067 static void transform_queue_test(struct state_test *test)
1069 test->setup_handler = transform_setup_handler;
1070 test->teardown_handler = transform_teardown_handler;
1071 test->set_handler = transform_set_handler;
1072 test->check_data = transform_check_data;
1073 test->test_name = "set_get_transforms";
1074 test->test_arg = NULL;
1077 /* =================== State test: Render States ===================================== */
1079 const D3DRENDERSTATETYPE render_state_indices[] =
1085 D3DRS_ALPHATESTENABLE,
1094 D3DRS_ALPHABLENDENABLE,
1096 D3DRS_SPECULARENABLE,
1102 D3DRS_RANGEFOGENABLE,
1103 D3DRS_STENCILENABLE,
1110 D3DRS_STENCILWRITEMASK,
1111 D3DRS_TEXTUREFACTOR,
1123 D3DRS_FOGVERTEXMODE,
1126 D3DRS_NORMALIZENORMALS,
1127 D3DRS_DIFFUSEMATERIALSOURCE,
1128 D3DRS_SPECULARMATERIALSOURCE,
1129 D3DRS_AMBIENTMATERIALSOURCE,
1130 D3DRS_EMISSIVEMATERIALSOURCE,
1132 D3DRS_CLIPPLANEENABLE,
1133 #if 0 /* Driver dependent */
1136 D3DRS_POINTSIZE_MIN,
1137 D3DRS_POINTSPRITEENABLE,
1138 D3DRS_POINTSCALEENABLE,
1142 D3DRS_MULTISAMPLEANTIALIAS,
1143 D3DRS_MULTISAMPLEMASK,
1144 D3DRS_PATCHEDGESTYLE,
1145 #if 0 /* Apparently not recorded in the stateblock */
1146 D3DRS_DEBUGMONITORTOKEN,
1148 D3DRS_POINTSIZE_MAX,
1149 D3DRS_INDEXEDVERTEXBLENDENABLE,
1150 D3DRS_COLORWRITEENABLE,
1153 D3DRS_POSITIONDEGREE,
1155 D3DRS_SCISSORTESTENABLE,
1156 D3DRS_SLOPESCALEDEPTHBIAS,
1157 D3DRS_ANTIALIASEDLINEENABLE,
1158 D3DRS_MINTESSELLATIONLEVEL,
1159 D3DRS_MAXTESSELLATIONLEVEL,
1160 D3DRS_ADAPTIVETESS_X,
1161 D3DRS_ADAPTIVETESS_Y,
1162 D3DRS_ADAPTIVETESS_Z,
1163 D3DRS_ADAPTIVETESS_W,
1164 D3DRS_ENABLEADAPTIVETESSELLATION,
1165 D3DRS_TWOSIDEDSTENCILMODE,
1166 D3DRS_CCW_STENCILFAIL,
1167 D3DRS_CCW_STENCILZFAIL,
1168 D3DRS_CCW_STENCILPASS,
1169 D3DRS_CCW_STENCILFUNC,
1170 D3DRS_COLORWRITEENABLE1,
1171 D3DRS_COLORWRITEENABLE2,
1172 D3DRS_COLORWRITEENABLE3,
1174 D3DRS_SRGBWRITEENABLE,
1184 D3DRS_SEPARATEALPHABLENDENABLE,
1185 D3DRS_SRCBLENDALPHA,
1186 D3DRS_DESTBLENDALPHA,
1190 struct render_state_data
1192 DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1195 struct render_state_arg
1197 D3DPRESENT_PARAMETERS *device_pparams;
1198 float pointsize_max;
1201 struct render_state_context
1203 struct render_state_data default_data_buffer;
1204 struct render_state_data test_data_buffer;
1205 struct render_state_data poison_data_buffer;
1208 static void render_state_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1210 const struct render_state_data *rsdata = data;
1214 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1216 hret = IDirect3DDevice9_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1217 ok(hret == D3D_OK, "SetRenderState returned %#x.\n", hret);
1221 static void render_state_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
1222 const struct state_test *test, const void *expected_data)
1224 const struct render_state_context *ctx = test->test_context;
1225 const struct render_state_data *rsdata = expected_data;
1229 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1231 DWORD value = ctx->poison_data_buffer.states[i];
1232 hr = IDirect3DDevice9_GetRenderState(device, render_state_indices[i], &value);
1233 ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1234 ok(value == rsdata->states[i], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1235 chain_stage, render_state_indices[i], rsdata->states[i], value);
1239 static inline DWORD to_dword(float fl) {
1240 return *((DWORD*) &fl);
1243 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1245 DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1246 unsigned int idx = 0;
1248 data->states[idx++] = zenable; /* ZENABLE */
1249 data->states[idx++] = D3DFILL_SOLID; /* FILLMODE */
1250 data->states[idx++] = D3DSHADE_GOURAUD; /* SHADEMODE */
1251 data->states[idx++] = TRUE; /* ZWRITEENABLE */
1252 data->states[idx++] = FALSE; /* ALPHATESTENABLE */
1253 data->states[idx++] = TRUE; /* LASTPIXEL */
1254 data->states[idx++] = D3DBLEND_ONE; /* SRCBLEND */
1255 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLEND */
1256 data->states[idx++] = D3DCULL_CCW; /* CULLMODE */
1257 data->states[idx++] = D3DCMP_LESSEQUAL; /* ZFUNC */
1258 data->states[idx++] = 0; /* ALPHAREF */
1259 data->states[idx++] = D3DCMP_ALWAYS; /* ALPHAFUNC */
1260 data->states[idx++] = FALSE; /* DITHERENABLE */
1261 data->states[idx++] = FALSE; /* ALPHABLENDENABLE */
1262 data->states[idx++] = FALSE; /* FOGENABLE */
1263 data->states[idx++] = FALSE; /* SPECULARENABLE */
1264 data->states[idx++] = 0; /* FOGCOLOR */
1265 data->states[idx++] = D3DFOG_NONE; /* FOGTABLEMODE */
1266 data->states[idx++] = to_dword(0.0f); /* FOGSTART */
1267 data->states[idx++] = to_dword(1.0f); /* FOGEND */
1268 data->states[idx++] = to_dword(1.0f); /* FOGDENSITY */
1269 data->states[idx++] = FALSE; /* RANGEFOGENABLE */
1270 data->states[idx++] = FALSE; /* STENCILENABLE */
1271 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILFAIL */
1272 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILZFAIL */
1273 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILPASS */
1274 data->states[idx++] = D3DCMP_ALWAYS; /* STENCILFUNC */
1275 data->states[idx++] = 0; /* STENCILREF */
1276 data->states[idx++] = 0xFFFFFFFF; /* STENCILMASK */
1277 data->states[idx++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1278 data->states[idx++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1279 data->states[idx++] = 0; /* WRAP 0 */
1280 data->states[idx++] = 0; /* WRAP 1 */
1281 data->states[idx++] = 0; /* WRAP 2 */
1282 data->states[idx++] = 0; /* WRAP 3 */
1283 data->states[idx++] = 0; /* WRAP 4 */
1284 data->states[idx++] = 0; /* WRAP 5 */
1285 data->states[idx++] = 0; /* WRAP 6 */
1286 data->states[idx++] = 0; /* WRAP 7 */
1287 data->states[idx++] = TRUE; /* CLIPPING */
1288 data->states[idx++] = TRUE; /* LIGHTING */
1289 data->states[idx++] = 0; /* AMBIENT */
1290 data->states[idx++] = D3DFOG_NONE; /* FOGVERTEXMODE */
1291 data->states[idx++] = TRUE; /* COLORVERTEX */
1292 data->states[idx++] = TRUE; /* LOCALVIEWER */
1293 data->states[idx++] = FALSE; /* NORMALIZENORMALS */
1294 data->states[idx++] = D3DMCS_COLOR1; /* DIFFUSEMATERIALSOURCE */
1295 data->states[idx++] = D3DMCS_COLOR2; /* SPECULARMATERIALSOURCE */
1296 data->states[idx++] = D3DMCS_MATERIAL; /* AMBIENTMATERIALSOURCE */
1297 data->states[idx++] = D3DMCS_MATERIAL; /* EMISSIVEMATERIALSOURCE */
1298 data->states[idx++] = D3DVBF_DISABLE; /* VERTEXBLEND */
1299 data->states[idx++] = 0; /* CLIPPLANEENABLE */
1300 #if 0 /* Driver dependent, increase array size to enable */
1301 data->states[idx++] = to_dword(1.0f); /* POINTSIZE */
1303 data->states[idx++] = to_dword(1.0f); /* POINTSIZEMIN */
1304 data->states[idx++] = FALSE; /* POINTSPRITEENABLE */
1305 data->states[idx++] = FALSE; /* POINTSCALEENABLE */
1306 data->states[idx++] = to_dword(1.0f); /* POINTSCALE_A */
1307 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_B */
1308 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_C */
1309 data->states[idx++] = TRUE; /* MULTISAMPLEANTIALIAS */
1310 data->states[idx++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1311 data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1312 if (0) data->states[idx++] = 0xbaadcafe; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1313 data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1314 data->states[idx++] = FALSE; /* INDEXEDVERTEXBLENDENABLE */
1315 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE */
1316 data->states[idx++] = to_dword(0.0f); /* TWEENFACTOR */
1317 data->states[idx++] = D3DBLENDOP_ADD; /* BLENDOP */
1318 data->states[idx++] = D3DDEGREE_CUBIC; /* POSITIONDEGREE */
1319 data->states[idx++] = D3DDEGREE_LINEAR; /* NORMALDEGREE */
1320 data->states[idx++] = FALSE; /* SCISSORTESTENABLE */
1321 data->states[idx++] = to_dword(0.0f); /* SLOPESCALEDEPTHBIAS */
1322 data->states[idx++] = FALSE; /* ANTIALIASEDLINEENABLE */
1323 data->states[idx++] = to_dword(1.0f); /* MINTESSELATIONLEVEL */
1324 data->states[idx++] = to_dword(1.0f); /* MAXTESSELATIONLEVEL */
1325 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_X */
1326 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_Y */
1327 data->states[idx++] = to_dword(1.0f); /* ADAPTIVETESS_Z */
1328 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_W */
1329 data->states[idx++] = FALSE; /* ENABLEADAPTIVETESSELATION */
1330 data->states[idx++] = FALSE; /* TWOSIDEDSTENCILMODE */
1331 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILFAIL */
1332 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILZFAIL */
1333 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILPASS */
1334 data->states[idx++] = D3DCMP_ALWAYS; /* CCW_STENCILFUNC */
1335 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE1 */
1336 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE2 */
1337 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE3 */
1338 data->states[idx++] = 0xFFFFFFFF; /* BLENDFACTOR */
1339 data->states[idx++] = 0; /* SRGBWRITEENABLE */
1340 data->states[idx++] = to_dword(0.0f); /* DEPTHBIAS */
1341 data->states[idx++] = 0; /* WRAP8 */
1342 data->states[idx++] = 0; /* WRAP9 */
1343 data->states[idx++] = 0; /* WRAP10 */
1344 data->states[idx++] = 0; /* WRAP11 */
1345 data->states[idx++] = 0; /* WRAP12 */
1346 data->states[idx++] = 0; /* WRAP13 */
1347 data->states[idx++] = 0; /* WRAP14 */
1348 data->states[idx++] = 0; /* WRAP15 */
1349 data->states[idx++] = FALSE; /* SEPARATEALPHABLENDENABLE */
1350 data->states[idx++] = D3DBLEND_ONE; /* SRCBLENDALPHA */
1351 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLENDALPHA */
1352 data->states[idx++] = TRUE; /* BLENDOPALPHA */
1355 static void render_state_poison_data_init(struct render_state_data *data)
1359 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1361 data->states[i] = 0x1337c0de;
1365 static void render_state_test_data_init(struct render_state_data *data)
1367 unsigned int idx = 0;
1368 data->states[idx++] = D3DZB_USEW; /* ZENABLE */
1369 data->states[idx++] = D3DFILL_WIREFRAME; /* FILLMODE */
1370 data->states[idx++] = D3DSHADE_PHONG; /* SHADEMODE */
1371 data->states[idx++] = FALSE; /* ZWRITEENABLE */
1372 data->states[idx++] = TRUE; /* ALPHATESTENABLE */
1373 data->states[idx++] = FALSE; /* LASTPIXEL */
1374 data->states[idx++] = D3DBLEND_SRCALPHASAT; /* SRCBLEND */
1375 data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1376 data->states[idx++] = D3DCULL_CW; /* CULLMODE */
1377 data->states[idx++] = D3DCMP_NOTEQUAL; /* ZFUNC */
1378 data->states[idx++] = 10; /* ALPHAREF */
1379 data->states[idx++] = D3DCMP_GREATER; /* ALPHAFUNC */
1380 data->states[idx++] = TRUE; /* DITHERENABLE */
1381 data->states[idx++] = TRUE; /* ALPHABLENDENABLE */
1382 data->states[idx++] = TRUE; /* FOGENABLE */
1383 data->states[idx++] = TRUE; /* SPECULARENABLE */
1384 data->states[idx++] = 255 << 31; /* FOGCOLOR */
1385 data->states[idx++] = D3DFOG_EXP; /* FOGTABLEMODE */
1386 data->states[idx++] = to_dword(0.1f); /* FOGSTART */
1387 data->states[idx++] = to_dword(0.8f); /* FOGEND */
1388 data->states[idx++] = to_dword(0.5f); /* FOGDENSITY */
1389 data->states[idx++] = TRUE; /* RANGEFOGENABLE */
1390 data->states[idx++] = TRUE; /* STENCILENABLE */
1391 data->states[idx++] = D3DSTENCILOP_INCRSAT; /* STENCILFAIL */
1392 data->states[idx++] = D3DSTENCILOP_REPLACE; /* STENCILZFAIL */
1393 data->states[idx++] = D3DSTENCILOP_INVERT; /* STENCILPASS */
1394 data->states[idx++] = D3DCMP_LESS; /* STENCILFUNC */
1395 data->states[idx++] = 10; /* STENCILREF */
1396 data->states[idx++] = 0xFF00FF00; /* STENCILMASK */
1397 data->states[idx++] = 0x00FF00FF; /* STENCILWRITEMASK */
1398 data->states[idx++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1399 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 0 */
1400 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 1 */
1401 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 2 */
1402 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 4 */
1403 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 5 */
1404 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 6 */
1405 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 7 */
1406 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1407 data->states[idx++] = FALSE; /* CLIPPING */
1408 data->states[idx++] = FALSE; /* LIGHTING */
1409 data->states[idx++] = 255 << 16; /* AMBIENT */
1410 data->states[idx++] = D3DFOG_EXP2; /* FOGVERTEXMODE */
1411 data->states[idx++] = FALSE; /* COLORVERTEX */
1412 data->states[idx++] = FALSE; /* LOCALVIEWER */
1413 data->states[idx++] = TRUE; /* NORMALIZENORMALS */
1414 data->states[idx++] = D3DMCS_COLOR2; /* DIFFUSEMATERIALSOURCE */
1415 data->states[idx++] = D3DMCS_MATERIAL; /* SPECULARMATERIALSOURCE */
1416 data->states[idx++] = D3DMCS_COLOR1; /* AMBIENTMATERIALSOURCE */
1417 data->states[idx++] = D3DMCS_COLOR2; /* EMISSIVEMATERIALSOURCE */
1418 data->states[idx++] = D3DVBF_3WEIGHTS; /* VERTEXBLEND */
1419 data->states[idx++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1420 #if 0 /* Driver dependent, increase array size to enable */
1421 data->states[idx++] = to_dword(32.0f); /* POINTSIZE */
1423 data->states[idx++] = to_dword(0.7f); /* POINTSIZEMIN */
1424 data->states[idx++] = TRUE; /* POINTSPRITEENABLE */
1425 data->states[idx++] = TRUE; /* POINTSCALEENABLE */
1426 data->states[idx++] = to_dword(0.7f); /* POINTSCALE_A */
1427 data->states[idx++] = to_dword(0.5f); /* POINTSCALE_B */
1428 data->states[idx++] = to_dword(0.4f); /* POINTSCALE_C */
1429 data->states[idx++] = FALSE; /* MULTISAMPLEANTIALIAS */
1430 data->states[idx++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1431 data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1432 if (0) data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1433 data->states[idx++] = to_dword(77.0f); /* POINTSIZE_MAX */
1434 data->states[idx++] = TRUE; /* INDEXEDVERTEXBLENDENABLE */
1435 data->states[idx++] = 0x00000009; /* COLORWRITEENABLE */
1436 data->states[idx++] = to_dword(0.2f); /* TWEENFACTOR */
1437 data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1438 data->states[idx++] = D3DDEGREE_LINEAR; /* POSITIONDEGREE */
1439 data->states[idx++] = D3DDEGREE_CUBIC; /* NORMALDEGREE */
1440 data->states[idx++] = TRUE; /* SCISSORTESTENABLE */
1441 data->states[idx++] = to_dword(0.33f); /* SLOPESCALEDEPTHBIAS */
1442 data->states[idx++] = TRUE; /* ANTIALIASEDLINEENABLE */
1443 data->states[idx++] = to_dword(0.8f); /* MINTESSELATIONLEVEL */
1444 data->states[idx++] = to_dword(0.8f); /* MAXTESSELATIONLEVEL */
1445 data->states[idx++] = to_dword(0.2f); /* ADAPTIVETESS_X */
1446 data->states[idx++] = to_dword(0.3f); /* ADAPTIVETESS_Y */
1447 data->states[idx++] = to_dword(0.6f); /* ADAPTIVETESS_Z */
1448 data->states[idx++] = to_dword(0.4f); /* ADAPTIVETESS_W */
1449 data->states[idx++] = TRUE; /* ENABLEADAPTIVETESSELATION */
1450 data->states[idx++] = TRUE; /* TWOSIDEDSTENCILMODE */
1451 data->states[idx++] = D3DSTENCILOP_ZERO; /* CCW_STENCILFAIL */
1452 data->states[idx++] = D3DSTENCILOP_DECR; /* CCW_STENCILZFAIL */
1453 data->states[idx++] = D3DSTENCILOP_INCR; /* CCW_STENCILPASS */
1454 data->states[idx++] = D3DCMP_ALWAYS; /* CCW_STENCILFUNC */
1455 data->states[idx++] = 0x00000007; /* COLORWRITEENABLE1 */
1456 data->states[idx++] = 0x00000008; /* COLORWRITEENABLE2 */
1457 data->states[idx++] = 0x00000004; /* COLORWRITEENABLE3 */
1458 data->states[idx++] = 0xF0F1F2F3; /* BLENDFACTOR */
1459 data->states[idx++] = 1; /* SRGBWRITEENABLE */
1460 data->states[idx++] = to_dword(0.3f); /* DEPTHBIAS */
1461 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 8 */
1462 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 9 */
1463 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 10 */
1464 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 11 */
1465 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 12 */
1466 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 13 */
1467 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 14 */
1468 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 15 */
1469 data->states[idx++] = TRUE; /* SEPARATEALPHABLENDENABLE */
1470 data->states[idx++] = D3DBLEND_ZERO; /* SRCBLENDALPHA */
1471 data->states[idx++] = D3DBLEND_ONE; /* DESTBLENDALPHA */
1472 data->states[idx++] = FALSE; /* BLENDOPALPHA */
1475 static HRESULT render_state_setup_handler(struct state_test *test)
1477 const struct render_state_arg *rsarg = test->test_arg;
1479 struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1480 if (ctx == NULL) return E_FAIL;
1481 test->test_context = ctx;
1483 test->default_data = &ctx->default_data_buffer;
1484 test->initial_data = &ctx->default_data_buffer;
1485 test->test_data_in = &ctx->test_data_buffer;
1486 test->test_data_out = &ctx->test_data_buffer;
1488 render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1489 render_state_test_data_init(&ctx->test_data_buffer);
1490 render_state_poison_data_init(&ctx->poison_data_buffer);
1495 static void render_state_teardown_handler(struct state_test *test)
1497 HeapFree(GetProcessHeap(), 0, test->test_context);
1500 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1502 test->setup_handler = render_state_setup_handler;
1503 test->teardown_handler = render_state_teardown_handler;
1504 test->set_handler = render_state_set_handler;
1505 test->check_data = render_state_check_data;
1506 test->test_name = "set_get_render_states";
1507 test->test_arg = test_arg;
1510 /* =================== Main state tests function =============================== */
1512 static void test_state_management(IDirect3DDevice9 *device, D3DPRESENT_PARAMETERS *device_pparams)
1514 struct shader_constant_arg pshader_constant_arg;
1515 struct shader_constant_arg vshader_constant_arg;
1516 struct render_state_arg render_state_arg;
1517 struct light_arg light_arg;
1521 /* Test count: 2 for shader constants
1526 struct state_test tests[5];
1527 unsigned int tcount = 0;
1529 hret = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1530 ok(hret == D3D_OK, "GetDeviceCaps returned %#x.\n", hret);
1531 if (hret != D3D_OK) return;
1533 texture_stages = caps.MaxTextureBlendStages;
1535 /* Zero test memory */
1536 memset(tests, 0, sizeof(tests));
1538 if (caps.VertexShaderVersion & 0xffff) {
1539 vshader_constant_arg.idx = 0;
1540 vshader_constant_arg.pshader = FALSE;
1541 shader_constants_queue_test(&tests[tcount], &vshader_constant_arg);
1545 if (caps.PixelShaderVersion & 0xffff) {
1546 pshader_constant_arg.idx = 0;
1547 pshader_constant_arg.pshader = TRUE;
1548 shader_constants_queue_test(&tests[tcount], &pshader_constant_arg);
1553 lights_queue_test(&tests[tcount], &light_arg);
1556 transform_queue_test(&tests[tcount]);
1559 render_state_arg.device_pparams = device_pparams;
1560 render_state_arg.pointsize_max = caps.MaxPointSize;
1561 render_states_queue_test(&tests[tcount], &render_state_arg);
1564 execute_test_chain_all(device, tests, tcount);
1567 static void test_shader_constant_apply(IDirect3DDevice9 *device)
1569 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
1570 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
1571 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
1572 IDirect3DStateBlock9 *stateblock;
1576 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
1577 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1578 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
1579 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1580 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
1581 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1582 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
1583 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1585 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
1586 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1587 ok(!memcmp(ret, initial, sizeof(initial)),
1588 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1589 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1590 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
1591 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1592 ok(!memcmp(ret, initial, sizeof(initial)),
1593 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1594 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1595 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
1596 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1597 ok(!memcmp(ret, initial, sizeof(initial)),
1598 "GetpixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1599 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1600 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
1601 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1602 ok(!memcmp(ret, initial, sizeof(initial)),
1603 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1604 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1606 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
1607 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1608 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
1609 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1611 hr = IDirect3DDevice9_BeginStateBlock(device);
1612 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x\n", hr);
1614 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
1615 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1616 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
1617 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1619 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
1620 ok(SUCCEEDED(hr), "EndStateBlock returned %#x\n", hr);
1622 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
1623 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1624 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1625 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1626 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1627 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
1628 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1629 ok(!memcmp(ret, initial, sizeof(initial)),
1630 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1631 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1632 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
1633 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1634 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1635 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1636 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1637 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
1638 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1639 ok(!memcmp(ret, initial, sizeof(initial)),
1640 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1641 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1643 hr = IDirect3DStateBlock9_Apply(stateblock);
1644 ok(SUCCEEDED(hr), "Apply returned %#x\n", hr);
1646 /* Apply doesn't overwrite constants that aren't explicitly set on the source stateblock. */
1647 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
1648 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1649 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1650 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1651 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1652 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
1653 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1654 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1655 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1656 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1657 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
1658 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1659 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1660 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1661 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1662 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
1663 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1664 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1665 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1666 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1668 IDirect3DStateBlock9_Release(stateblock);
1671 START_TEST(stateblock)
1673 IDirect3DDevice9 *device_ptr = NULL;
1674 D3DPRESENT_PARAMETERS device_pparams;
1678 d3d9_handle = LoadLibraryA("d3d9.dll");
1681 skip("Could not load d3d9.dll\n");
1685 hret = init_d3d9(&device_ptr, &device_pparams);
1686 if (hret != D3D_OK) return;
1688 test_begin_end_state_block(device_ptr);
1689 test_state_management(device_ptr, &device_pparams);
1690 test_shader_constant_apply(device_ptr);
1692 refcount = IDirect3DDevice9_Release(device_ptr);
1693 ok(!refcount, "Device has %u references left\n", refcount);