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_all;
125 const void *test_data_out_vertex;
126 const void *test_data_out_pixel;
128 HRESULT (*init)(IDirect3DDevice9 *device, struct state_test *test);
129 void (*cleanup)(IDirect3DDevice9 *device, struct state_test *test);
130 void (*apply_data)(IDirect3DDevice9 *device, const struct state_test *test,
132 void (*check_data)(IDirect3DDevice9 *device, const struct state_test *test,
133 const void *expected_data, unsigned int chain_stage, DWORD quirk);
136 const void* test_arg;
138 /* Test-specific context data */
143 #define EVENT_ERROR -1
145 /* Apparently recorded stateblocks record and apply vertex declarations,
146 * but don't capture them */
147 #define SB_QUIRK_RECORDED_VDECL_CAPTURE 0x00000001
151 IDirect3DStateBlock9 *stateblock;
152 IDirect3DSurface9 *original_render_target;
153 IDirect3DSwapChain9 *new_swap_chain;
169 int (*event_fn)(IDirect3DDevice9 *device, struct event_data *event_data);
170 enum stateblock_data check;
171 enum stateblock_data apply;
175 static const void *get_event_data(const struct state_test *test, enum stateblock_data data)
179 case SB_DATA_DEFAULT:
180 return test->default_data;
182 case SB_DATA_INITIAL:
183 return test->initial_data;
185 case SB_DATA_TEST_IN:
186 return test->test_data_in;
188 case SB_DATA_TEST_ALL:
189 return test->test_data_out_all;
191 case SB_DATA_TEST_VERTEX:
192 return test->test_data_out_vertex;
194 case SB_DATA_TEST_PIXEL:
195 return test->test_data_out_pixel;
202 /* This is an event-machine, which tests things.
203 * It tests get and set operations for a batch of states, based on
204 * results from the event function, which directs what's to be done */
206 static void execute_test_chain(IDirect3DDevice9 *device, struct state_test *test,
207 unsigned int ntests, struct event *event, unsigned int nevents, struct event_data *event_data)
211 /* For each queued event */
212 for (j = 0; j < nevents; ++j)
216 /* Execute the next event handler (if available). */
217 if (event[j].event_fn)
219 if (event[j].event_fn(device, event_data) == EVENT_ERROR)
221 trace("Stage %u in error state, aborting.\n", j);
226 if (event[j].check != SB_DATA_NONE)
228 for (i = 0; i < ntests; ++i)
230 data = get_event_data(&test[i], event[j].check);
231 test[i].check_data(device, &test[i], data, j, event[j].quirk);
235 if (event[j].apply != SB_DATA_NONE)
237 for (i = 0; i < ntests; ++i)
239 data = get_event_data(&test[i], event[j].apply);
240 test[i].apply_data(device, &test[i], data);
245 /* Attempt to reset any changes made. */
246 for (i = 0; i < ntests; ++i)
248 test[i].apply_data(device, &test[i], test[i].default_data);
252 static int switch_render_target(IDirect3DDevice9 *device, struct event_data *event_data)
255 D3DPRESENT_PARAMETERS present_parameters;
256 IDirect3DSwapChain9* swapchain = NULL;
257 IDirect3DSurface9* backbuffer = NULL;
259 /* Parameters for new swapchain */
260 ZeroMemory(&present_parameters, sizeof(present_parameters));
261 present_parameters.Windowed = TRUE;
262 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
264 /* Create new swapchain */
265 hret = IDirect3DDevice9_CreateAdditionalSwapChain(device, &present_parameters, &swapchain);
266 ok (hret == D3D_OK, "CreateAdditionalSwapChain returned %#x.\n", hret);
267 if (hret != D3D_OK) goto error;
269 /* Get its backbuffer */
270 hret = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
271 ok (hret == D3D_OK, "GetBackBuffer returned %#x.\n", hret);
272 if (hret != D3D_OK) goto error;
274 /* Save the current render target */
275 hret = IDirect3DDevice9_GetRenderTarget(device, 0, &event_data->original_render_target);
276 ok (hret == D3D_OK, "GetRenderTarget returned %#x.\n", hret);
277 if (hret != D3D_OK) goto error;
279 /* Set the new swapchain's backbuffer as a render target */
280 hret = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
281 ok (hret == D3D_OK, "SetRenderTarget returned %#x.\n", hret);
282 if (hret != D3D_OK) goto error;
284 IUnknown_Release(backbuffer);
285 event_data->new_swap_chain = swapchain;
289 if (backbuffer) IUnknown_Release(backbuffer);
290 if (swapchain) IUnknown_Release(swapchain);
294 static int revert_render_target(IDirect3DDevice9 *device, struct event_data *event_data)
298 /* Reset the old render target */
299 hret = IDirect3DDevice9_SetRenderTarget(device, 0, event_data->original_render_target);
300 ok (hret == D3D_OK, "SetRenderTarget returned %#x.\n", hret);
301 if (hret != D3D_OK) {
302 IUnknown_Release(event_data->original_render_target);
306 IUnknown_Release(event_data->original_render_target);
307 IUnknown_Release(event_data->new_swap_chain);
312 static int create_stateblock_all(IDirect3DDevice9 *device, struct event_data *event_data)
316 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &event_data->stateblock);
317 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
318 if (FAILED(hr)) return EVENT_ERROR;
322 static int create_stateblock_vertex(IDirect3DDevice9 *device, struct event_data *event_data)
326 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &event_data->stateblock);
327 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
328 if (FAILED(hr)) return EVENT_ERROR;
332 static int create_stateblock_pixel(IDirect3DDevice9 *device, struct event_data *event_data)
336 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_PIXELSTATE, &event_data->stateblock);
337 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
338 if (FAILED(hr)) return EVENT_ERROR;
342 static int begin_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
346 hret = IDirect3DDevice9_BeginStateBlock(device);
347 ok(hret == D3D_OK, "BeginStateBlock returned %#x.\n", hret);
348 if (hret != D3D_OK) return EVENT_ERROR;
352 static int end_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
356 hret = IDirect3DDevice9_EndStateBlock(device, &event_data->stateblock);
357 ok(hret == D3D_OK, "EndStateBlock returned %#x.\n", hret);
358 if (hret != D3D_OK) return EVENT_ERROR;
362 static int release_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
364 IUnknown_Release(event_data->stateblock);
368 static int apply_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
372 hret = IDirect3DStateBlock9_Apply(event_data->stateblock);
373 ok(hret == D3D_OK, "Apply returned %#x.\n", hret);
374 if (hret != D3D_OK) {
375 IUnknown_Release(event_data->stateblock);
379 IUnknown_Release(event_data->stateblock);
384 static int capture_stateblock(IDirect3DDevice9 *device, struct event_data *event_data)
388 hret = IDirect3DStateBlock9_Capture(event_data->stateblock);
389 ok(hret == D3D_OK, "Capture returned %#x.\n", hret);
396 static void execute_test_chain_all(IDirect3DDevice9 *device, struct state_test *test, unsigned int ntests)
398 struct event_data arg;
402 struct event read_events[] =
404 {NULL, SB_DATA_INITIAL, SB_DATA_NONE},
407 struct event write_read_events[] =
409 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
410 {NULL, SB_DATA_TEST_ALL, SB_DATA_NONE},
413 struct event abort_stateblock_events[] =
415 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
416 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
417 {release_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
420 struct event apply_stateblock_events[] =
422 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
423 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
424 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
427 struct event capture_reapply_stateblock_events[] =
429 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
430 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
431 {capture_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
432 {apply_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE, SB_QUIRK_RECORDED_VDECL_CAPTURE},
435 struct event create_stateblock_capture_apply_all_events[] =
437 {create_stateblock_all, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
438 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
439 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
442 struct event create_stateblock_apply_all_events[] =
444 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
445 {create_stateblock_all, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
446 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
449 struct event create_stateblock_capture_apply_vertex_events[] =
451 {create_stateblock_vertex, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
452 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
453 {apply_stateblock, SB_DATA_TEST_VERTEX, SB_DATA_NONE},
456 struct event create_stateblock_apply_vertex_events[] =
458 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
459 {create_stateblock_vertex, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
460 {apply_stateblock, SB_DATA_TEST_VERTEX, SB_DATA_NONE},
463 struct event create_stateblock_capture_apply_pixel_events[] =
465 {create_stateblock_pixel, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
466 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
467 {apply_stateblock, SB_DATA_TEST_PIXEL, SB_DATA_NONE},
470 struct event create_stateblock_apply_pixel_events[] =
472 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
473 {create_stateblock_pixel, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
474 {apply_stateblock, SB_DATA_TEST_PIXEL, SB_DATA_NONE},
477 struct event rendertarget_switch_events[] =
479 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
480 {switch_render_target, SB_DATA_TEST_ALL, SB_DATA_NONE},
481 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
484 struct event rendertarget_stateblock_events[] =
486 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
487 {switch_render_target, SB_DATA_DEFAULT, SB_DATA_NONE},
488 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
489 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
490 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
493 /* Setup each test for execution */
494 for (i = 0; i < ntests; ++i)
496 hr = test[i].init(device, &test[i]);
497 ok(SUCCEEDED(hr), "Test \"%s\" failed setup, aborting\n", test[i].test_name);
498 if (FAILED(hr)) return;
501 trace("Running initial read state tests\n");
502 execute_test_chain(device, test, ntests, read_events, 1, NULL);
504 trace("Running write-read state tests\n");
505 execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
507 trace("Running stateblock abort state tests\n");
508 execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
510 trace("Running stateblock apply state tests\n");
511 execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
513 trace("Running stateblock capture/reapply state tests\n");
514 execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
516 trace("Running create stateblock capture/apply all state tests\n");
517 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_all_events, 3, &arg);
519 trace("Running create stateblock apply state all tests\n");
520 execute_test_chain(device, test, ntests, create_stateblock_apply_all_events, 3, &arg);
522 trace("Running create stateblock capture/apply vertex state tests\n");
523 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_vertex_events, 3, &arg);
525 trace("Running create stateblock apply vertex state tests\n");
526 execute_test_chain(device, test, ntests, create_stateblock_apply_vertex_events, 3, &arg);
528 trace("Running create stateblock capture/apply pixel state tests\n");
529 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_pixel_events, 3, &arg);
531 trace("Running create stateblock apply pixel state tests\n");
532 execute_test_chain(device, test, ntests, create_stateblock_apply_pixel_events, 3, &arg);
534 trace("Running rendertarget switch state tests\n");
535 execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
537 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
538 execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
540 /* Cleanup resources */
541 for (i = 0; i < ntests; ++i)
543 if (test[i].cleanup) test[i].cleanup(device, &test[i]);
547 /* =================== State test: Pixel and Vertex Shader constants ============ */
549 struct shader_constant_data
551 int int_constant[4]; /* 1x4 integer constant */
552 float float_constant[4]; /* 1x4 float constant */
553 BOOL bool_constant[4]; /* 4x1 boolean constants */
556 struct shader_constant_arg
562 static const struct shader_constant_data shader_constant_poison_data =
564 {0x1337c0de, 0x1337c0de, 0x1337c0de, 0x1337c0de},
565 {1.0f, 2.0f, 3.0f, 4.0f},
566 {FALSE, TRUE, FALSE, TRUE},
569 static const struct shader_constant_data shader_constant_default_data =
572 {0.0f, 0.0f, 0.0f, 0.0f},
576 static const struct shader_constant_data shader_constant_test_data =
578 {0xdead0000, 0xdead0001, 0xdead0002, 0xdead0003},
579 {5.0f, 6.0f, 7.0f, 8.0f},
580 {TRUE, FALSE, FALSE, TRUE},
583 static void shader_constant_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
585 const struct shader_constant_arg *scarg = test->test_arg;
586 const struct shader_constant_data *scdata = data;
588 unsigned int index = scarg->idx;
590 if (!scarg->pshader) {
591 hret = IDirect3DDevice9_SetVertexShaderConstantI(device, index, scdata->int_constant, 1);
592 ok(hret == D3D_OK, "SetVertexShaderConstantI returned %#x.\n", hret);
593 hret = IDirect3DDevice9_SetVertexShaderConstantF(device, index, scdata->float_constant, 1);
594 ok(hret == D3D_OK, "SetVertexShaderConstantF returned %#x.\n", hret);
595 hret = IDirect3DDevice9_SetVertexShaderConstantB(device, index, scdata->bool_constant, 4);
596 ok(hret == D3D_OK, "SetVertexShaderConstantB returned %#x.\n", hret);
599 hret = IDirect3DDevice9_SetPixelShaderConstantI(device, index, scdata->int_constant, 1);
600 ok(hret == D3D_OK, "SetPixelShaderConstantI returned %#x.\n", hret);
601 hret = IDirect3DDevice9_SetPixelShaderConstantF(device, index, scdata->float_constant, 1);
602 ok(hret == D3D_OK, "SetPixelShaderConstantF returned %#x.\n", hret);
603 hret = IDirect3DDevice9_SetPixelShaderConstantB(device, index, scdata->bool_constant, 4);
604 ok(hret == D3D_OK, "SetPixelShaderConstantB returned %#x.\n", hret);
608 static void shader_constant_check_data(IDirect3DDevice9 *device, const struct state_test *test,
609 const void *expected_data, unsigned int chain_stage, DWORD quirk)
611 struct shader_constant_data value = shader_constant_poison_data;
612 const struct shader_constant_data *scdata = expected_data;
613 const struct shader_constant_arg *scarg = test->test_arg;
618 hr = IDirect3DDevice9_GetVertexShaderConstantI(device, scarg->idx, value.int_constant, 1);
619 ok(SUCCEEDED(hr), "GetVertexShaderConstantI returned %#x.\n", hr);
620 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, scarg->idx, value.float_constant, 1);
621 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x.\n", hr);
622 hr = IDirect3DDevice9_GetVertexShaderConstantB(device, scarg->idx, value.bool_constant, 4);
623 ok(SUCCEEDED(hr), "GetVertexShaderConstantB returned %#x.\n", hr);
627 hr = IDirect3DDevice9_GetPixelShaderConstantI(device, scarg->idx, value.int_constant, 1);
628 ok(SUCCEEDED(hr), "GetPixelShaderConstantI returned %#x.\n", hr);
629 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, scarg->idx, value.float_constant, 1);
630 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x.\n", hr);
631 hr = IDirect3DDevice9_GetPixelShaderConstantB(device, scarg->idx, value.bool_constant, 4);
632 ok(SUCCEEDED(hr), "GetPixelShaderConstantB returned %#x.\n", hr);
635 ok(!memcmp(scdata->int_constant, value.int_constant, sizeof(scdata->int_constant)),
636 "Chain stage %u, %s integer constant:\n"
637 "\t{%#x, %#x, %#x, %#x} expected\n"
638 "\t{%#x, %#x, %#x, %#x} received\n",
639 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
640 scdata->int_constant[0], scdata->int_constant[1],
641 scdata->int_constant[2], scdata->int_constant[3],
642 value.int_constant[0], value.int_constant[1],
643 value.int_constant[2], value.int_constant[3]);
645 ok(!memcmp(scdata->float_constant, value.float_constant, sizeof(scdata->float_constant)),
646 "Chain stage %u, %s float constant:\n"
647 "\t{%.8e, %.8e, %.8e, %.8e} expected\n"
648 "\t{%.8e, %.8e, %.8e, %.8e} received\n",
649 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
650 scdata->float_constant[0], scdata->float_constant[1],
651 scdata->float_constant[2], scdata->float_constant[3],
652 value.float_constant[0], value.float_constant[1],
653 value.float_constant[2], value.float_constant[3]);
655 ok(!memcmp(scdata->bool_constant, value.bool_constant, sizeof(scdata->bool_constant)),
656 "Chain stage %u, %s boolean constant:\n"
657 "\t{%#x, %#x, %#x, %#x} expected\n"
658 "\t{%#x, %#x, %#x, %#x} received\n",
659 chain_stage, scarg->pshader ? "pixel shader" : "vertex_shader",
660 scdata->bool_constant[0], scdata->bool_constant[1],
661 scdata->bool_constant[2], scdata->bool_constant[3],
662 value.bool_constant[0], value.bool_constant[1],
663 value.bool_constant[2], value.bool_constant[3]);
666 static HRESULT shader_constant_test_init(IDirect3DDevice9 *device, struct state_test *test)
668 const struct shader_constant_arg *test_arg = test->test_arg;
670 test->test_context = NULL;
671 test->test_data_in = &shader_constant_test_data;
672 test->test_data_out_all = &shader_constant_test_data;
673 if (test_arg->pshader)
675 test->test_data_out_vertex = &shader_constant_default_data;
676 test->test_data_out_pixel = &shader_constant_test_data;
680 test->test_data_out_vertex = &shader_constant_test_data;
681 test->test_data_out_pixel = &shader_constant_default_data;
683 test->default_data = &shader_constant_default_data;
684 test->initial_data = &shader_constant_default_data;
689 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
691 test->init = shader_constant_test_init;
692 test->cleanup = NULL;
693 test->apply_data = shader_constant_apply_data;
694 test->check_data = shader_constant_check_data;
695 test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
696 test->test_arg = test_arg;
699 /* =================== State test: Lights ===================================== */
705 HRESULT get_light_result;
706 HRESULT get_enabled_result;
714 static const struct light_data light_poison_data =
718 {7.0f, 4.0f, 2.0f, 1.0f},
719 {7.0f, 4.0f, 2.0f, 1.0f},
720 {7.0f, 4.0f, 2.0f, 1.0f},
723 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
730 static const struct light_data light_default_data =
733 D3DLIGHT_DIRECTIONAL,
734 {1.0f, 1.0f, 1.0f, 0.0f},
735 {0.0f, 0.0f, 0.0f, 0.0f},
736 {0.0f, 0.0f, 0.0f, 0.0f},
739 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
746 /* This is used for the initial read state (before a write causes side effects).
747 * The proper return status is D3DERR_INVALIDCALL. */
748 static const struct light_data light_initial_data =
752 {7.0f, 4.0f, 2.0f, 1.0f},
753 {7.0f, 4.0f, 2.0f, 1.0f},
754 {7.0f, 4.0f, 2.0f, 1.0f},
757 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
764 static const struct light_data light_test_data_in =
768 {2.0f, 2.0f, 2.0f, 2.0f},
769 {3.0f, 3.0f, 3.0f, 3.0f},
770 {4.0f, 4.0f, 4.0f, 4.0f},
773 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
780 /* SetLight will use 128 as the "enabled" value */
781 static const struct light_data light_test_data_out =
785 {2.0f, 2.0f, 2.0f, 2.0f},
786 {3.0f, 3.0f, 3.0f, 3.0f},
787 {4.0f, 4.0f, 4.0f, 4.0f},
790 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
797 static void light_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
799 const struct light_arg *larg = test->test_arg;
800 const struct light_data *ldata = data;
802 unsigned int index = larg->idx;
804 hret = IDirect3DDevice9_SetLight(device, index, &ldata->light);
805 ok(hret == D3D_OK, "SetLight returned %#x.\n", hret);
807 hret = IDirect3DDevice9_LightEnable(device, index, ldata->enabled);
808 ok(hret == D3D_OK, "SetLightEnable returned %#x.\n", hret);
811 static void light_check_data(IDirect3DDevice9 *device, const struct state_test *test,
812 const void *expected_data, unsigned int chain_stage, DWORD quirk)
814 const struct light_arg *larg = test->test_arg;
815 const struct light_data *ldata = expected_data;
816 struct light_data value;
818 value = light_poison_data;
820 value.get_enabled_result = IDirect3DDevice9_GetLightEnable(device, larg->idx, &value.enabled);
821 value.get_light_result = IDirect3DDevice9_GetLight(device, larg->idx, &value.light);
823 ok(value.get_enabled_result == ldata->get_enabled_result,
824 "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
825 chain_stage, ldata->get_enabled_result, value.get_enabled_result);
826 ok(value.get_light_result == ldata->get_light_result,
827 "Chain stage %u: expected get_light_result %#x, got %#x.\n",
828 chain_stage, ldata->get_light_result, value.get_light_result);
830 ok(value.enabled == ldata->enabled,
831 "Chain stage %u: expected enabled %#x, got %#x.\n",
832 chain_stage, ldata->enabled, value.enabled);
833 ok(value.light.Type == ldata->light.Type,
834 "Chain stage %u: expected light.Type %#x, got %#x.\n",
835 chain_stage, ldata->light.Type, value.light.Type);
836 ok(!memcmp(&value.light.Diffuse, &ldata->light.Diffuse, sizeof(value.light.Diffuse)),
837 "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
838 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
839 ldata->light.Diffuse.r, ldata->light.Diffuse.g,
840 ldata->light.Diffuse.b, ldata->light.Diffuse.a,
841 value.light.Diffuse.r, value.light.Diffuse.g,
842 value.light.Diffuse.b, value.light.Diffuse.a);
843 ok(!memcmp(&value.light.Specular, &ldata->light.Specular, sizeof(value.light.Specular)),
844 "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
845 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
846 ldata->light.Specular.r, ldata->light.Specular.g,
847 ldata->light.Specular.b, ldata->light.Specular.a,
848 value.light.Specular.r, value.light.Specular.g,
849 value.light.Specular.b, value.light.Specular.a);
850 ok(!memcmp(&value.light.Ambient, &ldata->light.Ambient, sizeof(value.light.Ambient)),
851 "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
852 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
853 ldata->light.Ambient.r, ldata->light.Ambient.g,
854 ldata->light.Ambient.b, ldata->light.Ambient.a,
855 value.light.Ambient.r, value.light.Ambient.g,
856 value.light.Ambient.b, value.light.Ambient.a);
857 ok(!memcmp(&value.light.Position, &ldata->light.Position, sizeof(value.light.Position)),
858 "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
859 chain_stage, ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z,
860 value.light.Position.x, value.light.Position.y, value.light.Position.z);
861 ok(!memcmp(&value.light.Direction, &ldata->light.Direction, sizeof(value.light.Direction)),
862 "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
863 chain_stage, ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z,
864 value.light.Direction.x, value.light.Direction.y, value.light.Direction.z);
865 ok(value.light.Range == ldata->light.Range,
866 "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
867 chain_stage, ldata->light.Range, value.light.Range);
868 ok(value.light.Falloff == ldata->light.Falloff,
869 "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
870 chain_stage, ldata->light.Falloff, value.light.Falloff);
871 ok(value.light.Attenuation0 == ldata->light.Attenuation0,
872 "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
873 chain_stage, ldata->light.Attenuation0, value.light.Attenuation0);
874 ok(value.light.Attenuation1 == ldata->light.Attenuation1,
875 "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
876 chain_stage, ldata->light.Attenuation1, value.light.Attenuation1);
877 ok(value.light.Attenuation2 == ldata->light.Attenuation2,
878 "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
879 chain_stage, ldata->light.Attenuation2, value.light.Attenuation2);
880 ok(value.light.Theta == ldata->light.Theta,
881 "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
882 chain_stage, ldata->light.Theta, value.light.Theta);
883 ok(value.light.Phi == ldata->light.Phi,
884 "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
885 chain_stage, ldata->light.Phi, value.light.Phi);
888 static HRESULT light_test_init(IDirect3DDevice9 *device, struct state_test *test)
890 test->test_context = NULL;
891 test->test_data_in = &light_test_data_in;
892 test->test_data_out_all = &light_test_data_out;
893 test->test_data_out_vertex = &light_test_data_out;
894 test->test_data_out_pixel = &light_default_data;
895 test->default_data = &light_default_data;
896 test->initial_data = &light_initial_data;
901 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
903 test->init = light_test_init;
904 test->cleanup = NULL;
905 test->apply_data = light_apply_data;
906 test->check_data = light_check_data;
907 test->test_name = "set_get_light";
908 test->test_arg = test_arg;
911 /* =================== State test: Transforms ===================================== */
913 struct transform_data
916 D3DMATRIX projection;
923 static const struct transform_data transform_default_data =
926 1.0f, 0.0f, 0.0f, 0.0f,
927 0.0f, 1.0f, 0.0f, 0.0f,
928 0.0f, 0.0f, 1.0f, 0.0f,
929 0.0f, 0.0f, 0.0f, 1.0f,
932 1.0f, 0.0f, 0.0f, 0.0f,
933 0.0f, 1.0f, 0.0f, 0.0f,
934 0.0f, 0.0f, 1.0f, 0.0f,
935 0.0f, 0.0f, 0.0f, 1.0f,
938 1.0f, 0.0f, 0.0f, 0.0f,
939 0.0f, 1.0f, 0.0f, 0.0f,
940 0.0f, 0.0f, 1.0f, 0.0f,
941 0.0f, 0.0f, 0.0f, 1.0f,
944 1.0f, 0.0f, 0.0f, 0.0f,
945 0.0f, 1.0f, 0.0f, 0.0f,
946 0.0f, 0.0f, 1.0f, 0.0f,
947 0.0f, 0.0f, 0.0f, 1.0f,
950 1.0f, 0.0f, 0.0f, 0.0f,
951 0.0f, 1.0f, 0.0f, 0.0f,
952 0.0f, 0.0f, 1.0f, 0.0f,
953 0.0f, 0.0f, 0.0f, 1.0f,
956 1.0f, 0.0f, 0.0f, 0.0f,
957 0.0f, 1.0f, 0.0f, 0.0f,
958 0.0f, 0.0f, 1.0f, 0.0f,
959 0.0f, 0.0f, 0.0f, 1.0f,
963 static const struct transform_data transform_poison_data =
966 1.0f, 2.0f, 3.0f, 4.0f,
967 5.0f, 6.0f, 7.0f, 8.0f,
968 9.0f, 10.0f, 11.0f, 12.0f,
969 13.0f, 14.0f, 15.0f, 16.0f,
972 17.0f, 18.0f, 19.0f, 20.0f,
973 21.0f, 22.0f, 23.0f, 24.0f,
974 25.0f, 26.0f, 27.0f, 28.0f,
975 29.0f, 30.0f, 31.0f, 32.0f,
978 33.0f, 34.0f, 35.0f, 36.0f,
979 37.0f, 38.0f, 39.0f, 40.0f,
980 41.0f, 42.0f, 43.0f, 44.0f,
981 45.0f, 46.0f, 47.0f, 48.0f
984 49.0f, 50.0f, 51.0f, 52.0f,
985 53.0f, 54.0f, 55.0f, 56.0f,
986 57.0f, 58.0f, 59.0f, 60.0f,
987 61.0f, 62.0f, 63.0f, 64.0f,
990 64.0f, 66.0f, 67.0f, 68.0f,
991 69.0f, 70.0f, 71.0f, 72.0f,
992 73.0f, 74.0f, 75.0f, 76.0f,
993 77.0f, 78.0f, 79.0f, 80.0f,
996 81.0f, 82.0f, 83.0f, 84.0f,
997 85.0f, 86.0f, 87.0f, 88.0f,
998 89.0f, 90.0f, 91.0f, 92.0f,
999 93.0f, 94.0f, 95.0f, 96.0f,
1003 static const struct transform_data transform_test_data =
1006 1.2f, 3.4f, -5.6f, 7.2f,
1007 10.11f, -12.13f, 14.15f, -1.5f,
1008 23.56f, 12.89f, 44.56f, -1.0f,
1009 2.3f, 0.0f, 4.4f, 5.5f,
1012 9.2f, 38.7f, -6.6f, 7.2f,
1013 10.11f, -12.13f, 77.15f, -1.5f,
1014 23.56f, 12.89f, 14.56f, -1.0f,
1015 12.3f, 0.0f, 4.4f, 5.5f,
1018 10.2f, 3.4f, 0.6f, 7.2f,
1019 10.11f, -12.13f, 14.15f, -1.5f,
1020 23.54f, 12.9f, 44.56f, -1.0f,
1021 2.3f, 0.0f, 4.4f, 5.5f,
1024 1.2f, 3.4f, -5.6f, 7.2f,
1025 10.11f, -12.13f, -14.5f, -1.5f,
1026 2.56f, 12.89f, 23.56f, -1.0f,
1027 112.3f, 0.0f, 4.4f, 2.5f,
1030 1.2f, 31.41f, 58.6f, 7.2f,
1031 10.11f, -12.13f, -14.5f, -1.5f,
1032 2.56f, 12.89f, 11.56f, -1.0f,
1033 112.3f, 0.0f, 44.4f, 2.5f,
1036 1.20f, 3.4f, -5.6f, 7.0f,
1037 10.11f, -12.156f, -14.5f, -1.5f,
1038 2.56f, 1.829f, 23.6f, -1.0f,
1039 112.3f, 0.0f, 41.4f, 2.5f,
1043 static void transform_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1045 const struct transform_data *tdata = data;
1048 hret = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &tdata->view);
1049 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1051 hret = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
1052 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1054 hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
1055 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1057 hret = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
1058 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1060 hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &tdata->world0);
1061 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1063 hret = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
1064 ok(hret == D3D_OK, "SetTransform returned %#x.\n", hret);
1067 static void compare_matrix(const char *name, unsigned int chain_stage,
1068 const D3DMATRIX *received, const D3DMATRIX *expected)
1070 ok(!memcmp(expected, received, sizeof(*expected)),
1071 "Chain stage %u, matrix %s:\n"
1073 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1074 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1075 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1076 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1079 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1080 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1081 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1082 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1085 U(*expected).m[0][0], U(*expected).m[1][0], U(*expected).m[2][0], U(*expected).m[3][0],
1086 U(*expected).m[0][1], U(*expected).m[1][1], U(*expected).m[2][1], U(*expected).m[3][1],
1087 U(*expected).m[0][2], U(*expected).m[1][2], U(*expected).m[2][2], U(*expected).m[3][2],
1088 U(*expected).m[0][3], U(*expected).m[1][3], U(*expected).m[2][3], U(*expected).m[3][3],
1089 U(*received).m[0][0], U(*received).m[1][0], U(*received).m[2][0], U(*received).m[3][0],
1090 U(*received).m[0][1], U(*received).m[1][1], U(*received).m[2][1], U(*received).m[3][1],
1091 U(*received).m[0][2], U(*received).m[1][2], U(*received).m[2][2], U(*received).m[3][2],
1092 U(*received).m[0][3], U(*received).m[1][3], U(*received).m[2][3], U(*received).m[3][3]);
1095 static void transform_check_data(IDirect3DDevice9 *device, const struct state_test *test,
1096 const void *expected_data, unsigned int chain_stage, DWORD quirk)
1098 const struct transform_data *tdata = expected_data;
1102 value = transform_poison_data.view;
1103 hr = IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &value);
1104 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1105 compare_matrix("View", chain_stage, &value, &tdata->view);
1107 value = transform_poison_data.projection;
1108 hr = IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &value);
1109 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1110 compare_matrix("Projection", chain_stage, &value, &tdata->projection);
1112 value = transform_poison_data.texture0;
1113 hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0, &value);
1114 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1115 compare_matrix("Texture0", chain_stage, &value, &tdata->texture0);
1117 value = transform_poison_data.texture7;
1118 hr = IDirect3DDevice9_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &value);
1119 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1120 compare_matrix("Texture7", chain_stage, &value, &tdata->texture7);
1122 value = transform_poison_data.world0;
1123 hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &value);
1124 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1125 compare_matrix("World0", chain_stage, &value, &tdata->world0);
1127 value = transform_poison_data.world255;
1128 hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(255), &value);
1129 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1130 compare_matrix("World255", chain_stage, &value, &tdata->world255);
1133 static HRESULT transform_test_init(IDirect3DDevice9 *device, struct state_test *test)
1135 test->test_context = NULL;
1136 test->test_data_in = &transform_test_data;
1137 test->test_data_out_all = &transform_test_data;
1138 test->test_data_out_vertex = &transform_default_data;
1139 test->test_data_out_pixel = &transform_default_data;
1140 test->default_data = &transform_default_data;
1141 test->initial_data = &transform_default_data;
1146 static void transform_queue_test(struct state_test *test)
1148 test->init = transform_test_init;
1149 test->cleanup = NULL;
1150 test->apply_data = transform_apply_data;
1151 test->check_data = transform_check_data;
1152 test->test_name = "set_get_transforms";
1153 test->test_arg = NULL;
1156 /* =================== State test: Render States ===================================== */
1158 const D3DRENDERSTATETYPE render_state_indices[] =
1164 D3DRS_ALPHATESTENABLE,
1173 D3DRS_ALPHABLENDENABLE,
1175 D3DRS_SPECULARENABLE,
1181 D3DRS_RANGEFOGENABLE,
1182 D3DRS_STENCILENABLE,
1189 D3DRS_STENCILWRITEMASK,
1190 D3DRS_TEXTUREFACTOR,
1202 D3DRS_FOGVERTEXMODE,
1205 D3DRS_NORMALIZENORMALS,
1206 D3DRS_DIFFUSEMATERIALSOURCE,
1207 D3DRS_SPECULARMATERIALSOURCE,
1208 D3DRS_AMBIENTMATERIALSOURCE,
1209 D3DRS_EMISSIVEMATERIALSOURCE,
1211 D3DRS_CLIPPLANEENABLE,
1212 #if 0 /* Driver dependent */
1215 D3DRS_POINTSIZE_MIN,
1216 D3DRS_POINTSPRITEENABLE,
1217 D3DRS_POINTSCALEENABLE,
1221 D3DRS_MULTISAMPLEANTIALIAS,
1222 D3DRS_MULTISAMPLEMASK,
1223 D3DRS_PATCHEDGESTYLE,
1224 #if 0 /* Apparently not recorded in the stateblock */
1225 D3DRS_DEBUGMONITORTOKEN,
1227 D3DRS_POINTSIZE_MAX,
1228 D3DRS_INDEXEDVERTEXBLENDENABLE,
1229 D3DRS_COLORWRITEENABLE,
1232 D3DRS_POSITIONDEGREE,
1234 D3DRS_SCISSORTESTENABLE,
1235 D3DRS_SLOPESCALEDEPTHBIAS,
1236 D3DRS_ANTIALIASEDLINEENABLE,
1237 D3DRS_MINTESSELLATIONLEVEL,
1238 D3DRS_MAXTESSELLATIONLEVEL,
1239 D3DRS_ADAPTIVETESS_X,
1240 D3DRS_ADAPTIVETESS_Y,
1241 D3DRS_ADAPTIVETESS_Z,
1242 D3DRS_ADAPTIVETESS_W,
1243 D3DRS_ENABLEADAPTIVETESSELLATION,
1244 D3DRS_TWOSIDEDSTENCILMODE,
1245 D3DRS_CCW_STENCILFAIL,
1246 D3DRS_CCW_STENCILZFAIL,
1247 D3DRS_CCW_STENCILPASS,
1248 D3DRS_CCW_STENCILFUNC,
1249 D3DRS_COLORWRITEENABLE1,
1250 D3DRS_COLORWRITEENABLE2,
1251 D3DRS_COLORWRITEENABLE3,
1253 D3DRS_SRGBWRITEENABLE,
1263 D3DRS_SEPARATEALPHABLENDENABLE,
1264 D3DRS_SRCBLENDALPHA,
1265 D3DRS_DESTBLENDALPHA,
1269 struct render_state_data
1271 DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1274 struct render_state_arg
1276 D3DPRESENT_PARAMETERS *device_pparams;
1277 float pointsize_max;
1280 struct render_state_context
1282 struct render_state_data default_data_buffer;
1283 struct render_state_data test_data_all_buffer;
1284 struct render_state_data test_data_vertex_buffer;
1285 struct render_state_data test_data_pixel_buffer;
1286 struct render_state_data poison_data_buffer;
1289 static void render_state_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1291 const struct render_state_data *rsdata = data;
1295 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1297 hret = IDirect3DDevice9_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1298 ok(hret == D3D_OK, "SetRenderState returned %#x.\n", hret);
1302 static void render_state_check_data(IDirect3DDevice9 *device, const struct state_test *test,
1303 const void *expected_data, unsigned int chain_stage, DWORD quirk)
1305 const struct render_state_context *ctx = test->test_context;
1306 const struct render_state_data *rsdata = expected_data;
1310 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1312 DWORD value = ctx->poison_data_buffer.states[i];
1313 hr = IDirect3DDevice9_GetRenderState(device, render_state_indices[i], &value);
1314 ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1315 ok(value == rsdata->states[i], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1316 chain_stage, render_state_indices[i], rsdata->states[i], value);
1320 static inline DWORD to_dword(float fl) {
1321 return *((DWORD*) &fl);
1324 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1326 DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1327 unsigned int idx = 0;
1329 data->states[idx++] = zenable; /* ZENABLE */
1330 data->states[idx++] = D3DFILL_SOLID; /* FILLMODE */
1331 data->states[idx++] = D3DSHADE_GOURAUD; /* SHADEMODE */
1332 data->states[idx++] = TRUE; /* ZWRITEENABLE */
1333 data->states[idx++] = FALSE; /* ALPHATESTENABLE */
1334 data->states[idx++] = TRUE; /* LASTPIXEL */
1335 data->states[idx++] = D3DBLEND_ONE; /* SRCBLEND */
1336 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLEND */
1337 data->states[idx++] = D3DCULL_CCW; /* CULLMODE */
1338 data->states[idx++] = D3DCMP_LESSEQUAL; /* ZFUNC */
1339 data->states[idx++] = 0; /* ALPHAREF */
1340 data->states[idx++] = D3DCMP_ALWAYS; /* ALPHAFUNC */
1341 data->states[idx++] = FALSE; /* DITHERENABLE */
1342 data->states[idx++] = FALSE; /* ALPHABLENDENABLE */
1343 data->states[idx++] = FALSE; /* FOGENABLE */
1344 data->states[idx++] = FALSE; /* SPECULARENABLE */
1345 data->states[idx++] = 0; /* FOGCOLOR */
1346 data->states[idx++] = D3DFOG_NONE; /* FOGTABLEMODE */
1347 data->states[idx++] = to_dword(0.0f); /* FOGSTART */
1348 data->states[idx++] = to_dword(1.0f); /* FOGEND */
1349 data->states[idx++] = to_dword(1.0f); /* FOGDENSITY */
1350 data->states[idx++] = FALSE; /* RANGEFOGENABLE */
1351 data->states[idx++] = FALSE; /* STENCILENABLE */
1352 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILFAIL */
1353 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILZFAIL */
1354 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILPASS */
1355 data->states[idx++] = D3DCMP_ALWAYS; /* STENCILFUNC */
1356 data->states[idx++] = 0; /* STENCILREF */
1357 data->states[idx++] = 0xFFFFFFFF; /* STENCILMASK */
1358 data->states[idx++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1359 data->states[idx++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1360 data->states[idx++] = 0; /* WRAP 0 */
1361 data->states[idx++] = 0; /* WRAP 1 */
1362 data->states[idx++] = 0; /* WRAP 2 */
1363 data->states[idx++] = 0; /* WRAP 3 */
1364 data->states[idx++] = 0; /* WRAP 4 */
1365 data->states[idx++] = 0; /* WRAP 5 */
1366 data->states[idx++] = 0; /* WRAP 6 */
1367 data->states[idx++] = 0; /* WRAP 7 */
1368 data->states[idx++] = TRUE; /* CLIPPING */
1369 data->states[idx++] = TRUE; /* LIGHTING */
1370 data->states[idx++] = 0; /* AMBIENT */
1371 data->states[idx++] = D3DFOG_NONE; /* FOGVERTEXMODE */
1372 data->states[idx++] = TRUE; /* COLORVERTEX */
1373 data->states[idx++] = TRUE; /* LOCALVIEWER */
1374 data->states[idx++] = FALSE; /* NORMALIZENORMALS */
1375 data->states[idx++] = D3DMCS_COLOR1; /* DIFFUSEMATERIALSOURCE */
1376 data->states[idx++] = D3DMCS_COLOR2; /* SPECULARMATERIALSOURCE */
1377 data->states[idx++] = D3DMCS_MATERIAL; /* AMBIENTMATERIALSOURCE */
1378 data->states[idx++] = D3DMCS_MATERIAL; /* EMISSIVEMATERIALSOURCE */
1379 data->states[idx++] = D3DVBF_DISABLE; /* VERTEXBLEND */
1380 data->states[idx++] = 0; /* CLIPPLANEENABLE */
1381 #if 0 /* Driver dependent, increase array size to enable */
1382 data->states[idx++] = to_dword(1.0f); /* POINTSIZE */
1384 data->states[idx++] = to_dword(1.0f); /* POINTSIZEMIN */
1385 data->states[idx++] = FALSE; /* POINTSPRITEENABLE */
1386 data->states[idx++] = FALSE; /* POINTSCALEENABLE */
1387 data->states[idx++] = to_dword(1.0f); /* POINTSCALE_A */
1388 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_B */
1389 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_C */
1390 data->states[idx++] = TRUE; /* MULTISAMPLEANTIALIAS */
1391 data->states[idx++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1392 data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1393 if (0) data->states[idx++] = 0xbaadcafe; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1394 data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1395 data->states[idx++] = FALSE; /* INDEXEDVERTEXBLENDENABLE */
1396 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE */
1397 data->states[idx++] = to_dword(0.0f); /* TWEENFACTOR */
1398 data->states[idx++] = D3DBLENDOP_ADD; /* BLENDOP */
1399 data->states[idx++] = D3DDEGREE_CUBIC; /* POSITIONDEGREE */
1400 data->states[idx++] = D3DDEGREE_LINEAR; /* NORMALDEGREE */
1401 data->states[idx++] = FALSE; /* SCISSORTESTENABLE */
1402 data->states[idx++] = to_dword(0.0f); /* SLOPESCALEDEPTHBIAS */
1403 data->states[idx++] = FALSE; /* ANTIALIASEDLINEENABLE */
1404 data->states[idx++] = to_dword(1.0f); /* MINTESSELATIONLEVEL */
1405 data->states[idx++] = to_dword(1.0f); /* MAXTESSELATIONLEVEL */
1406 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_X */
1407 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_Y */
1408 data->states[idx++] = to_dword(1.0f); /* ADAPTIVETESS_Z */
1409 data->states[idx++] = to_dword(0.0f); /* ADAPTIVETESS_W */
1410 data->states[idx++] = FALSE; /* ENABLEADAPTIVETESSELATION */
1411 data->states[idx++] = FALSE; /* TWOSIDEDSTENCILMODE */
1412 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILFAIL */
1413 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILZFAIL */
1414 data->states[idx++] = D3DSTENCILOP_KEEP; /* CCW_STENCILPASS */
1415 data->states[idx++] = D3DCMP_ALWAYS; /* CCW_STENCILFUNC */
1416 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE1 */
1417 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE2 */
1418 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE3 */
1419 data->states[idx++] = 0xFFFFFFFF; /* BLENDFACTOR */
1420 data->states[idx++] = 0; /* SRGBWRITEENABLE */
1421 data->states[idx++] = to_dword(0.0f); /* DEPTHBIAS */
1422 data->states[idx++] = 0; /* WRAP8 */
1423 data->states[idx++] = 0; /* WRAP9 */
1424 data->states[idx++] = 0; /* WRAP10 */
1425 data->states[idx++] = 0; /* WRAP11 */
1426 data->states[idx++] = 0; /* WRAP12 */
1427 data->states[idx++] = 0; /* WRAP13 */
1428 data->states[idx++] = 0; /* WRAP14 */
1429 data->states[idx++] = 0; /* WRAP15 */
1430 data->states[idx++] = FALSE; /* SEPARATEALPHABLENDENABLE */
1431 data->states[idx++] = D3DBLEND_ONE; /* SRCBLENDALPHA */
1432 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLENDALPHA */
1433 data->states[idx++] = TRUE; /* BLENDOPALPHA */
1436 static void render_state_poison_data_init(struct render_state_data *data)
1440 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1442 data->states[i] = 0x1337c0de;
1446 static void render_state_test_data_init(struct render_state_data *data)
1448 unsigned int idx = 0;
1449 data->states[idx++] = D3DZB_USEW; /* ZENABLE */
1450 data->states[idx++] = D3DFILL_WIREFRAME; /* FILLMODE */
1451 data->states[idx++] = D3DSHADE_PHONG; /* SHADEMODE */
1452 data->states[idx++] = FALSE; /* ZWRITEENABLE */
1453 data->states[idx++] = TRUE; /* ALPHATESTENABLE */
1454 data->states[idx++] = FALSE; /* LASTPIXEL */
1455 data->states[idx++] = D3DBLEND_SRCALPHASAT; /* SRCBLEND */
1456 data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1457 data->states[idx++] = D3DCULL_CW; /* CULLMODE */
1458 data->states[idx++] = D3DCMP_NOTEQUAL; /* ZFUNC */
1459 data->states[idx++] = 10; /* ALPHAREF */
1460 data->states[idx++] = D3DCMP_GREATER; /* ALPHAFUNC */
1461 data->states[idx++] = TRUE; /* DITHERENABLE */
1462 data->states[idx++] = TRUE; /* ALPHABLENDENABLE */
1463 data->states[idx++] = TRUE; /* FOGENABLE */
1464 data->states[idx++] = TRUE; /* SPECULARENABLE */
1465 data->states[idx++] = 255 << 31; /* FOGCOLOR */
1466 data->states[idx++] = D3DFOG_EXP; /* FOGTABLEMODE */
1467 data->states[idx++] = to_dword(0.1f); /* FOGSTART */
1468 data->states[idx++] = to_dword(0.8f); /* FOGEND */
1469 data->states[idx++] = to_dword(0.5f); /* FOGDENSITY */
1470 data->states[idx++] = TRUE; /* RANGEFOGENABLE */
1471 data->states[idx++] = TRUE; /* STENCILENABLE */
1472 data->states[idx++] = D3DSTENCILOP_INCRSAT; /* STENCILFAIL */
1473 data->states[idx++] = D3DSTENCILOP_REPLACE; /* STENCILZFAIL */
1474 data->states[idx++] = D3DSTENCILOP_INVERT; /* STENCILPASS */
1475 data->states[idx++] = D3DCMP_LESS; /* STENCILFUNC */
1476 data->states[idx++] = 10; /* STENCILREF */
1477 data->states[idx++] = 0xFF00FF00; /* STENCILMASK */
1478 data->states[idx++] = 0x00FF00FF; /* STENCILWRITEMASK */
1479 data->states[idx++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1480 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 0 */
1481 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 1 */
1482 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 2 */
1483 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 4 */
1484 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 5 */
1485 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 6 */
1486 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 7 */
1487 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1488 data->states[idx++] = FALSE; /* CLIPPING */
1489 data->states[idx++] = FALSE; /* LIGHTING */
1490 data->states[idx++] = 255 << 16; /* AMBIENT */
1491 data->states[idx++] = D3DFOG_EXP2; /* FOGVERTEXMODE */
1492 data->states[idx++] = FALSE; /* COLORVERTEX */
1493 data->states[idx++] = FALSE; /* LOCALVIEWER */
1494 data->states[idx++] = TRUE; /* NORMALIZENORMALS */
1495 data->states[idx++] = D3DMCS_COLOR2; /* DIFFUSEMATERIALSOURCE */
1496 data->states[idx++] = D3DMCS_MATERIAL; /* SPECULARMATERIALSOURCE */
1497 data->states[idx++] = D3DMCS_COLOR1; /* AMBIENTMATERIALSOURCE */
1498 data->states[idx++] = D3DMCS_COLOR2; /* EMISSIVEMATERIALSOURCE */
1499 data->states[idx++] = D3DVBF_3WEIGHTS; /* VERTEXBLEND */
1500 data->states[idx++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1501 #if 0 /* Driver dependent, increase array size to enable */
1502 data->states[idx++] = to_dword(32.0f); /* POINTSIZE */
1504 data->states[idx++] = to_dword(0.7f); /* POINTSIZEMIN */
1505 data->states[idx++] = TRUE; /* POINTSPRITEENABLE */
1506 data->states[idx++] = TRUE; /* POINTSCALEENABLE */
1507 data->states[idx++] = to_dword(0.7f); /* POINTSCALE_A */
1508 data->states[idx++] = to_dword(0.5f); /* POINTSCALE_B */
1509 data->states[idx++] = to_dword(0.4f); /* POINTSCALE_C */
1510 data->states[idx++] = FALSE; /* MULTISAMPLEANTIALIAS */
1511 data->states[idx++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1512 data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1513 if (0) data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1514 data->states[idx++] = to_dword(77.0f); /* POINTSIZE_MAX */
1515 data->states[idx++] = TRUE; /* INDEXEDVERTEXBLENDENABLE */
1516 data->states[idx++] = 0x00000009; /* COLORWRITEENABLE */
1517 data->states[idx++] = to_dword(0.2f); /* TWEENFACTOR */
1518 data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1519 data->states[idx++] = D3DDEGREE_LINEAR; /* POSITIONDEGREE */
1520 data->states[idx++] = D3DDEGREE_CUBIC; /* NORMALDEGREE */
1521 data->states[idx++] = TRUE; /* SCISSORTESTENABLE */
1522 data->states[idx++] = to_dword(0.33f); /* SLOPESCALEDEPTHBIAS */
1523 data->states[idx++] = TRUE; /* ANTIALIASEDLINEENABLE */
1524 data->states[idx++] = to_dword(0.8f); /* MINTESSELATIONLEVEL */
1525 data->states[idx++] = to_dword(0.8f); /* MAXTESSELATIONLEVEL */
1526 data->states[idx++] = to_dword(0.2f); /* ADAPTIVETESS_X */
1527 data->states[idx++] = to_dword(0.3f); /* ADAPTIVETESS_Y */
1528 data->states[idx++] = to_dword(0.6f); /* ADAPTIVETESS_Z */
1529 data->states[idx++] = to_dword(0.4f); /* ADAPTIVETESS_W */
1530 data->states[idx++] = TRUE; /* ENABLEADAPTIVETESSELATION */
1531 data->states[idx++] = TRUE; /* TWOSIDEDSTENCILMODE */
1532 data->states[idx++] = D3DSTENCILOP_ZERO; /* CCW_STENCILFAIL */
1533 data->states[idx++] = D3DSTENCILOP_DECR; /* CCW_STENCILZFAIL */
1534 data->states[idx++] = D3DSTENCILOP_INCR; /* CCW_STENCILPASS */
1535 data->states[idx++] = D3DCMP_ALWAYS; /* CCW_STENCILFUNC */
1536 data->states[idx++] = 0x00000007; /* COLORWRITEENABLE1 */
1537 data->states[idx++] = 0x00000008; /* COLORWRITEENABLE2 */
1538 data->states[idx++] = 0x00000004; /* COLORWRITEENABLE3 */
1539 data->states[idx++] = 0xF0F1F2F3; /* BLENDFACTOR */
1540 data->states[idx++] = 1; /* SRGBWRITEENABLE */
1541 data->states[idx++] = to_dword(0.3f); /* DEPTHBIAS */
1542 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 8 */
1543 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 9 */
1544 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 10 */
1545 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 11 */
1546 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 12 */
1547 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 13 */
1548 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 14 */
1549 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 15 */
1550 data->states[idx++] = TRUE; /* SEPARATEALPHABLENDENABLE */
1551 data->states[idx++] = D3DBLEND_ZERO; /* SRCBLENDALPHA */
1552 data->states[idx++] = D3DBLEND_ONE; /* DESTBLENDALPHA */
1553 data->states[idx++] = FALSE; /* BLENDOPALPHA */
1556 static HRESULT render_state_test_init(IDirect3DDevice9 *device, struct state_test *test)
1558 static const DWORD states_vertex[] =
1560 D3DRS_ADAPTIVETESS_W,
1561 D3DRS_ADAPTIVETESS_X,
1562 D3DRS_ADAPTIVETESS_Y,
1563 D3DRS_ADAPTIVETESS_Z,
1565 D3DRS_AMBIENTMATERIALSOURCE,
1567 D3DRS_CLIPPLANEENABLE,
1570 D3DRS_DIFFUSEMATERIALSOURCE,
1571 D3DRS_EMISSIVEMATERIALSOURCE,
1572 D3DRS_ENABLEADAPTIVETESSELLATION,
1579 D3DRS_FOGVERTEXMODE,
1580 D3DRS_INDEXEDVERTEXBLENDENABLE,
1583 D3DRS_MAXTESSELLATIONLEVEL,
1584 D3DRS_MINTESSELLATIONLEVEL,
1585 D3DRS_MULTISAMPLEANTIALIAS,
1586 D3DRS_MULTISAMPLEMASK,
1588 D3DRS_NORMALIZENORMALS,
1589 D3DRS_PATCHEDGESTYLE,
1593 D3DRS_POINTSCALEENABLE,
1595 D3DRS_POINTSIZE_MAX,
1596 D3DRS_POINTSIZE_MIN,
1597 D3DRS_POINTSPRITEENABLE,
1598 D3DRS_POSITIONDEGREE,
1599 D3DRS_RANGEFOGENABLE,
1601 D3DRS_SPECULARENABLE,
1602 D3DRS_SPECULARMATERIALSOURCE,
1607 static const DWORD states_pixel[] =
1609 D3DRS_ALPHABLENDENABLE,
1612 D3DRS_ALPHATESTENABLE,
1613 D3DRS_ANTIALIASEDLINEENABLE,
1617 D3DRS_CCW_STENCILFAIL,
1618 D3DRS_CCW_STENCILPASS,
1619 D3DRS_CCW_STENCILZFAIL,
1620 D3DRS_COLORWRITEENABLE,
1621 D3DRS_COLORWRITEENABLE1,
1622 D3DRS_COLORWRITEENABLE2,
1623 D3DRS_COLORWRITEENABLE3,
1626 D3DRS_DESTBLENDALPHA,
1633 D3DRS_SCISSORTESTENABLE,
1634 D3DRS_SEPARATEALPHABLENDENABLE,
1636 D3DRS_SLOPESCALEDEPTHBIAS,
1638 D3DRS_SRCBLENDALPHA,
1639 D3DRS_SRGBWRITEENABLE,
1640 D3DRS_STENCILENABLE,
1646 D3DRS_STENCILWRITEMASK,
1648 D3DRS_TEXTUREFACTOR,
1649 D3DRS_TWOSIDEDSTENCILMODE,
1671 const struct render_state_arg *rsarg = test->test_arg;
1674 struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1675 if (ctx == NULL) return E_FAIL;
1676 test->test_context = ctx;
1678 test->default_data = &ctx->default_data_buffer;
1679 test->initial_data = &ctx->default_data_buffer;
1680 test->test_data_in = &ctx->test_data_all_buffer;
1681 test->test_data_out_all = &ctx->test_data_all_buffer;
1682 test->test_data_out_vertex = &ctx->test_data_vertex_buffer;
1683 test->test_data_out_pixel = &ctx->test_data_pixel_buffer;
1685 render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1686 render_state_test_data_init(&ctx->test_data_all_buffer);
1687 render_state_poison_data_init(&ctx->poison_data_buffer);
1689 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1691 ctx->test_data_vertex_buffer.states[i] = ctx->default_data_buffer.states[i];
1692 for (j = 0; j < sizeof(states_vertex) / sizeof(*states_vertex); ++j)
1694 if (render_state_indices[i] == states_vertex[j])
1696 ctx->test_data_vertex_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1701 ctx->test_data_pixel_buffer.states[i] = ctx->default_data_buffer.states[i];
1702 for (j = 0; j < sizeof(states_pixel) / sizeof(*states_pixel); ++j)
1704 if (render_state_indices[i] == states_pixel[j])
1706 ctx->test_data_pixel_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1715 static void render_state_test_cleanup(IDirect3DDevice9 *device, struct state_test *test)
1717 HeapFree(GetProcessHeap(), 0, test->test_context);
1720 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1722 test->init = render_state_test_init;
1723 test->cleanup = render_state_test_cleanup;
1724 test->apply_data = render_state_apply_data;
1725 test->check_data = render_state_check_data;
1726 test->test_name = "set_get_render_states";
1727 test->test_arg = test_arg;
1730 /* resource tests */
1732 struct resource_test_arg
1740 struct resource_test_data
1742 IDirect3DVertexDeclaration9 *decl;
1743 IDirect3DVertexShader9 *vs;
1744 IDirect3DPixelShader9 *ps;
1745 IDirect3DIndexBuffer9 *ib;
1746 IDirect3DVertexBuffer9 **vb;
1747 IDirect3DTexture9 **tex;
1750 struct resource_test_context
1752 struct resource_test_data default_data;
1753 struct resource_test_data test_data_all;
1754 struct resource_test_data test_data_vertex;
1755 struct resource_test_data test_data_pixel;
1756 struct resource_test_data poison_data;
1759 static void resource_apply_data(IDirect3DDevice9 *device, const struct state_test *test, const void *data)
1761 const struct resource_test_arg *arg = test->test_arg;
1762 const struct resource_test_data *d = data;
1766 hr = IDirect3DDevice9_SetVertexDeclaration(device, d->decl);
1767 ok(SUCCEEDED(hr), "SetVertexDeclaration (%p) returned %#x.\n", d->decl, hr);
1769 hr = IDirect3DDevice9_SetVertexShader(device, d->vs);
1770 ok(SUCCEEDED(hr), "SetVertexShader (%p) returned %#x.\n", d->vs, hr);
1772 hr = IDirect3DDevice9_SetPixelShader(device, d->ps);
1773 ok(SUCCEEDED(hr), "SetPixelShader (%p) returned %#x.\n", d->ps, hr);
1775 hr = IDirect3DDevice9_SetIndices(device, d->ib);
1776 ok(SUCCEEDED(hr), "SetIndices (%p) returned %#x.\n", d->ib, hr);
1778 for (i = 0; i < arg->stream_count; ++i)
1780 hr = IDirect3DDevice9_SetStreamSource(device, i, d->vb[i], 0, 64);
1781 ok(SUCCEEDED(hr), "SetStreamSource (%u, %p, 0, 64) returned %#x.\n",
1785 for (i = 0; i < arg->tex_count; ++i)
1787 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)d->tex[i]);
1788 ok(SUCCEEDED(hr), "SetTexture (%u, %p) returned %#x.\n", i, d->tex[i], hr);
1792 static void resource_check_data(IDirect3DDevice9 *device, const struct state_test *test,
1793 const void *expected_data, unsigned int chain_stage, DWORD quirk)
1795 const struct resource_test_context *ctx = test->test_context;
1796 const struct resource_test_data *poison = &ctx->poison_data;
1797 const struct resource_test_arg *arg = test->test_arg;
1798 const struct resource_test_data *d = expected_data;
1805 hr = IDirect3DDevice9_GetVertexDeclaration(device, (IDirect3DVertexDeclaration9 **)&ptr);
1806 ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x.\n", hr);
1807 if (quirk & SB_QUIRK_RECORDED_VDECL_CAPTURE)
1809 ok(ptr == ctx->test_data_all.decl, "Chain stage %u, expected vertex declaration %p, received %p.\n",
1810 chain_stage, ctx->test_data_all.decl, ptr);
1814 ok(ptr == d->decl, "Chain stage %u, expected vertex declaration %p, received %p.\n",
1815 chain_stage, d->decl, ptr);
1817 if (SUCCEEDED(hr) && ptr)
1819 IDirect3DVertexDeclaration9_Release((IDirect3DVertexDeclaration9 *)ptr);
1823 hr = IDirect3DDevice9_GetVertexShader(device, (IDirect3DVertexShader9 **)&ptr);
1824 ok(SUCCEEDED(hr), "GetVertexShader returned %#x.\n", hr);
1825 ok(ptr == d->vs, "Chain stage %u, expected vertex shader %p, received %p.\n",
1826 chain_stage, d->vs, ptr);
1827 if (SUCCEEDED(hr) && ptr)
1829 IDirect3DVertexShader9_Release((IDirect3DVertexShader9 *)ptr);
1833 hr = IDirect3DDevice9_GetPixelShader(device, (IDirect3DPixelShader9 **)&ptr);
1834 ok(SUCCEEDED(hr), "GetPixelShader returned %#x.\n", hr);
1835 ok(ptr == d->ps, "Chain stage %u, expected pixel shader %p, received %p.\n",
1836 chain_stage, d->ps, ptr);
1837 if (SUCCEEDED(hr) && ptr)
1839 IDirect3DPixelShader9_Release((IDirect3DPixelShader9 *)ptr);
1843 hr = IDirect3DDevice9_GetIndices(device, (IDirect3DIndexBuffer9 **)&ptr);
1844 ok(SUCCEEDED(hr), "GetIndices returned %#x.\n", hr);
1845 ok(ptr == d->ib, "Chain stage %u, expected index buffer %p, received %p.\n",
1846 chain_stage, d->ib, ptr);
1847 if (SUCCEEDED(hr) && ptr)
1849 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)ptr);
1852 for (i = 0; i < arg->stream_count; ++i)
1854 ptr = poison->vb[i];
1855 hr = IDirect3DDevice9_GetStreamSource(device, i, (IDirect3DVertexBuffer9 **)&ptr, &v, &w);
1856 ok(SUCCEEDED(hr), "GetStreamSource (%u) returned %#x.\n", i, hr);
1857 ok(ptr == d->vb[i], "Chain stage %u, stream %u, expected vertex buffer %p, received %p.\n",
1858 chain_stage, i, d->vb[i], ptr);
1859 if (SUCCEEDED(hr) && ptr)
1861 IDirect3DIndexBuffer9_Release((IDirect3DVertexBuffer9 *)ptr);
1865 for (i = 0; i < arg->tex_count; ++i)
1867 ptr = poison->tex[i];
1868 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **)&ptr);
1869 ok(SUCCEEDED(hr), "SetTexture (%u) returned %#x.\n", i, hr);
1870 ok(ptr == d->tex[i], "Chain stage %u, texture stage %u, expected texture %p, received %p.\n",
1871 chain_stage, i, d->tex[i], ptr);
1872 if (SUCCEEDED(hr) && ptr)
1874 IDirect3DBaseTexture9_Release((IDirect3DBaseTexture9 *)ptr);
1879 static void resource_default_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1887 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1888 for (i = 0; i < arg->stream_count; ++i)
1892 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1893 for (i = 0; i < arg->tex_count; ++i)
1895 data->tex[i] = NULL;
1899 static void resource_test_data_init(IDirect3DDevice9 *device,
1900 struct resource_test_data *data, const struct resource_test_arg *arg)
1902 static const DWORD vs_code[] =
1904 0xfffe0101, /* vs_1_1 */
1905 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
1906 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
1907 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
1908 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
1909 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
1910 0x0000ffff, /* END */
1912 static const DWORD ps_code[] =
1914 0xffff0101, /* ps_1_1 */
1915 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
1916 0x00000042, 0xb00f0000, /* tex t0 */
1917 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
1918 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
1919 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
1920 0x0000ffff, /* END */
1922 static const D3DVERTEXELEMENT9 decl[] =
1924 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1925 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1932 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &data->decl);
1933 ok(SUCCEEDED(hr), "CreateVertexDeclaration returned %#x.\n", hr);
1935 if (arg->vs_version)
1937 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &data->vs);
1938 ok(SUCCEEDED(hr), "CreateVertexShader returned %#x.\n", hr);
1945 if (arg->ps_version)
1947 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &data->ps);
1948 ok(SUCCEEDED(hr), "CreatePixelShader returned %#x.\n", hr);
1955 hr = IDirect3DDevice9_CreateIndexBuffer(device, 64, D3DUSAGE_DYNAMIC,
1956 D3DFMT_INDEX32, D3DPOOL_DEFAULT, &data->ib, NULL);
1957 ok(SUCCEEDED(hr), "CreateIndexBuffer returned %#x.\n", hr);
1959 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1960 for (i = 0; i < arg->stream_count; ++i)
1962 hr = IDirect3DDevice9_CreateVertexBuffer(device, 64, D3DUSAGE_DYNAMIC,
1963 0, D3DPOOL_DEFAULT, &data->vb[i], NULL);
1964 ok(SUCCEEDED(hr), "CreateVertexBuffer (%u) returned %#x.\n", i, hr);
1966 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1967 for (i = 0; i < arg->tex_count; ++i)
1969 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
1970 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &data->tex[i], NULL);
1971 ok(SUCCEEDED(hr), "CreateTexture (%u) returned %#x.\n", i, hr);
1975 static void resource_poison_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1977 DWORD_PTR poison = 0xdeadbeef;
1980 data->decl = (IDirect3DVertexDeclaration9 *)poison++;
1981 data->vs = (IDirect3DVertexShader9 *)poison++;
1982 data->ps = (IDirect3DPixelShader9 *)poison++;
1983 data->ib = (IDirect3DIndexBuffer9 *)poison++;
1984 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1985 for (i = 0; i < arg->stream_count; ++i)
1987 data->vb[i] = (IDirect3DVertexBuffer9 *)poison++;
1989 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1990 for (i = 0; i < arg->tex_count; ++i)
1992 data->tex[i] = (IDirect3DTexture9 *)poison++;
1996 static HRESULT resource_test_init(IDirect3DDevice9 *device, struct state_test *test)
1998 const struct resource_test_arg *arg = test->test_arg;
1999 struct resource_test_context *ctx;
2001 ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
2002 if (!ctx) return E_OUTOFMEMORY;
2004 test->test_context = ctx;
2005 test->test_data_in = &ctx->test_data_all;
2006 test->test_data_out_all = &ctx->test_data_all;
2007 test->test_data_out_vertex = &ctx->test_data_vertex;
2008 test->test_data_out_pixel = &ctx->test_data_pixel;
2009 test->default_data = &ctx->default_data;
2010 test->initial_data = &ctx->default_data;
2012 resource_default_data_init(&ctx->default_data, arg);
2013 resource_test_data_init(device, &ctx->test_data_all, arg);
2014 resource_default_data_init(&ctx->test_data_vertex, arg);
2015 resource_default_data_init(&ctx->test_data_pixel, arg);
2016 resource_poison_data_init(&ctx->poison_data, arg);
2018 ctx->test_data_vertex.decl = ctx->test_data_all.decl;
2019 ctx->test_data_vertex.vs = ctx->test_data_all.vs;
2020 ctx->test_data_pixel.ps = ctx->test_data_all.ps;
2025 static void resource_test_cleanup(IDirect3DDevice9 *device, struct state_test *test)
2027 struct resource_test_context *ctx = test->test_context;
2028 const struct resource_test_arg *arg = test->test_arg;
2031 resource_apply_data(device, test, &ctx->default_data);
2033 IDirect3DVertexDeclaration9_Release(ctx->test_data_all.decl);
2034 if (ctx->test_data_all.vs) IDirect3DVertexShader9_Release(ctx->test_data_all.vs);
2035 if (ctx->test_data_all.ps) IDirect3DPixelShader9_Release(ctx->test_data_all.ps);
2036 IDirect3DIndexBuffer9_Release(ctx->test_data_all.ib);
2037 for (i = 0; i < arg->stream_count; ++i)
2039 IDirect3DVertexBuffer9_Release(ctx->test_data_all.vb[i]);
2042 for (i = 0; i < arg->tex_count; ++i)
2044 IDirect3DBaseTexture9_Release(ctx->test_data_all.tex[i]);
2047 HeapFree(GetProcessHeap(), 0, ctx->default_data.vb);
2048 HeapFree(GetProcessHeap(), 0, ctx->default_data.tex);
2049 HeapFree(GetProcessHeap(), 0, ctx->test_data_all.vb);
2050 HeapFree(GetProcessHeap(), 0, ctx->test_data_all.tex);
2051 HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.vb);
2052 HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.tex);
2053 HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.vb);
2054 HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.tex);
2055 HeapFree(GetProcessHeap(), 0, ctx->poison_data.vb);
2056 HeapFree(GetProcessHeap(), 0, ctx->poison_data.tex);
2057 HeapFree(GetProcessHeap(), 0, ctx);
2060 static void resource_test_queue(struct state_test *test, const struct resource_test_arg *test_arg)
2062 test->init = resource_test_init;
2063 test->cleanup = resource_test_cleanup;
2064 test->apply_data = resource_apply_data;
2065 test->check_data = resource_check_data;
2066 test->test_name = "set_get_resources";
2067 test->test_arg = test_arg;
2070 /* =================== Main state tests function =============================== */
2072 static void test_state_management(IDirect3DDevice9 *device, D3DPRESENT_PARAMETERS *device_pparams)
2074 struct shader_constant_arg pshader_constant_arg;
2075 struct shader_constant_arg vshader_constant_arg;
2076 struct resource_test_arg resource_test_arg;
2077 struct render_state_arg render_state_arg;
2078 struct light_arg light_arg;
2082 /* Test count: 2 for shader constants
2088 struct state_test tests[6];
2089 unsigned int tcount = 0;
2091 hret = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2092 ok(hret == D3D_OK, "GetDeviceCaps returned %#x.\n", hret);
2093 if (hret != D3D_OK) return;
2095 texture_stages = caps.MaxTextureBlendStages;
2097 /* Zero test memory */
2098 memset(tests, 0, sizeof(tests));
2100 if (caps.VertexShaderVersion & 0xffff) {
2101 vshader_constant_arg.idx = 0;
2102 vshader_constant_arg.pshader = FALSE;
2103 shader_constants_queue_test(&tests[tcount], &vshader_constant_arg);
2107 if (caps.PixelShaderVersion & 0xffff) {
2108 pshader_constant_arg.idx = 0;
2109 pshader_constant_arg.pshader = TRUE;
2110 shader_constants_queue_test(&tests[tcount], &pshader_constant_arg);
2115 lights_queue_test(&tests[tcount], &light_arg);
2118 transform_queue_test(&tests[tcount]);
2121 render_state_arg.device_pparams = device_pparams;
2122 render_state_arg.pointsize_max = caps.MaxPointSize;
2123 render_states_queue_test(&tests[tcount], &render_state_arg);
2126 resource_test_arg.vs_version = caps.VertexShaderVersion & 0xffff;
2127 resource_test_arg.ps_version = caps.PixelShaderVersion & 0xffff;
2128 resource_test_arg.stream_count = caps.MaxStreams;
2129 resource_test_arg.tex_count = caps.MaxTextureBlendStages;
2130 resource_test_queue(&tests[tcount], &resource_test_arg);
2133 execute_test_chain_all(device, tests, tcount);
2136 static void test_shader_constant_apply(IDirect3DDevice9 *device)
2138 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
2139 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
2140 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
2141 IDirect3DStateBlock9 *stateblock;
2142 DWORD vs_version, ps_version;
2147 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2148 ok(SUCCEEDED(hr), "GetDeviceCaps returned %#x.\n", hr);
2149 vs_version = caps.VertexShaderVersion & 0xffff;
2150 ps_version = caps.PixelShaderVersion & 0xffff;
2154 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
2155 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2156 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
2157 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2159 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
2160 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2161 ok(!memcmp(ret, initial, sizeof(initial)),
2162 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2163 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2164 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
2165 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2166 ok(!memcmp(ret, initial, sizeof(initial)),
2167 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2168 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2170 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
2171 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2175 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
2176 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2177 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
2178 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2180 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
2181 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2182 ok(!memcmp(ret, initial, sizeof(initial)),
2183 "GetpixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2184 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2185 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
2186 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2187 ok(!memcmp(ret, initial, sizeof(initial)),
2188 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2189 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2191 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
2192 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2195 hr = IDirect3DDevice9_BeginStateBlock(device);
2196 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x\n", hr);
2200 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
2201 ok(SUCCEEDED(hr), "SetVertexShaderConstantF returned %#x\n", hr);
2205 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
2206 ok(SUCCEEDED(hr), "SetPixelShaderConstantF returned %#x\n", hr);
2209 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
2210 ok(SUCCEEDED(hr), "EndStateBlock returned %#x\n", hr);
2214 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
2215 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2216 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2217 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2218 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2219 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
2220 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2221 ok(!memcmp(ret, initial, sizeof(initial)),
2222 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2223 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2227 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
2228 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2229 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2230 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2231 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2232 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
2233 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2234 ok(!memcmp(ret, initial, sizeof(initial)),
2235 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2236 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2239 /* Apply doesn't overwrite constants that aren't explicitly set on the source stateblock. */
2240 hr = IDirect3DStateBlock9_Apply(stateblock);
2241 ok(SUCCEEDED(hr), "Apply returned %#x\n", hr);
2245 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
2246 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2247 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2248 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2249 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2250 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
2251 ok(SUCCEEDED(hr), "GetVertexShaderConstantF returned %#x\n", hr);
2252 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2253 "GetVertexShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2254 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2258 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
2259 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2260 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2261 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2262 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2263 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
2264 ok(SUCCEEDED(hr), "GetPixelShaderConstantF returned %#x\n", hr);
2265 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2266 "GetPixelShaderConstantF got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2267 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2270 IDirect3DStateBlock9_Release(stateblock);
2273 static void test_vdecl_apply(IDirect3DDevice9 *device)
2275 static const D3DVERTEXELEMENT9 decl1[] =
2277 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2278 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2282 static const D3DVERTEXELEMENT9 decl2[] =
2284 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2285 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2286 {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
2290 IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
2291 IDirect3DStateBlock9 *stateblock;
2294 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
2295 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
2297 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
2298 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
2300 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2301 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2302 hr = IDirect3DDevice9_BeginStateBlock(device);
2303 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
2304 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
2305 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2306 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
2307 ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#x.\n", hr);
2308 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2309 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2310 hr = IDirect3DStateBlock9_Apply(stateblock);
2311 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2312 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2313 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2314 ok(declaration == declaration1, "Expected vertex declaration %p, received %p.\n",
2315 declaration1, declaration);
2316 IDirect3DVertexDeclaration9_Release(declaration);
2318 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2319 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2320 hr = IDirect3DStateBlock9_Capture(stateblock);
2321 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2322 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2323 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2324 hr = IDirect3DStateBlock9_Apply(stateblock);
2325 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2326 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2327 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2328 ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2329 declaration2, declaration);
2330 IDirect3DVertexDeclaration9_Release(declaration);
2332 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2333 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2334 hr = IDirect3DStateBlock9_Capture(stateblock);
2335 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2336 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2337 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2338 hr = IDirect3DStateBlock9_Apply(stateblock);
2339 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2340 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2341 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2342 ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2343 declaration2, declaration);
2344 IDirect3DVertexDeclaration9_Release(declaration);
2346 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2347 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2348 hr = IDirect3DStateBlock9_Capture(stateblock);
2349 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2350 hr = IDirect3DStateBlock9_Apply(stateblock);
2351 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2352 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2353 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2354 ok(declaration == NULL, "Expected vertex declaration %p, received %p.\n",
2357 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2358 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2359 hr = IDirect3DStateBlock9_Capture(stateblock);
2360 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2361 hr = IDirect3DStateBlock9_Apply(stateblock);
2362 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2363 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2364 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2365 ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2366 declaration2, declaration);
2367 IDirect3DVertexDeclaration9_Release(declaration);
2369 IDirect3DStateBlock9_Release(stateblock);
2370 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
2371 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2372 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
2373 ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#x.\n", hr);
2374 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2375 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2376 hr = IDirect3DStateBlock9_Apply(stateblock);
2377 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2378 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2379 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2380 ok(declaration == declaration1, "Expected vertex declaration %p, received %p.\n",
2381 declaration1, declaration);
2382 IDirect3DVertexDeclaration9_Release(declaration);
2384 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2385 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2386 hr = IDirect3DStateBlock9_Capture(stateblock);
2387 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2388 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2389 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2390 hr = IDirect3DStateBlock9_Apply(stateblock);
2391 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2392 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2393 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2394 ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2395 declaration2, declaration);
2396 IDirect3DVertexDeclaration9_Release(declaration);
2398 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2399 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2400 hr = IDirect3DStateBlock9_Capture(stateblock);
2401 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2402 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2403 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2404 hr = IDirect3DStateBlock9_Apply(stateblock);
2405 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2406 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2407 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2408 ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2409 declaration2, declaration);
2410 IDirect3DVertexDeclaration9_Release(declaration);
2412 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2413 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2414 hr = IDirect3DStateBlock9_Capture(stateblock);
2415 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2416 hr = IDirect3DStateBlock9_Apply(stateblock);
2417 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2418 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2419 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2420 ok(declaration == NULL, "Expected vertex declaration %p, received %p.\n",
2423 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
2424 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2425 hr = IDirect3DStateBlock9_Capture(stateblock);
2426 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
2427 hr = IDirect3DStateBlock9_Apply(stateblock);
2428 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
2429 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
2430 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
2431 ok(declaration == declaration2, "Expected vertex declaration %p, received %p.\n",
2432 declaration2, declaration);
2433 IDirect3DVertexDeclaration9_Release(declaration);
2435 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2436 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2437 IDirect3DVertexDeclaration9_Release(declaration1);
2438 IDirect3DVertexDeclaration9_Release(declaration2);
2439 IDirect3DStateBlock9_Release(stateblock);
2442 START_TEST(stateblock)
2444 IDirect3DDevice9 *device_ptr = NULL;
2445 D3DPRESENT_PARAMETERS device_pparams;
2449 d3d9_handle = LoadLibraryA("d3d9.dll");
2452 skip("Could not load d3d9.dll\n");
2456 hret = init_d3d9(&device_ptr, &device_pparams);
2457 if (hret != D3D_OK) return;
2459 test_begin_end_state_block(device_ptr);
2460 test_state_management(device_ptr, &device_pparams);
2461 test_shader_constant_apply(device_ptr);
2462 test_vdecl_apply(device_ptr);
2464 refcount = IDirect3DDevice9_Release(device_ptr);
2465 ok(!refcount, "Device has %u references left\n", refcount);