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 begin_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
301 hret = IDirect3DDevice9_BeginStateBlock(device);
302 ok(hret == D3D_OK, "BeginStateBlock returned %#x.\n", hret);
303 if (hret != D3D_OK) return EVENT_ERROR;
307 static int end_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
311 hret = IDirect3DDevice9_EndStateBlock(device, &event_data->stateblock);
312 ok(hret == D3D_OK, "EndStateBlock returned %#x.\n", hret);
313 if (hret != D3D_OK) return EVENT_ERROR;
317 static int abort_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
319 IUnknown_Release(event_data->stateblock);
323 static int apply_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
327 hret = IDirect3DStateBlock9_Apply(event_data->stateblock);
328 ok(hret == D3D_OK, "Apply returned %#x.\n", hret);
329 if (hret != D3D_OK) {
330 IUnknown_Release(event_data->stateblock);
334 IUnknown_Release(event_data->stateblock);
339 static int capture_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
343 hret = IDirect3DStateBlock9_Capture(event_data->stateblock);
344 ok(hret == D3D_OK, "Capture returned %#x.\n", hret);
351 static void execute_test_chain_all(IDirect3DDevice9 *device, struct state_test *test, unsigned int ntests)
353 struct event_data arg;
356 struct event read_events[] =
358 {NULL, SB_DATA_INITIAL, SB_DATA_NONE},
361 struct event write_read_events[] =
363 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
364 {NULL, SB_DATA_TEST, SB_DATA_NONE},
367 struct event abort_stateblock_events[] =
369 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
370 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
371 {abort_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
374 struct event apply_stateblock_events[] =
376 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
377 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
378 {apply_stateblock, SB_DATA_TEST, SB_DATA_NONE},
381 struct event capture_reapply_stateblock_events[] =
383 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
384 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
385 {capture_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
386 {apply_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
389 struct event rendertarget_switch_events[] =
391 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
392 {switch_render_target, SB_DATA_TEST, SB_DATA_NONE},
393 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
396 struct event rendertarget_stateblock_events[] =
398 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
399 {switch_render_target, SB_DATA_DEFAULT, SB_DATA_NONE},
400 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
401 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
402 {apply_stateblock, SB_DATA_TEST, SB_DATA_NONE},
405 /* Setup each test for execution */
406 for (i=0; i < ntests; i++) {
407 if (test[i].setup_handler(&test[i]) != D3D_OK) {
408 ok(FALSE, "Test \"%s\" failed setup, aborting\n", test[i].test_name);
413 trace("Running initial read state tests\n");
414 execute_test_chain(device, test, ntests, read_events, 1, NULL);
416 trace("Running write-read state tests\n");
417 execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
419 trace("Running stateblock abort state tests\n");
420 execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
422 trace("Running stateblock apply state tests\n");
423 execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
425 trace("Running stateblock capture/reapply state tests\n");
426 execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
428 trace("Running rendertarget switch state tests\n");
429 execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
431 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
432 execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
434 /* Cleanup resources */
435 for (i=0; i < ntests; i++)
436 test[i].teardown_handler(&test[i]);
439 /* =================== State test: Pixel and Vertex Shader constants ============ */
441 struct shader_constant_data
443 int int_constant[4]; /* 1x4 integer constant */
444 float float_constant[4]; /* 1x4 float constant */
445 BOOL bool_constant[4]; /* 4x1 boolean constants */
448 struct shader_constant_arg
454 static const struct shader_constant_data shader_constant_poison_data =
456 {0x1337c0de, 0x1337c0de, 0x1337c0de, 0x1337c0de},
457 {1.0f, 2.0f, 3.0f, 4.0f},
458 {FALSE, TRUE, FALSE, TRUE},
461 static const struct shader_constant_data shader_constant_default_data =
464 {0.0f, 0.0f, 0.0f, 0.0f},
468 static const struct shader_constant_data shader_constant_test_data =
470 {0xdead0000, 0xdead0001, 0xdead0002, 0xdead0003},
471 {5.0f, 6.0f, 7.0f, 8.0f},
472 {TRUE, FALSE, FALSE, TRUE},
475 static void shader_constant_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
477 const struct shader_constant_arg *scarg = test->test_arg;
478 const struct shader_constant_data *scdata = data;
480 unsigned int index = scarg->idx;
482 if (!scarg->pshader) {
483 hret = IDirect3DDevice9_SetVertexShaderConstantI(device, index, scdata->int_constant, 1);
484 ok(hret == D3D_OK, "SetVertexShaderConstantI returned %#x.\n", hret);
485 hret = IDirect3DDevice9_SetVertexShaderConstantF(device, index, scdata->float_constant, 1);
486 ok(hret == D3D_OK, "SetVertexShaderConstantF returned %#x.\n", hret);
487 hret = IDirect3DDevice9_SetVertexShaderConstantB(device, index, scdata->bool_constant, 4);
488 ok(hret == D3D_OK, "SetVertexShaderConstantB returned %#x.\n", hret);
491 hret = IDirect3DDevice9_SetPixelShaderConstantI(device, index, scdata->int_constant, 1);
492 ok(hret == D3D_OK, "SetPixelShaderConstantI returned %#x.\n", hret);
493 hret = IDirect3DDevice9_SetPixelShaderConstantF(device, index, scdata->float_constant, 1);
494 ok(hret == D3D_OK, "SetPixelShaderConstantF returned %#x.\n", hret);
495 hret = IDirect3DDevice9_SetPixelShaderConstantB(device, index, scdata->bool_constant, 4);
496 ok(hret == D3D_OK, "SetPixelShaderConstantB returned %#x.\n", hret);
500 static void shader_constant_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
501 const struct state_test *test, const void *expected_data)
503 struct shader_constant_data value = shader_constant_poison_data;
504 const struct shader_constant_data *scdata = expected_data;
505 const struct shader_constant_arg *scarg = test->test_arg;
510 hr = IDirect3DDevice9_GetVertexShaderConstantI(device, scarg->idx, value.int_constant, 1);
511 ok(SUCCEEDED(hr), "GetVertexShaderConstantI returned %#x.\n", hr);
512 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, scarg->idx, value.float_constant, 1);
513 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x.\n", hr);
514 hr = IDirect3DDevice9_GetVertexShaderConstantB(device, scarg->idx, value.bool_constant, 4);
515 ok(SUCCEEDED(hr), "GetVertexShaderConstantB returned %#x.\n", hr);
519 hr = IDirect3DDevice9_GetPixelShaderConstantI(device, scarg->idx, value.int_constant, 1);
520 ok(SUCCEEDED(hr), "GetPixelShaderConstantI returned %#x.\n", hr);
521 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, scarg->idx, value.float_constant, 1);
522 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x.\n", hr);
523 hr = IDirect3DDevice9_GetPixelShaderConstantB(device, scarg->idx, value.bool_constant, 4);
524 ok(SUCCEEDED(hr), "GetPixelShaderConstantB returned %#x.\n", hr);
527 ok(!memcmp(scdata->int_constant, value.int_constant, sizeof(scdata->int_constant)),
528 "Chain stage %u, %s integer constant:\n"
529 "\t{%#x, %#x, %#x, %#x} expected\n"
530 "\t{%#x, %#x, %#x, %#x} received\n",
531 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
532 scdata->int_constant[0], scdata->int_constant[1],
533 scdata->int_constant[2], scdata->int_constant[3],
534 value.int_constant[0], value.int_constant[1],
535 value.int_constant[2], value.int_constant[3]);
537 ok(!memcmp(scdata->float_constant, value.float_constant, sizeof(scdata->float_constant)),
538 "Chain stage %u, %s float constant:\n"
539 "\t{%.8e, %.8e, %.8e, %.8e} expected\n"
540 "\t{%.8e, %.8e, %.8e, %.8e} received\n",
541 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
542 scdata->float_constant[0], scdata->float_constant[1],
543 scdata->float_constant[2], scdata->float_constant[3],
544 value.float_constant[0], value.float_constant[1],
545 value.float_constant[2], value.float_constant[3]);
547 ok(!memcmp(scdata->bool_constant, value.bool_constant, sizeof(scdata->bool_constant)),
548 "Chain stage %u, %s boolean constant:\n"
549 "\t{%#x, %#x, %#x, %#x} expected\n"
550 "\t{%#x, %#x, %#x, %#x} received\n",
551 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
552 scdata->bool_constant[0], scdata->bool_constant[1],
553 scdata->bool_constant[2], scdata->bool_constant[3],
554 value.bool_constant[0], value.bool_constant[1],
555 value.bool_constant[2], value.bool_constant[3]);
558 static HRESULT shader_constant_setup_handler(struct state_test *test)
560 test->test_context = NULL;
561 test->test_data_in = &shader_constant_test_data;
562 test->test_data_out = &shader_constant_test_data;
563 test->default_data = &shader_constant_default_data;
564 test->initial_data = &shader_constant_default_data;
569 static void shader_constant_teardown_handler(struct state_test *test)
571 HeapFree(GetProcessHeap(), 0, test->test_context);
574 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
576 test->setup_handler = shader_constant_setup_handler;
577 test->teardown_handler = shader_constant_teardown_handler;
578 test->set_handler = shader_constant_set_handler;
579 test->check_data = shader_constant_check_data;
580 test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
581 test->test_arg = test_arg;
584 /* =================== State test: Lights ===================================== */
590 HRESULT get_light_result;
591 HRESULT get_enabled_result;
599 static const struct light_data light_poison_data =
603 {7.0f, 4.0f, 2.0f, 1.0f},
604 {7.0f, 4.0f, 2.0f, 1.0f},
605 {7.0f, 4.0f, 2.0f, 1.0f},
608 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
615 static const struct light_data light_default_data =
618 D3DLIGHT_DIRECTIONAL,
619 {1.0f, 1.0f, 1.0f, 0.0f},
620 {0.0f, 0.0f, 0.0f, 0.0f},
621 {0.0f, 0.0f, 0.0f, 0.0f},
624 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
631 /* This is used for the initial read state (before a write causes side effects).
632 * The proper return status is D3DERR_INVALIDCALL. */
633 static const struct light_data light_initial_data =
637 {7.0f, 4.0f, 2.0f, 1.0f},
638 {7.0f, 4.0f, 2.0f, 1.0f},
639 {7.0f, 4.0f, 2.0f, 1.0f},
642 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
649 static const struct light_data light_test_data_in =
653 {2.0f, 2.0f, 2.0f, 2.0f},
654 {3.0f, 3.0f, 3.0f, 3.0f},
655 {4.0f, 4.0f, 4.0f, 4.0f},
658 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
665 /* SetLight will use 128 as the "enabled" value */
666 static const struct light_data light_test_data_out =
670 {2.0f, 2.0f, 2.0f, 2.0f},
671 {3.0f, 3.0f, 3.0f, 3.0f},
672 {4.0f, 4.0f, 4.0f, 4.0f},
675 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
682 static void light_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
684 const struct light_arg *larg = test->test_arg;
685 const struct light_data *ldata = data;
687 unsigned int index = larg->idx;
689 hret = IDirect3DDevice9_SetLight(device, index, &ldata->light);
690 ok(hret == D3D_OK, "SetLight returned %#x.\n", hret);
692 hret = IDirect3DDevice9_LightEnable(device, index, ldata->enabled);
693 ok(hret == D3D_OK, "SetLightEnable returned %#x.\n", hret);
696 static void light_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
697 const struct state_test *test, const void *expected_data)
699 const struct light_arg *larg = test->test_arg;
700 const struct light_data *ldata = expected_data;
701 struct light_data value;
703 value = light_poison_data;
705 value.get_enabled_result = IDirect3DDevice9_GetLightEnable(device, larg->idx, &value.enabled);
706 value.get_light_result = IDirect3DDevice9_GetLight(device, larg->idx, &value.light);
708 ok(value.get_enabled_result == ldata->get_enabled_result,
709 "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
710 chain_stage, ldata->get_enabled_result, value.get_enabled_result);
711 ok(value.get_light_result == ldata->get_light_result,
712 "Chain stage %u: expected get_light_result %#x, got %#x.\n",
713 chain_stage, ldata->get_light_result, value.get_light_result);
715 ok(value.enabled == ldata->enabled,
716 "Chain stage %u: expected enabled %#x, got %#x.\n",
717 chain_stage, ldata->enabled, value.enabled);
718 ok(value.light.Type == ldata->light.Type,
719 "Chain stage %u: expected light.Type %#x, got %#x.\n",
720 chain_stage, ldata->light.Type, value.light.Type);
721 ok(!memcmp(&value.light.Diffuse, &ldata->light.Diffuse, sizeof(value.light.Diffuse)),
722 "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
723 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
724 ldata->light.Diffuse.r, ldata->light.Diffuse.g,
725 ldata->light.Diffuse.b, ldata->light.Diffuse.a,
726 value.light.Diffuse.r, value.light.Diffuse.g,
727 value.light.Diffuse.b, value.light.Diffuse.a);
728 ok(!memcmp(&value.light.Specular, &ldata->light.Specular, sizeof(value.light.Specular)),
729 "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
730 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
731 ldata->light.Specular.r, ldata->light.Specular.g,
732 ldata->light.Specular.b, ldata->light.Specular.a,
733 value.light.Specular.r, value.light.Specular.g,
734 value.light.Specular.b, value.light.Specular.a);
735 ok(!memcmp(&value.light.Ambient, &ldata->light.Ambient, sizeof(value.light.Ambient)),
736 "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
737 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
738 ldata->light.Ambient.r, ldata->light.Ambient.g,
739 ldata->light.Ambient.b, ldata->light.Ambient.a,
740 value.light.Ambient.r, value.light.Ambient.g,
741 value.light.Ambient.b, value.light.Ambient.a);
742 ok(!memcmp(&value.light.Position, &ldata->light.Position, sizeof(value.light.Position)),
743 "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
744 chain_stage, ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z,
745 value.light.Position.x, value.light.Position.y, value.light.Position.z);
746 ok(!memcmp(&value.light.Direction, &ldata->light.Direction, sizeof(value.light.Direction)),
747 "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
748 chain_stage, ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z,
749 value.light.Direction.x, value.light.Direction.y, value.light.Direction.z);
750 ok(value.light.Range == ldata->light.Range,
751 "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
752 chain_stage, ldata->light.Range, value.light.Range);
753 ok(value.light.Falloff == ldata->light.Falloff,
754 "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
755 chain_stage, ldata->light.Falloff, value.light.Falloff);
756 ok(value.light.Attenuation0 == ldata->light.Attenuation0,
757 "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
758 chain_stage, ldata->light.Attenuation0, value.light.Attenuation0);
759 ok(value.light.Attenuation1 == ldata->light.Attenuation1,
760 "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
761 chain_stage, ldata->light.Attenuation1, value.light.Attenuation1);
762 ok(value.light.Attenuation2 == ldata->light.Attenuation2,
763 "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
764 chain_stage, ldata->light.Attenuation2, value.light.Attenuation2);
765 ok(value.light.Theta == ldata->light.Theta,
766 "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
767 chain_stage, ldata->light.Theta, value.light.Theta);
768 ok(value.light.Phi == ldata->light.Phi,
769 "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
770 chain_stage, ldata->light.Phi, value.light.Phi);
773 static HRESULT light_setup_handler(struct state_test *test)
775 test->test_context = NULL;
776 test->test_data_in = &light_test_data_in;
777 test->test_data_out = &light_test_data_out;
778 test->default_data = &light_default_data;
779 test->initial_data = &light_initial_data;
784 static void light_teardown_handler(struct state_test *test)
786 HeapFree(GetProcessHeap(), 0, test->test_context);
789 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
791 test->setup_handler = light_setup_handler;
792 test->teardown_handler = light_teardown_handler;
793 test->set_handler = light_set_handler;
794 test->check_data = light_check_data;
795 test->test_name = "set_get_light";
796 test->test_arg = test_arg;
799 /* =================== State test: Transforms ===================================== */
801 struct transform_data
804 D3DMATRIX projection;
811 static const struct transform_data transform_default_data =
814 1.0f, 0.0f, 0.0f, 0.0f,
815 0.0f, 1.0f, 0.0f, 0.0f,
816 0.0f, 0.0f, 1.0f, 0.0f,
817 0.0f, 0.0f, 0.0f, 1.0f,
820 1.0f, 0.0f, 0.0f, 0.0f,
821 0.0f, 1.0f, 0.0f, 0.0f,
822 0.0f, 0.0f, 1.0f, 0.0f,
823 0.0f, 0.0f, 0.0f, 1.0f,
826 1.0f, 0.0f, 0.0f, 0.0f,
827 0.0f, 1.0f, 0.0f, 0.0f,
828 0.0f, 0.0f, 1.0f, 0.0f,
829 0.0f, 0.0f, 0.0f, 1.0f,
832 1.0f, 0.0f, 0.0f, 0.0f,
833 0.0f, 1.0f, 0.0f, 0.0f,
834 0.0f, 0.0f, 1.0f, 0.0f,
835 0.0f, 0.0f, 0.0f, 1.0f,
838 1.0f, 0.0f, 0.0f, 0.0f,
839 0.0f, 1.0f, 0.0f, 0.0f,
840 0.0f, 0.0f, 1.0f, 0.0f,
841 0.0f, 0.0f, 0.0f, 1.0f,
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,
851 static const struct transform_data transform_poison_data =
854 1.0f, 2.0f, 3.0f, 4.0f,
855 5.0f, 6.0f, 7.0f, 8.0f,
856 9.0f, 10.0f, 11.0f, 12.0f,
857 13.0f, 14.0f, 15.0f, 16.0f,
860 17.0f, 18.0f, 19.0f, 20.0f,
861 21.0f, 22.0f, 23.0f, 24.0f,
862 25.0f, 26.0f, 27.0f, 28.0f,
863 29.0f, 30.0f, 31.0f, 32.0f,
866 33.0f, 34.0f, 35.0f, 36.0f,
867 37.0f, 38.0f, 39.0f, 40.0f,
868 41.0f, 42.0f, 43.0f, 44.0f,
869 45.0f, 46.0f, 47.0f, 48.0f
872 49.0f, 50.0f, 51.0f, 52.0f,
873 53.0f, 54.0f, 55.0f, 56.0f,
874 57.0f, 58.0f, 59.0f, 60.0f,
875 61.0f, 62.0f, 63.0f, 64.0f,
878 64.0f, 66.0f, 67.0f, 68.0f,
879 69.0f, 70.0f, 71.0f, 72.0f,
880 73.0f, 74.0f, 75.0f, 76.0f,
881 77.0f, 78.0f, 79.0f, 80.0f,
884 81.0f, 82.0f, 83.0f, 84.0f,
885 85.0f, 86.0f, 87.0f, 88.0f,
886 89.0f, 90.0f, 91.0f, 92.0f,
887 93.0f, 94.0f, 95.0f, 96.0f,
891 static const struct transform_data transform_test_data =
894 1.2f, 3.4f, -5.6f, 7.2f,
895 10.11f, -12.13f, 14.15f, -1.5f,
896 23.56f, 12.89f, 44.56f, -1.0f,
897 2.3f, 0.0f, 4.4f, 5.5f,
900 9.2f, 38.7f, -6.6f, 7.2f,
901 10.11f, -12.13f, 77.15f, -1.5f,
902 23.56f, 12.89f, 14.56f, -1.0f,
903 12.3f, 0.0f, 4.4f, 5.5f,
906 10.2f, 3.4f, 0.6f, 7.2f,
907 10.11f, -12.13f, 14.15f, -1.5f,
908 23.54f, 12.9f, 44.56f, -1.0f,
909 2.3f, 0.0f, 4.4f, 5.5f,
912 1.2f, 3.4f, -5.6f, 7.2f,
913 10.11f, -12.13f, -14.5f, -1.5f,
914 2.56f, 12.89f, 23.56f, -1.0f,
915 112.3f, 0.0f, 4.4f, 2.5f,
918 1.2f, 31.41f, 58.6f, 7.2f,
919 10.11f, -12.13f, -14.5f, -1.5f,
920 2.56f, 12.89f, 11.56f, -1.0f,
921 112.3f, 0.0f, 44.4f, 2.5f,
924 1.20f, 3.4f, -5.6f, 7.0f,
925 10.11f, -12.156f, -14.5f, -1.5f,
926 2.56f, 1.829f, 23.6f, -1.0f,
927 112.3f, 0.0f, 41.4f, 2.5f,
931 static void transform_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
933 const struct transform_data *tdata = data;
936 hret = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &tdata->view);
937 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
939 hret = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
940 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
942 hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
943 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
945 hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
946 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
948 hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &tdata->world0);
949 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
951 hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
952 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
955 static void compare_matrix(const char *name, unsigned int chain_stage,
956 const D3DMATRIX *received, const D3DMATRIX *expected)
958 ok(!memcmp(expected, received, sizeof(*expected)),
959 "Chain stage %u, matrix %s:\n"
961 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
962 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
963 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
964 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
967 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
968 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
969 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
970 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
973 U(*expected).m[0][0], U(*expected).m[1][0], U(*expected).m[2][0], U(*expected).m[3][0],
974 U(*expected).m[0][1], U(*expected).m[1][1], U(*expected).m[2][1], U(*expected).m[3][1],
975 U(*expected).m[0][2], U(*expected).m[1][2], U(*expected).m[2][2], U(*expected).m[3][2],
976 U(*expected).m[0][3], U(*expected).m[1][3], U(*expected).m[2][3], U(*expected).m[3][3],
977 U(*received).m[0][0], U(*received).m[1][0], U(*received).m[2][0], U(*received).m[3][0],
978 U(*received).m[0][1], U(*received).m[1][1], U(*received).m[2][1], U(*received).m[3][1],
979 U(*received).m[0][2], U(*received).m[1][2], U(*received).m[2][2], U(*received).m[3][2],
980 U(*received).m[0][3], U(*received).m[1][3], U(*received).m[2][3], U(*received).m[3][3]);
983 static void transform_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
984 const struct state_test *test, const void *expected_data)
986 const struct transform_data *tdata = expected_data;
990 value = transform_poison_data.view;
991 hr = IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &value);
992 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
993 compare_matrix("View", chain_stage, &value, &tdata->view);
995 value = transform_poison_data.projection;
996 hr = IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &value);
997 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
998 compare_matrix("Projection", chain_stage, &value, &tdata->projection);
1000 value = transform_poison_data.texture0;
1001 hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0, &value);
1002 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1003 compare_matrix("Texture0", chain_stage, &value, &tdata->texture0);
1005 value = transform_poison_data.texture7;
1006 hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &value);
1007 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1008 compare_matrix("Texture7", chain_stage, &value, &tdata->texture7);
1010 value = transform_poison_data.world0;
1011 hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &value);
1012 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1013 compare_matrix("World0", chain_stage, &value, &tdata->world0);
1015 value = transform_poison_data.world255;
1016 hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(255), &value);
1017 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1018 compare_matrix("World255", chain_stage, &value, &tdata->world255);
1021 static HRESULT transform_setup_handler(struct state_test *test)
1023 test->test_context = NULL;
1024 test->test_data_in = &transform_test_data;
1025 test->test_data_out = &transform_test_data;
1026 test->default_data = &transform_default_data;
1027 test->initial_data = &transform_default_data;
1032 static void transform_teardown_handler(struct state_test *test)
1034 HeapFree(GetProcessHeap(), 0, test->test_context);
1037 static void transform_queue_test(struct state_test *test)
1039 test->setup_handler = transform_setup_handler;
1040 test->teardown_handler = transform_teardown_handler;
1041 test->set_handler = transform_set_handler;
1042 test->check_data = transform_check_data;
1043 test->test_name = "set_get_transforms";
1044 test->test_arg = NULL;
1047 /* =================== State test: Render States ===================================== */
1049 const D3DRENDERSTATETYPE render_state_indices[] =
1055 D3DRS_ALPHATESTENABLE,
1064 D3DRS_ALPHABLENDENABLE,
1066 D3DRS_SPECULARENABLE,
1072 D3DRS_RANGEFOGENABLE,
1073 D3DRS_STENCILENABLE,
1080 D3DRS_STENCILWRITEMASK,
1081 D3DRS_TEXTUREFACTOR,
1093 D3DRS_FOGVERTEXMODE,
1096 D3DRS_NORMALIZENORMALS,
1097 D3DRS_DIFFUSEMATERIALSOURCE,
1098 D3DRS_SPECULARMATERIALSOURCE,
1099 D3DRS_AMBIENTMATERIALSOURCE,
1100 D3DRS_EMISSIVEMATERIALSOURCE,
1102 D3DRS_CLIPPLANEENABLE,
1103 #if 0 /* Driver dependent, increase array size to enable */
1106 D3DRS_POINTSIZE_MIN,
1107 D3DRS_POINTSPRITEENABLE,
1108 D3DRS_POINTSCALEENABLE,
1112 D3DRS_MULTISAMPLEANTIALIAS,
1113 D3DRS_MULTISAMPLEMASK,
1114 D3DRS_PATCHEDGESTYLE,
1115 D3DRS_DEBUGMONITORTOKEN,
1116 D3DRS_POINTSIZE_MAX,
1117 D3DRS_INDEXEDVERTEXBLENDENABLE,
1118 D3DRS_COLORWRITEENABLE,
1121 D3DRS_POSITIONDEGREE,
1123 D3DRS_SCISSORTESTENABLE,
1124 D3DRS_SLOPESCALEDEPTHBIAS,
1125 D3DRS_ANTIALIASEDLINEENABLE,
1126 D3DRS_MINTESSELLATIONLEVEL,
1127 D3DRS_MAXTESSELLATIONLEVEL,
1128 D3DRS_ADAPTIVETESS_X,
1129 D3DRS_ADAPTIVETESS_Y,
1130 D3DRS_ADAPTIVETESS_Z,
1131 D3DRS_ADAPTIVETESS_W,
1132 D3DRS_ENABLEADAPTIVETESSELLATION,
1133 D3DRS_TWOSIDEDSTENCILMODE,
1134 D3DRS_CCW_STENCILFAIL,
1135 D3DRS_CCW_STENCILZFAIL,
1136 D3DRS_CCW_STENCILPASS,
1137 D3DRS_CCW_STENCILFUNC,
1138 D3DRS_COLORWRITEENABLE1,
1139 D3DRS_COLORWRITEENABLE2,
1140 D3DRS_COLORWRITEENABLE3,
1142 D3DRS_SRGBWRITEENABLE,
1152 D3DRS_SEPARATEALPHABLENDENABLE,
1153 D3DRS_SRCBLENDALPHA,
1154 D3DRS_DESTBLENDALPHA,
1158 struct render_state_data
1160 DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1163 struct render_state_arg
1165 D3DPRESENT_PARAMETERS *device_pparams;
1166 float pointsize_max;
1169 struct render_state_context
1171 struct render_state_data default_data_buffer;
1172 struct render_state_data test_data_buffer;
1173 struct render_state_data poison_data_buffer;
1176 static void render_state_set_handler(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1178 const struct render_state_data *rsdata = data;
1182 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1184 hret = IDirect3DDevice9_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1185 ok(hret == D3D_OK, "SetRenderState returned %#x.\n", hret);
1189 static void render_state_check_data(IDirect3DDevice9 *device, unsigned int chain_stage,
1190 const struct state_test *test, const void *expected_data)
1192 const struct render_state_context *ctx = test->test_context;
1193 const struct render_state_data *rsdata = expected_data;
1197 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1199 DWORD value = ctx->poison_data_buffer.states[i];
1200 hr = IDirect3DDevice9_GetRenderState(device, render_state_indices[i], &value);
1201 ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1202 ok(value == rsdata->states[i], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1203 chain_stage, render_state_indices[i], rsdata->states[i], value);
1207 static inline DWORD to_dword(float fl) {
1208 return *((DWORD*) &fl);
1211 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1213 DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1214 unsigned int idx = 0;
1216 data->states[idx++] = zenable; /* ZENABLE */
1217 data->states[idx++] = D3DFILL_SOLID; /* FILLMODE */
1218 data->states[idx++] = D3DSHADE_GOURAUD; /* SHADEMODE */
1219 data->states[idx++] = TRUE; /* ZWRITEENABLE */
1220 data->states[idx++] = FALSE; /* ALPHATESTENABLE */
1221 data->states[idx++] = TRUE; /* LASTPIXEL */
1222 data->states[idx++] = D3DBLEND_ONE; /* SRCBLEND */
1223 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLEND */
1224 data->states[idx++] = D3DCULL_CCW; /* CULLMODE */
1225 data->states[idx++] = D3DCMP_LESSEQUAL; /* ZFUNC */
1226 data->states[idx++] = 0; /* ALPHAREF */
1227 data->states[idx++] = D3DCMP_ALWAYS; /* ALPHAFUNC */
1228 data->states[idx++] = FALSE; /* DITHERENABLE */
1229 data->states[idx++] = FALSE; /* ALPHABLENDENABLE */
1230 data->states[idx++] = FALSE; /* FOGENABLE */
1231 data->states[idx++] = FALSE; /* SPECULARENABLE */
1232 data->states[idx++] = 0; /* FOGCOLOR */
1233 data->states[idx++] = D3DFOG_NONE; /* FOGTABLEMODE */
1234 data->states[idx++] = to_dword(0.0f); /* FOGSTART */
1235 data->states[idx++] = to_dword(1.0f); /* FOGEND */
1236 data->states[idx++] = to_dword(1.0f); /* FOGDENSITY */
1237 data->states[idx++] = FALSE; /* RANGEFOGENABLE */
1238 data->states[idx++] = FALSE; /* STENCILENABLE */
1239 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILFAIL */
1240 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILZFAIL */
1241 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILPASS */
1242 data->states[idx++] = D3DCMP_ALWAYS; /* STENCILFUNC */
1243 data->states[idx++] = 0; /* STENCILREF */
1244 data->states[idx++] = 0xFFFFFFFF; /* STENCILMASK */
1245 data->states[idx++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1246 data->states[idx++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1247 data->states[idx++] = 0; /* WRAP 0 */
1248 data->states[idx++] = 0; /* WRAP 1 */
1249 data->states[idx++] = 0; /* WRAP 2 */
1250 data->states[idx++] = 0; /* WRAP 3 */
1251 data->states[idx++] = 0; /* WRAP 4 */
1252 data->states[idx++] = 0; /* WRAP 5 */
1253 data->states[idx++] = 0; /* WRAP 6 */
1254 data->states[idx++] = 0; /* WRAP 7 */
1255 data->states[idx++] = TRUE; /* CLIPPING */
1256 data->states[idx++] = TRUE; /* LIGHTING */
1257 data->states[idx++] = 0; /* AMBIENT */
1258 data->states[idx++] = D3DFOG_NONE; /* FOGVERTEXMODE */
1259 data->states[idx++] = TRUE; /* COLORVERTEX */
1260 data->states[idx++] = TRUE; /* LOCALVIEWER */
1261 data->states[idx++] = FALSE; /* NORMALIZENORMALS */
1262 data->states[idx++] = D3DMCS_COLOR1; /* DIFFUSEMATERIALSOURCE */
1263 data->states[idx++] = D3DMCS_COLOR2; /* SPECULARMATERIALSOURCE */
1264 data->states[idx++] = D3DMCS_MATERIAL; /* AMBIENTMATERIALSOURCE */
1265 data->states[idx++] = D3DMCS_MATERIAL; /* EMISSIVEMATERIALSOURCE */
1266 data->states[idx++] = D3DVBF_DISABLE; /* VERTEXBLEND */
1267 data->states[idx++] = 0; /* CLIPPLANEENABLE */
1268 #if 0 /* Driver dependent, increase array size to enable */
1269 data->states[idx++] = to_dword(1.0f); /* POINTSIZE */
1271 data->states[idx++] = to_dword(1.0f); /* POINTSIZEMIN */
1272 data->states[idx++] = FALSE; /* POINTSPRITEENABLE */
1273 data->states[idx++] = FALSE; /* POINTSCALEENABLE */
1274 data->states[idx++] = to_dword(1.0f); /* POINTSCALE_A */
1275 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_B */
1276 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_C */
1277 data->states[idx++] = TRUE; /* MULTISAMPLEANTIALIAS */
1278 data->states[idx++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1279 data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1280 data->states[idx++] = 0xbaadcafe; /* DEBUGMONITORTOKEN */
1281 data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1282 data->states[idx++] = FALSE; /* INDEXEDVERTEXBLENDENABLE */
1283 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE */
1284 data->states[idx++] = to_dword(0.0f); /* TWEENFACTOR */
1285 data->states[idx++] = D3DBLENDOP_ADD; /* BLENDOP */
1286 data->states[idx++] = D3DDEGREE_CUBIC; /* POSITIONDEGREE */
1287 data->states[idx++] = D3DDEGREE_LINEAR; /* NORMALDEGREE */
1288 data->states[idx++] = FALSE; /* SCISSORTESTENABLE */
1289 data->states[idx++] = to_dword(0.0f); /* SLOPESCALEDEPTHBIAS */
1290 data->states[idx++] = FALSE; /* ANTIALIASEDLINEENABLE */
1291 data->states[idx++] = to_dword(1.0f); /* MINTESSELATIONLEVEL */
1292 data->states[idx++] = to_dword(1.0f); /* MAXTESSELATIONLEVEL */
1293 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_X */
1294 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_Y */
1295 data->states[idx++] = to_dword(1.0f); /* ADAPTIVETESS_Z */
1296 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_W */
1297 data->states[idx++] = FALSE; /* ENABLEADAPTIVETESSELATION */
1298 data->states[idx++] = FALSE; /* TWOSIDEDSTENCILMODE */
1299 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILFAIL */
1300 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILZFAIL */
1301 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILPASS */
1302 data->states[idx++] = D3DCMP_ALWAYS; /* CCW_STENCILFUNC */
1303 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE1 */
1304 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE2 */
1305 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE3 */
1306 data->states[idx++] = 0xFFFFFFFF; /* BLENDFACTOR */
1307 data->states[idx++] = 0; /* SRGBWRITEENABLE */
1308 data->states[idx++] = to_dword(0.0f); /* DEPTHBIAS */
1309 data->states[idx++] = 0; /* WRAP8 */
1310 data->states[idx++] = 0; /* WRAP9 */
1311 data->states[idx++] = 0; /* WRAP10 */
1312 data->states[idx++] = 0; /* WRAP11 */
1313 data->states[idx++] = 0; /* WRAP12 */
1314 data->states[idx++] = 0; /* WRAP13 */
1315 data->states[idx++] = 0; /* WRAP14 */
1316 data->states[idx++] = 0; /* WRAP15 */
1317 data->states[idx++] = FALSE; /* SEPARATEALPHABLENDENABLE */
1318 data->states[idx++] = D3DBLEND_ONE; /* SRCBLENDALPHA */
1319 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLENDALPHA */
1320 data->states[idx++] = TRUE; /* BLENDOPALPHA */
1323 static void render_state_poison_data_init(struct render_state_data *data)
1327 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1329 data->states[i] = 0x1337c0de;
1333 static void render_state_test_data_init(struct render_state_data *data)
1335 unsigned int idx = 0;
1336 data->states[idx++] = D3DZB_USEW; /* ZENABLE */
1337 data->states[idx++] = D3DFILL_WIREFRAME; /* FILLMODE */
1338 data->states[idx++] = D3DSHADE_PHONG; /* SHADEMODE */
1339 data->states[idx++] = FALSE; /* ZWRITEENABLE */
1340 data->states[idx++] = TRUE; /* ALPHATESTENABLE */
1341 data->states[idx++] = FALSE; /* LASTPIXEL */
1342 data->states[idx++] = D3DBLEND_SRCALPHASAT; /* SRCBLEND */
1343 data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1344 data->states[idx++] = D3DCULL_CW; /* CULLMODE */
1345 data->states[idx++] = D3DCMP_NOTEQUAL; /* ZFUNC */
1346 data->states[idx++] = 10; /* ALPHAREF */
1347 data->states[idx++] = D3DCMP_GREATER; /* ALPHAFUNC */
1348 data->states[idx++] = TRUE; /* DITHERENABLE */
1349 data->states[idx++] = TRUE; /* ALPHABLENDENABLE */
1350 data->states[idx++] = TRUE; /* FOGENABLE */
1351 data->states[idx++] = TRUE; /* SPECULARENABLE */
1352 data->states[idx++] = 255 << 31; /* FOGCOLOR */
1353 data->states[idx++] = D3DFOG_EXP; /* FOGTABLEMODE */
1354 data->states[idx++] = to_dword(0.1f); /* FOGSTART */
1355 data->states[idx++] = to_dword(0.8f); /* FOGEND */
1356 data->states[idx++] = to_dword(0.5f); /* FOGDENSITY */
1357 data->states[idx++] = TRUE; /* RANGEFOGENABLE */
1358 data->states[idx++] = TRUE; /* STENCILENABLE */
1359 data->states[idx++] = D3DSTENCILOP_INCRSAT; /* STENCILFAIL */
1360 data->states[idx++] = D3DSTENCILOP_REPLACE; /* STENCILZFAIL */
1361 data->states[idx++] = D3DSTENCILOP_INVERT; /* STENCILPASS */
1362 data->states[idx++] = D3DCMP_LESS; /* STENCILFUNC */
1363 data->states[idx++] = 10; /* STENCILREF */
1364 data->states[idx++] = 0xFF00FF00; /* STENCILMASK */
1365 data->states[idx++] = 0x00FF00FF; /* STENCILWRITEMASK */
1366 data->states[idx++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1367 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 0 */
1368 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 1 */
1369 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 2 */
1370 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 4 */
1371 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 5 */
1372 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 6 */
1373 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 7 */
1374 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1375 data->states[idx++] = FALSE; /* CLIPPING */
1376 data->states[idx++] = FALSE; /* LIGHTING */
1377 data->states[idx++] = 255 << 16; /* AMBIENT */
1378 data->states[idx++] = D3DFOG_EXP2; /* FOGVERTEXMODE */
1379 data->states[idx++] = FALSE; /* COLORVERTEX */
1380 data->states[idx++] = FALSE; /* LOCALVIEWER */
1381 data->states[idx++] = TRUE; /* NORMALIZENORMALS */
1382 data->states[idx++] = D3DMCS_COLOR2; /* DIFFUSEMATERIALSOURCE */
1383 data->states[idx++] = D3DMCS_MATERIAL; /* SPECULARMATERIALSOURCE */
1384 data->states[idx++] = D3DMCS_COLOR1; /* AMBIENTMATERIALSOURCE */
1385 data->states[idx++] = D3DMCS_COLOR2; /* EMISSIVEMATERIALSOURCE */
1386 data->states[idx++] = D3DVBF_3WEIGHTS; /* VERTEXBLEND */
1387 data->states[idx++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1388 #if 0 /* Driver dependent, increase array size to enable */
1389 data->states[idx++] = to_dword(32.0f); /* POINTSIZE */
1391 data->states[idx++] = to_dword(0.7f); /* POINTSIZEMIN */
1392 data->states[idx++] = TRUE; /* POINTSPRITEENABLE */
1393 data->states[idx++] = TRUE; /* POINTSCALEENABLE */
1394 data->states[idx++] = to_dword(0.7f); /* POINTSCALE_A */
1395 data->states[idx++] = to_dword(0.5f); /* POINTSCALE_B */
1396 data->states[idx++] = to_dword(0.4f); /* POINTSCALE_C */
1397 data->states[idx++] = FALSE; /* MULTISAMPLEANTIALIAS */
1398 data->states[idx++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1399 data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1400 data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN */
1401 data->states[idx++] = to_dword(77.0f); /* POINTSIZE_MAX */
1402 data->states[idx++] = TRUE; /* INDEXEDVERTEXBLENDENABLE */
1403 data->states[idx++] = 0x00000009; /* COLORWRITEENABLE */
1404 data->states[idx++] = to_dword(0.2f); /* TWEENFACTOR */
1405 data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1406 data->states[idx++] = D3DDEGREE_LINEAR; /* POSITIONDEGREE */
1407 data->states[idx++] = D3DDEGREE_CUBIC; /* NORMALDEGREE */
1408 data->states[idx++] = TRUE; /* SCISSORTESTENABLE */
1409 data->states[idx++] = to_dword(0.33f); /* SLOPESCALEDEPTHBIAS */
1410 data->states[idx++] = TRUE; /* ANTIALIASEDLINEENABLE */
1411 data->states[idx++] = to_dword(0.8f); /* MINTESSELATIONLEVEL */
1412 data->states[idx++] = to_dword(0.8f); /* MAXTESSELATIONLEVEL */
1413 data->states[idx++] = to_dword(0.2f); /* ADAPTIVETESS_X */
1414 data->states[idx++] = to_dword(0.3f); /* ADAPTIVETESS_Y */
1415 data->states[idx++] = to_dword(0.6f); /* ADAPTIVETESS_Z */
1416 data->states[idx++] = to_dword(0.4f); /* ADAPTIVETESS_W */
1417 data->states[idx++] = TRUE; /* ENABLEADAPTIVETESSELATION */
1418 data->states[idx++] = TRUE; /* TWOSIDEDSTENCILMODE */
1419 data->states[idx++] = D3DSTENCILOP_ZERO; /* CCW_STENCILFAIL */
1420 data->states[idx++] = D3DSTENCILOP_DECR; /* CCW_STENCILZFAIL */
1421 data->states[idx++] = D3DSTENCILOP_INCR; /* CCW_STENCILPASS */
1422 data->states[idx++] = D3DCMP_ALWAYS; /* CCW_STENCILFUNC */
1423 data->states[idx++] = 0x00000007; /* COLORWRITEENABLE1 */
1424 data->states[idx++] = 0x00000008; /* COLORWRITEENABLE2 */
1425 data->states[idx++] = 0x00000004; /* COLORWRITEENABLE3 */
1426 data->states[idx++] = 0xF0F1F2F3; /* BLENDFACTOR */
1427 data->states[idx++] = 1; /* SRGBWRITEENABLE */
1428 data->states[idx++] = to_dword(0.3f); /* DEPTHBIAS */
1429 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 8 */
1430 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 9 */
1431 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 10 */
1432 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 11 */
1433 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 12 */
1434 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 13 */
1435 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 14 */
1436 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 15 */
1437 data->states[idx++] = TRUE; /* SEPARATEALPHABLENDENABLE */
1438 data->states[idx++] = D3DBLEND_ZERO; /* SRCBLENDALPHA */
1439 data->states[idx++] = D3DBLEND_ONE; /* DESTBLENDALPHA */
1440 data->states[idx++] = FALSE; /* BLENDOPALPHA */
1443 static HRESULT render_state_setup_handler(struct state_test *test)
1445 const struct render_state_arg *rsarg = test->test_arg;
1447 struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1448 if (ctx == NULL) return E_FAIL;
1449 test->test_context = ctx;
1451 test->default_data = &ctx->default_data_buffer;
1452 test->initial_data = &ctx->default_data_buffer;
1453 test->test_data_in = &ctx->test_data_buffer;
1454 test->test_data_out = &ctx->test_data_buffer;
1456 render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1457 render_state_test_data_init(&ctx->test_data_buffer);
1458 render_state_poison_data_init(&ctx->poison_data_buffer);
1463 static void render_state_teardown_handler(struct state_test *test)
1465 HeapFree(GetProcessHeap(), 0, test->test_context);
1468 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1470 test->setup_handler = render_state_setup_handler;
1471 test->teardown_handler = render_state_teardown_handler;
1472 test->set_handler = render_state_set_handler;
1473 test->check_data = render_state_check_data;
1474 test->test_name = "set_get_render_states";
1475 test->test_arg = test_arg;
1478 /* =================== Main state tests function =============================== */
1480 static void test_state_management(IDirect3DDevice9 *device, D3DPRESENT_PARAMETERS *device_pparams)
1482 struct shader_constant_arg pshader_constant_arg;
1483 struct shader_constant_arg vshader_constant_arg;
1484 struct render_state_arg render_state_arg;
1485 struct light_arg light_arg;
1489 /* Test count: 2 for shader constants
1494 struct state_test tests[5];
1495 unsigned int tcount = 0;
1497 hret = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1498 ok(hret == D3D_OK, "GetDeviceCaps returned %#x.\n", hret);
1499 if (hret != D3D_OK) return;
1501 texture_stages = caps.MaxTextureBlendStages;
1503 /* Zero test memory */
1504 memset(tests, 0, sizeof(tests));
1506 if (caps.VertexShaderVersion & 0xffff) {
1507 vshader_constant_arg.idx = 0;
1508 vshader_constant_arg.pshader = FALSE;
1509 shader_constants_queue_test(&tests[tcount], &vshader_constant_arg);
1513 if (caps.PixelShaderVersion & 0xffff) {
1514 pshader_constant_arg.idx = 0;
1515 pshader_constant_arg.pshader = TRUE;
1516 shader_constants_queue_test(&tests[tcount], &pshader_constant_arg);
1521 lights_queue_test(&tests[tcount], &light_arg);
1524 transform_queue_test(&tests[tcount]);
1527 render_state_arg.device_pparams = device_pparams;
1528 render_state_arg.pointsize_max = caps.MaxPointSize;
1529 render_states_queue_test(&tests[tcount], &render_state_arg);
1532 execute_test_chain_all(device, tests, tcount);
1535 static void test_shader_constant_apply(IDirect3DDevice9 *device)
1537 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
1538 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
1539 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
1540 IDirect3DStateBlock9 *stateblock;
1544 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
1545 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1546 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
1547 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1548 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
1549 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1550 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
1551 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1553 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
1554 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1555 ok(!memcmp(ret, initial, sizeof(initial)),
1556 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1557 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1558 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
1559 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1560 ok(!memcmp(ret, initial, sizeof(initial)),
1561 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1562 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1563 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
1564 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1565 ok(!memcmp(ret, initial, sizeof(initial)),
1566 "GetpixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1567 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1568 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
1569 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1570 ok(!memcmp(ret, initial, sizeof(initial)),
1571 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1572 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1574 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
1575 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1576 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
1577 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1579 hr = IDirect3DDevice9_BeginStateBlock(device);
1580 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x\n", hr);
1582 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
1583 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
1584 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
1585 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
1587 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
1588 ok(SUCCEEDED(hr), "EndStateBlock returned %#x\n", hr);
1590 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
1591 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1592 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1593 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1594 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1595 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
1596 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1597 ok(!memcmp(ret, initial, sizeof(initial)),
1598 "GetVertexShaderConstantF 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, 0, ret, 1);
1601 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1602 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1603 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1604 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1605 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
1606 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1607 ok(!memcmp(ret, initial, sizeof(initial)),
1608 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1609 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1611 hr = IDirect3DStateBlock9_Apply(stateblock);
1612 ok(SUCCEEDED(hr), "Apply returned %#x\n", hr);
1614 /* Apply doesn't overwrite constants that aren't explicitly set on the source stateblock. */
1615 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
1616 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1617 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1618 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1619 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1620 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
1621 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
1622 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1623 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1624 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1625 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
1626 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1627 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1628 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1629 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1630 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
1631 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
1632 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1633 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1634 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1636 IDirect3DStateBlock9_Release(stateblock);
1639 START_TEST(stateblock)
1641 IDirect3DDevice9 *device_ptr = NULL;
1642 D3DPRESENT_PARAMETERS device_pparams;
1646 d3d9_handle = LoadLibraryA("d3d9.dll");
1649 skip("Could not load d3d9.dll\n");
1653 hret = init_d3d9(&device_ptr, &device_pparams);
1654 if (hret != D3D_OK) return;
1656 test_begin_end_state_block(device_ptr);
1657 test_state_management(device_ptr, &device_pparams);
1658 test_shader_constant_apply(device_ptr);
1660 refcount = IDirect3DDevice9_Release(device_ptr);
1661 ok(!refcount, "Device has %u references left\n", refcount);