2 * Copyright 2006 Ivan Gyurdiev
3 * Copyright 2005, 2008 Henri Verbeet
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 DWORD texture_stages;
26 static HWND create_window(void)
29 wc.lpfnWndProc = DefWindowProc;
30 wc.lpszClassName = "d3d8_test_wc";
33 return CreateWindow("d3d8_test_wc", "d3d8_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
36 static HRESULT init_d3d8(HMODULE d3d8_module, IDirect3DDevice8 **device, D3DPRESENT_PARAMETERS *device_pparams)
38 IDirect3D8 * (WINAPI *d3d8_create)(UINT SDKVersion) = 0;
44 d3d8_create = (void *)GetProcAddress(d3d8_module, "Direct3DCreate8");
45 if (!d3d8_create) return E_FAIL;
47 d3d8 = d3d8_create(D3D_SDK_VERSION);
50 skip("Failed to create D3D8 object.\n");
54 window = create_window();
56 IDirect3D8_GetAdapterDisplayMode(d3d8, D3DADAPTER_DEFAULT, &d3ddm);
57 memset(device_pparams, 0, sizeof(*device_pparams));
58 device_pparams->Windowed = TRUE;
59 device_pparams->SwapEffect = D3DSWAPEFFECT_DISCARD;
60 device_pparams->BackBufferFormat = d3ddm.Format;
62 hr = IDirect3D8_CreateDevice(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
63 D3DCREATE_SOFTWARE_VERTEXPROCESSING, device_pparams, device);
64 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL),
65 "IDirect3D8_CreateDevice failed, hr %#x.\n", hr);
70 static void test_begin_end_state_block(IDirect3DDevice8 *device)
76 hr = IDirect3DDevice8_BeginStateBlock(device);
77 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
78 if (FAILED(hr)) return;
80 /* Calling BeginStateBlock while recording should return D3DERR_INVALIDCALL */
81 hr = IDirect3DDevice8_BeginStateBlock(device);
82 ok(hr == D3DERR_INVALIDCALL, "BeginStateBlock returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
83 if (hr != D3DERR_INVALIDCALL) return;
86 state_block = 0xdeadbeef;
87 hr = IDirect3DDevice8_EndStateBlock(device, &state_block);
88 ok(SUCCEEDED(hr) && state_block && state_block != 0xdeadbeef,
89 "EndStateBlock returned: hr %#x, state_block %#x. "
90 "Expected hr %#x, state_block != 0, state_block != 0xdeadbeef.\n", hr, state_block, D3D_OK);
91 IDirect3DDevice8_DeleteStateBlock(device, state_block);
93 /* Calling EndStateBlock while not recording should return D3DERR_INVALIDCALL.
94 * state_block should not be touched. */
95 state_block = 0xdeadbeef;
96 hr = IDirect3DDevice8_EndStateBlock(device, &state_block);
97 ok(hr == D3DERR_INVALIDCALL && state_block == 0xdeadbeef,
98 "EndStateBlock returned: hr %#x, state_block %#x. "
99 "Expected hr %#x, state_block 0xdeadbeef.\n", hr, state_block, D3DERR_INVALIDCALL);
102 /* ============================ State Testing Framework ========================== */
106 const char *test_name;
108 /* The initial data is usually the same
109 * as the default data, but a write can have side effects.
110 * The initial data is tested first, before any writes take place
111 * The default data can be tested after a write */
112 const void *initial_data;
114 /* The default data is the standard state to compare
115 * against, and restore to */
116 const void *default_data;
118 /* The test data is the experiment data to try
119 * in - what we want to write
120 * out - what windows will actually write (not necessarily the same) */
121 const void *test_data_in;
122 const void *test_data_out_all;
123 const void *test_data_out_vertex;
124 const void *test_data_out_pixel;
126 HRESULT (*init)(IDirect3DDevice8 *device, struct state_test *test);
127 void (*cleanup)(IDirect3DDevice8 *device, struct state_test *test);
128 void (*apply_data)(IDirect3DDevice8 *device, const struct state_test *test,
130 void (*check_data)(IDirect3DDevice8 *device, const struct state_test *test,
131 const void *data_expected, unsigned int chain_stage);
134 const void *test_arg;
136 /* Test-specific context data */
140 /* See below for explanation of the flags */
142 #define EVENT_ERROR -1
147 IDirect3DSurface8 *original_render_target;
148 IDirect3DSwapChain8 *new_swap_chain;
164 int (*event_fn)(IDirect3DDevice8 *device, struct event_data *event_data);
165 enum stateblock_data check;
166 enum stateblock_data apply;
169 static const void *get_event_data(const struct state_test *test, enum stateblock_data data)
173 case SB_DATA_DEFAULT:
174 return test->default_data;
176 case SB_DATA_INITIAL:
177 return test->initial_data;
179 case SB_DATA_TEST_IN:
180 return test->test_data_in;
182 case SB_DATA_TEST_ALL:
183 return test->test_data_out_all;
185 case SB_DATA_TEST_VERTEX:
186 return test->test_data_out_vertex;
188 case SB_DATA_TEST_PIXEL:
189 return test->test_data_out_pixel;
196 /* This is an event-machine, which tests things.
197 * It tests get and set operations for a batch of states, based on
198 * results from the event function, which directs what's to be done */
199 static void execute_test_chain(IDirect3DDevice8 *device, struct state_test *test,
200 unsigned int ntests, struct event *event, unsigned int nevents, struct event_data *event_data)
204 /* For each queued event */
205 for (j = 0; j < nevents; ++j)
209 /* Execute the next event handler (if available). */
210 if (event[j].event_fn)
212 if (event[j].event_fn(device, event_data) == EVENT_ERROR)
214 trace("Stage %u in error state, aborting.\n", j);
219 if (event[j].check != SB_DATA_NONE)
221 for (i = 0; i < ntests; ++i)
223 data = get_event_data(&test[i], event[j].check);
224 test[i].check_data(device, &test[i], data, j);
228 if (event[j].apply != SB_DATA_NONE)
230 for (i = 0; i < ntests; ++i)
232 data = get_event_data(&test[i], event[j].apply);
233 test[i].apply_data(device, &test[i], data);
238 /* Attempt to reset any changes made. */
239 for (i = 0; i < ntests; ++i)
241 test[i].apply_data(device, &test[i], test[i].default_data);
245 static int switch_render_target(IDirect3DDevice8* device, struct event_data *event_data)
247 D3DPRESENT_PARAMETERS present_parameters;
248 IDirect3DSwapChain8 *swapchain = NULL;
249 IDirect3DSurface8 *backbuffer = NULL;
250 D3DDISPLAYMODE d3ddm;
253 /* Parameters for new swapchain */
254 IDirect3DDevice8_GetDisplayMode(device, &d3ddm);
255 memset(&present_parameters, 0, sizeof(present_parameters));
256 present_parameters.Windowed = TRUE;
257 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
258 present_parameters.BackBufferFormat = d3ddm.Format;
260 /* Create new swapchain */
261 hr = IDirect3DDevice8_CreateAdditionalSwapChain(device, &present_parameters, &swapchain);
262 ok(SUCCEEDED(hr), "CreateAdditionalSwapChain returned %#x.\n", hr);
263 if (FAILED(hr)) goto error;
265 /* Get its backbuffer */
266 hr = IDirect3DSwapChain8_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
267 ok(SUCCEEDED(hr), "GetBackBuffer returned %#x.\n", hr);
268 if (FAILED(hr)) goto error;
270 /* Save the current render target */
271 hr = IDirect3DDevice8_GetRenderTarget(device, &event_data->original_render_target);
272 ok(SUCCEEDED(hr), "GetRenderTarget returned %#x.\n", hr);
273 if (FAILED(hr)) goto error;
275 /* Set the new swapchain's backbuffer as a render target */
276 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
277 ok(SUCCEEDED(hr), "SetRenderTarget returned %#x.\n", hr);
278 if (FAILED(hr)) goto error;
280 IDirect3DSurface8_Release(backbuffer);
281 event_data->new_swap_chain = swapchain;
285 if (backbuffer) IDirect3DSurface8_Release(backbuffer);
286 if (swapchain) IDirect3DSwapChain8_Release(swapchain);
290 static int revert_render_target(IDirect3DDevice8 *device, struct event_data *event_data)
294 /* Reset the old render target */
295 hr = IDirect3DDevice8_SetRenderTarget(device, event_data->original_render_target, NULL);
296 ok(SUCCEEDED(hr), "SetRenderTarget returned %#x.\n", hr);
299 IDirect3DSurface8_Release(event_data->original_render_target);
303 IDirect3DSurface8_Release(event_data->original_render_target);
304 IDirect3DSwapChain8_Release(event_data->new_swap_chain);
308 static int create_stateblock_all(IDirect3DDevice8 *device, struct event_data *event_data)
312 hr = IDirect3DDevice8_CreateStateBlock(device, D3DSBT_ALL, &event_data->stateblock);
313 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
314 if (FAILED(hr)) return EVENT_ERROR;
318 static int create_stateblock_vertex(IDirect3DDevice8 *device, struct event_data *event_data)
322 hr = IDirect3DDevice8_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &event_data->stateblock);
323 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
324 if (FAILED(hr)) return EVENT_ERROR;
328 static int create_stateblock_pixel(IDirect3DDevice8 *device, struct event_data *event_data)
332 hr = IDirect3DDevice8_CreateStateBlock(device, D3DSBT_PIXELSTATE, &event_data->stateblock);
333 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
334 if (FAILED(hr)) return EVENT_ERROR;
338 static int begin_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
342 hr = IDirect3DDevice8_BeginStateBlock(device);
343 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x.\n", hr);
344 if (FAILED(hr)) return EVENT_ERROR;
348 static int end_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
352 hr = IDirect3DDevice8_EndStateBlock(device, &event_data->stateblock);
353 ok(SUCCEEDED(hr), "EndStateBlock returned %#x.\n", hr);
354 if (FAILED(hr)) return EVENT_ERROR;
358 static int delete_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
360 IDirect3DDevice8_DeleteStateBlock(device, event_data->stateblock);
364 static int apply_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
368 hr = IDirect3DDevice8_ApplyStateBlock(device, event_data->stateblock);
369 ok(SUCCEEDED(hr), "Apply returned %#x.\n", hr);
371 IDirect3DDevice8_DeleteStateBlock(device, event_data->stateblock);
372 if (FAILED(hr)) return EVENT_ERROR;
376 static int capture_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
380 hr = IDirect3DDevice8_CaptureStateBlock(device, event_data->stateblock);
381 ok(SUCCEEDED(hr), "Capture returned %#x.\n", hr);
382 if (FAILED(hr)) return EVENT_ERROR;
387 static void execute_test_chain_all(IDirect3DDevice8 *device, struct state_test *test, unsigned int ntests)
389 struct event_data arg;
393 struct event read_events[] =
395 {NULL, SB_DATA_INITIAL, SB_DATA_NONE},
398 struct event write_read_events[] =
400 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
401 {NULL, SB_DATA_TEST_ALL, SB_DATA_NONE},
404 struct event abort_stateblock_events[] =
406 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
407 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
408 {delete_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
411 struct event apply_stateblock_events[] =
413 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
414 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
415 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
418 struct event capture_reapply_stateblock_events[] =
420 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
421 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
422 {capture_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
423 {apply_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
426 struct event create_stateblock_capture_apply_all_events[] =
428 {create_stateblock_all, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
429 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
430 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
433 struct event create_stateblock_apply_all_events[] =
435 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
436 {create_stateblock_all, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
437 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
440 struct event create_stateblock_capture_apply_vertex_events[] =
442 {create_stateblock_vertex, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
443 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
444 {apply_stateblock, SB_DATA_TEST_VERTEX, SB_DATA_NONE},
447 struct event create_stateblock_apply_vertex_events[] =
449 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
450 {create_stateblock_vertex, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
451 {apply_stateblock, SB_DATA_TEST_VERTEX, SB_DATA_NONE},
454 struct event create_stateblock_capture_apply_pixel_events[] =
456 {create_stateblock_pixel, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
457 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
458 {apply_stateblock, SB_DATA_TEST_PIXEL, SB_DATA_NONE},
461 struct event create_stateblock_apply_pixel_events[] =
463 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
464 {create_stateblock_pixel, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
465 {apply_stateblock, SB_DATA_TEST_PIXEL, SB_DATA_NONE},
468 struct event rendertarget_switch_events[] =
470 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
471 {switch_render_target, SB_DATA_TEST_ALL, SB_DATA_NONE},
472 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
475 struct event rendertarget_stateblock_events[] =
477 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
478 {switch_render_target, SB_DATA_DEFAULT, SB_DATA_NONE},
479 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
480 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
481 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
484 /* Setup each test for execution */
485 for (i = 0; i < ntests; ++i)
487 hr = test[i].init(device, &test[i]);
488 ok(SUCCEEDED(hr), "Test \"%s\" failed setup, aborting\n", test[i].test_name);
489 if (FAILED(hr)) return;
492 trace("Running initial read state tests\n");
493 execute_test_chain(device, test, ntests, read_events, 1, NULL);
495 trace("Running write-read state tests\n");
496 execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
498 trace("Running stateblock abort state tests\n");
499 execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
501 trace("Running stateblock apply state tests\n");
502 execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
504 trace("Running stateblock capture/reapply state tests\n");
505 execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
507 trace("Running create stateblock capture/apply all state tests\n");
508 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_all_events, 3, &arg);
510 trace("Running create stateblock apply all state tests\n");
511 execute_test_chain(device, test, ntests, create_stateblock_apply_all_events, 3, &arg);
513 trace("Running create stateblock capture/apply vertex state tests\n");
514 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_vertex_events, 3, &arg);
516 trace("Running create stateblock apply vertex state tests\n");
517 execute_test_chain(device, test, ntests, create_stateblock_apply_vertex_events, 3, &arg);
519 trace("Running create stateblock capture/apply pixel state tests\n");
520 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_pixel_events, 3, &arg);
522 trace("Running create stateblock apply pixel state tests\n");
523 execute_test_chain(device, test, ntests, create_stateblock_apply_pixel_events, 3, &arg);
525 trace("Running rendertarget switch state tests\n");
526 execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
528 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
529 execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
531 /* Cleanup resources */
532 for (i = 0; i < ntests; ++i)
534 if (test[i].cleanup) test[i].cleanup(device, &test[i]);
538 /* =================== State test: Pixel and Vertex Shader constants ============ */
540 struct shader_constant_data
542 float float_constant[4]; /* 1x4 float constant */
545 struct shader_constant_arg
551 static const struct shader_constant_data shader_constant_poison_data =
553 {1.0f, 2.0f, 3.0f, 4.0f},
556 static const struct shader_constant_data shader_constant_default_data =
558 {0.0f, 0.0f, 0.0f, 0.0f},
561 static const struct shader_constant_data shader_constant_test_data =
563 {5.0f, 6.0f, 7.0f, 8.0f},
566 static void shader_constant_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
568 const struct shader_constant_data *scdata = data;
569 const struct shader_constant_arg *scarg = test->test_arg;
570 unsigned int index = scarg->idx;
575 hr = IDirect3DDevice8_SetVertexShaderConstant(device, index, scdata->float_constant, 1);
576 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
580 hr = IDirect3DDevice8_SetPixelShaderConstant(device, index, scdata->float_constant, 1);
581 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
585 static void shader_constant_check_data(IDirect3DDevice8 *device, const struct state_test *test,
586 const void *expected_data, unsigned int chain_stage)
588 const struct shader_constant_data *scdata = expected_data;
589 const struct shader_constant_arg *scarg = test->test_arg;
590 struct shader_constant_data value;
593 value = shader_constant_poison_data;
597 hr = IDirect3DDevice8_GetVertexShaderConstant(device, scarg->idx, value.float_constant, 1);
598 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
602 hr = IDirect3DDevice8_GetPixelShaderConstant(device, scarg->idx, value.float_constant, 1);
603 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
606 ok(!memcmp(value.float_constant, scdata->float_constant, sizeof(scdata->float_constant)),
607 "Chain stage %u, %s constant:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e, %.8e} received\n",
608 chain_stage, scarg->pshader ? "pixel shader" : "vertex shader",
609 scdata->float_constant[0], scdata->float_constant[1],
610 scdata->float_constant[2], scdata->float_constant[3],
611 value.float_constant[0], value.float_constant[1],
612 value.float_constant[2], value.float_constant[3]);
615 static HRESULT shader_constant_test_init(IDirect3DDevice8 *device, struct state_test *test)
617 const struct shader_constant_arg *test_arg = test->test_arg;
619 test->test_context = NULL;
620 test->test_data_in = &shader_constant_test_data;
621 test->test_data_out_all = &shader_constant_test_data;
622 if (test_arg->pshader)
624 test->test_data_out_vertex = &shader_constant_default_data;
625 test->test_data_out_pixel = &shader_constant_test_data;
629 test->test_data_out_vertex = &shader_constant_test_data;
630 test->test_data_out_pixel = &shader_constant_default_data;
632 test->default_data = &shader_constant_default_data;
633 test->initial_data = &shader_constant_default_data;
638 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
640 test->init = shader_constant_test_init;
641 test->cleanup = NULL;
642 test->apply_data = shader_constant_apply_data;
643 test->check_data = shader_constant_check_data;
644 test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
645 test->test_arg = test_arg;
648 /* =================== State test: Lights ===================================== */
654 HRESULT get_light_result;
655 HRESULT get_enabled_result;
663 static const struct light_data light_poison_data =
667 {7.0, 4.0, 2.0, 1.0},
668 {7.0, 4.0, 2.0, 1.0},
669 {7.0, 4.0, 2.0, 1.0},
672 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
679 static const struct light_data light_default_data =
682 D3DLIGHT_DIRECTIONAL,
683 {1.0, 1.0, 1.0, 0.0},
684 {0.0, 0.0, 0.0, 0.0},
685 {0.0, 0.0, 0.0, 0.0},
688 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
695 /* This is used for the initial read state (before a write causes side effects)
696 * The proper return status is D3DERR_INVALIDCALL */
697 static const struct light_data light_initial_data =
701 {7.0, 4.0, 2.0, 1.0},
702 {7.0, 4.0, 2.0, 1.0},
703 {7.0, 4.0, 2.0, 1.0},
706 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
713 static const struct light_data light_test_data_in =
717 {2.0, 2.0, 2.0, 2.0},
718 {3.0, 3.0, 3.0, 3.0},
719 {4.0, 4.0, 4.0, 4.0},
722 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
729 /* SetLight will use 128 as the "enabled" value */
730 static const struct light_data light_test_data_out =
734 {2.0, 2.0, 2.0, 2.0},
735 {3.0, 3.0, 3.0, 3.0},
736 {4.0, 4.0, 4.0, 4.0},
739 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
746 static void light_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
748 const struct light_data *ldata = data;
749 const struct light_arg *larg = test->test_arg;
750 unsigned int index = larg->idx;
753 hr = IDirect3DDevice8_SetLight(device, index, &ldata->light);
754 ok(SUCCEEDED(hr), "SetLight returned %#x.\n", hr);
756 hr = IDirect3DDevice8_LightEnable(device, index, ldata->enabled);
757 ok(SUCCEEDED(hr), "SetLightEnable returned %#x.\n", hr);
760 static void light_check_data(IDirect3DDevice8 *device, const struct state_test *test,
761 const void *expected_data, unsigned int chain_stage)
763 const struct light_arg *larg = test->test_arg;
764 const struct light_data *ldata = expected_data;
765 struct light_data value;
767 value = light_poison_data;
769 value.get_enabled_result = IDirect3DDevice8_GetLightEnable(device, larg->idx, &value.enabled);
770 value.get_light_result = IDirect3DDevice8_GetLight(device, larg->idx, &value.light);
772 ok(value.get_enabled_result == ldata->get_enabled_result,
773 "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
774 chain_stage, ldata->get_enabled_result, value.get_enabled_result);
775 ok(value.get_light_result == ldata->get_light_result,
776 "Chain stage %u: expected get_light_result %#x, got %#x.\n",
777 chain_stage, ldata->get_light_result, value.get_light_result);
779 ok(value.enabled == ldata->enabled,
780 "Chain stage %u: expected enabled %#x, got %#x.\n",
781 chain_stage, ldata->enabled, value.enabled);
782 ok(value.light.Type == ldata->light.Type,
783 "Chain stage %u: expected light.Type %#x, got %#x.\n",
784 chain_stage, ldata->light.Type, value.light.Type);
785 ok(!memcmp(&value.light.Diffuse, &ldata->light.Diffuse, sizeof(value.light.Diffuse)),
786 "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
787 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
788 ldata->light.Diffuse.r, ldata->light.Diffuse.g,
789 ldata->light.Diffuse.b, ldata->light.Diffuse.a,
790 value.light.Diffuse.r, value.light.Diffuse.g,
791 value.light.Diffuse.b, value.light.Diffuse.a);
792 ok(!memcmp(&value.light.Specular, &ldata->light.Specular, sizeof(value.light.Specular)),
793 "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
794 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
795 ldata->light.Specular.r, ldata->light.Specular.g,
796 ldata->light.Specular.b, ldata->light.Specular.a,
797 value.light.Specular.r, value.light.Specular.g,
798 value.light.Specular.b, value.light.Specular.a);
799 ok(!memcmp(&value.light.Ambient, &ldata->light.Ambient, sizeof(value.light.Ambient)),
800 "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
801 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
802 ldata->light.Ambient.r, ldata->light.Ambient.g,
803 ldata->light.Ambient.b, ldata->light.Ambient.a,
804 value.light.Ambient.r, value.light.Ambient.g,
805 value.light.Ambient.b, value.light.Ambient.a);
806 ok(!memcmp(&value.light.Position, &ldata->light.Position, sizeof(value.light.Position)),
807 "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
808 chain_stage, ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z,
809 value.light.Position.x, value.light.Position.y, value.light.Position.z);
810 ok(!memcmp(&value.light.Direction, &ldata->light.Direction, sizeof(value.light.Direction)),
811 "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
812 chain_stage, ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z,
813 value.light.Direction.x, value.light.Direction.y, value.light.Direction.z);
814 ok(value.light.Range == ldata->light.Range,
815 "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
816 chain_stage, ldata->light.Range, value.light.Range);
817 ok(value.light.Falloff == ldata->light.Falloff,
818 "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
819 chain_stage, ldata->light.Falloff, value.light.Falloff);
820 ok(value.light.Attenuation0 == ldata->light.Attenuation0,
821 "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
822 chain_stage, ldata->light.Attenuation0, value.light.Attenuation0);
823 ok(value.light.Attenuation1 == ldata->light.Attenuation1,
824 "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
825 chain_stage, ldata->light.Attenuation1, value.light.Attenuation1);
826 ok(value.light.Attenuation2 == ldata->light.Attenuation2,
827 "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
828 chain_stage, ldata->light.Attenuation2, value.light.Attenuation2);
829 ok(value.light.Theta == ldata->light.Theta,
830 "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
831 chain_stage, ldata->light.Theta, value.light.Theta);
832 ok(value.light.Phi == ldata->light.Phi,
833 "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
834 chain_stage, ldata->light.Phi, value.light.Phi);
837 static HRESULT light_test_init(IDirect3DDevice8 *device, struct state_test *test)
839 test->test_context = NULL;
840 test->test_data_in = &light_test_data_in;
841 test->test_data_out_all = &light_test_data_out;
842 test->test_data_out_vertex = &light_test_data_out;
843 test->test_data_out_pixel = &light_default_data;
844 test->default_data = &light_default_data;
845 test->initial_data = &light_initial_data;
850 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
852 test->init = light_test_init;
853 test->cleanup = NULL;
854 test->apply_data = light_apply_data;
855 test->check_data = light_check_data;
856 test->test_name = "set_get_light";
857 test->test_arg = test_arg;
860 /* =================== State test: Transforms ===================================== */
862 struct transform_data
865 D3DMATRIX projection;
872 static const struct transform_data transform_default_data =
875 1.0f, 0.0f, 0.0f, 0.0f,
876 0.0f, 1.0f, 0.0f, 0.0f,
877 0.0f, 0.0f, 1.0f, 0.0f,
878 0.0f, 0.0f, 0.0f, 1.0f,
881 1.0f, 0.0f, 0.0f, 0.0f,
882 0.0f, 1.0f, 0.0f, 0.0f,
883 0.0f, 0.0f, 1.0f, 0.0f,
884 0.0f, 0.0f, 0.0f, 1.0f,
887 1.0f, 0.0f, 0.0f, 0.0f,
888 0.0f, 1.0f, 0.0f, 0.0f,
889 0.0f, 0.0f, 1.0f, 0.0f,
890 0.0f, 0.0f, 0.0f, 1.0f,
893 1.0f, 0.0f, 0.0f, 0.0f,
894 0.0f, 1.0f, 0.0f, 0.0f,
895 0.0f, 0.0f, 1.0f, 0.0f,
896 0.0f, 0.0f, 0.0f, 1.0f,
899 1.0f, 0.0f, 0.0f, 0.0f,
900 0.0f, 1.0f, 0.0f, 0.0f,
901 0.0f, 0.0f, 1.0f, 0.0f,
902 0.0f, 0.0f, 0.0f, 1.0f,
905 1.0f, 0.0f, 0.0f, 0.0f,
906 0.0f, 1.0f, 0.0f, 0.0f,
907 0.0f, 0.0f, 1.0f, 0.0f,
908 0.0f, 0.0f, 0.0f, 1.0f,
912 static const struct transform_data transform_poison_data =
915 1.0f, 2.0f, 3.0f, 4.0f,
916 5.0f, 6.0f, 7.0f, 8.0f,
917 9.0f, 10.0f, 11.0f, 12.0f,
918 13.0f, 14.0f, 15.0f, 16.0f,
921 17.0f, 18.0f, 19.0f, 20.0f,
922 21.0f, 22.0f, 23.0f, 24.0f,
923 25.0f, 26.0f, 27.0f, 28.0f,
924 29.0f, 30.0f, 31.0f, 32.0f,
927 33.0f, 34.0f, 35.0f, 36.0f,
928 37.0f, 38.0f, 39.0f, 40.0f,
929 41.0f, 42.0f, 43.0f, 44.0f,
930 45.0f, 46.0f, 47.0f, 48.0f,
933 49.0f, 50.0f, 51.0f, 52.0f,
934 53.0f, 54.0f, 55.0f, 56.0f,
935 57.0f, 58.0f, 59.0f, 60.0f,
936 61.0f, 62.0f, 63.0f, 64.0f,
939 64.0f, 66.0f, 67.0f, 68.0f,
940 69.0f, 70.0f, 71.0f, 72.0f,
941 73.0f, 74.0f, 75.0f, 76.0f,
942 77.0f, 78.0f, 79.0f, 80.0f,
945 81.0f, 82.0f, 83.0f, 84.0f,
946 85.0f, 86.0f, 87.0f, 88.0f,
947 89.0f, 90.0f, 91.0f, 92.0f,
948 93.0f, 94.0f, 95.0f, 96.0f,
952 static const struct transform_data transform_test_data =
955 1.2f, 3.4f, -5.6f, 7.2f,
956 10.11f, -12.13f, 14.15f, -1.5f,
957 23.56f, 12.89f, 44.56f, -1.0f,
958 2.3f, 0.0f, 4.4f, 5.5f,
961 9.2f, 38.7f, -6.6f, 7.2f,
962 10.11f, -12.13f, 77.15f, -1.5f,
963 23.56f, 12.89f, 14.56f, -1.0f,
964 12.3f, 0.0f, 4.4f, 5.5f,
967 10.2f, 3.4f, 0.6f, 7.2f,
968 10.11f, -12.13f, 14.15f, -1.5f,
969 23.54f, 12.9f, 44.56f, -1.0f,
970 2.3f, 0.0f, 4.4f, 5.5f,
973 1.2f, 3.4f, -5.6f, 7.2f,
974 10.11f, -12.13f, -14.5f, -1.5f,
975 2.56f, 12.89f, 23.56f, -1.0f,
976 112.3f, 0.0f, 4.4f, 2.5f,
979 1.2f, 31.41f, 58.6f, 7.2f,
980 10.11f, -12.13f, -14.5f, -1.5f,
981 2.56f, 12.89f, 11.56f, -1.0f,
982 112.3f, 0.0f, 44.4f, 2.5f,
986 1.20f, 3.4f, -5.6f, 7.0f,
987 10.11f, -12.156f, -14.5f, -1.5f,
988 2.56f, 1.829f, 23.6f, -1.0f,
989 112.3f, 0.0f, 41.4f, 2.5f,
994 static void transform_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
996 const struct transform_data *tdata = data;
999 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &tdata->view);
1000 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
1002 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
1003 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
1005 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
1006 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
1008 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
1009 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
1011 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &tdata->world0);
1012 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
1014 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
1015 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
1018 static void compare_matrix(const char *name, unsigned int chain_stage,
1019 const D3DMATRIX *received, const D3DMATRIX *expected)
1021 ok(!memcmp(expected, received, sizeof(*expected)),
1022 "Chain stage %u, matrix %s:\n"
1024 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1025 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1026 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1027 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1030 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1031 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1032 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1033 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1036 U(*expected).m[0][0], U(*expected).m[1][0], U(*expected).m[2][0], U(*expected).m[3][0],
1037 U(*expected).m[0][1], U(*expected).m[1][1], U(*expected).m[2][1], U(*expected).m[3][1],
1038 U(*expected).m[0][2], U(*expected).m[1][2], U(*expected).m[2][2], U(*expected).m[3][2],
1039 U(*expected).m[0][3], U(*expected).m[1][3], U(*expected).m[2][3], U(*expected).m[3][3],
1040 U(*received).m[0][0], U(*received).m[1][0], U(*received).m[2][0], U(*received).m[3][0],
1041 U(*received).m[0][1], U(*received).m[1][1], U(*received).m[2][1], U(*received).m[3][1],
1042 U(*received).m[0][2], U(*received).m[1][2], U(*received).m[2][2], U(*received).m[3][2],
1043 U(*received).m[0][3], U(*received).m[1][3], U(*received).m[2][3], U(*received).m[3][3]);
1046 static void transform_check_data(IDirect3DDevice8 *device, const struct state_test *test,
1047 const void *expected_data, unsigned int chain_stage)
1049 const struct transform_data *tdata = expected_data;
1053 value = transform_poison_data.view;
1054 hr = IDirect3DDevice8_GetTransform(device, D3DTS_VIEW, &value);
1055 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1056 compare_matrix("View", chain_stage, &value, &tdata->view);
1058 value = transform_poison_data.projection;
1059 hr = IDirect3DDevice8_GetTransform(device, D3DTS_PROJECTION, &value);
1060 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1061 compare_matrix("Projection", chain_stage, &value, &tdata->projection);
1063 value = transform_poison_data.texture0;
1064 hr = IDirect3DDevice8_GetTransform(device, D3DTS_TEXTURE0, &value);
1065 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1066 compare_matrix("Texture0", chain_stage, &value, &tdata->texture0);
1068 value = transform_poison_data.texture7;
1069 hr = IDirect3DDevice8_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &value);
1070 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1071 compare_matrix("Texture7", chain_stage, &value, &tdata->texture7);
1073 value = transform_poison_data.world0;
1074 hr = IDirect3DDevice8_GetTransform(device, D3DTS_WORLD, &value);
1075 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1076 compare_matrix("World0", chain_stage, &value, &tdata->world0);
1078 value = transform_poison_data.world255;
1079 hr = IDirect3DDevice8_GetTransform(device, D3DTS_WORLDMATRIX(255), &value);
1080 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1081 compare_matrix("World255", chain_stage, &value, &tdata->world255);
1084 static HRESULT transform_test_init(IDirect3DDevice8 *device, struct state_test *test)
1086 test->test_context = NULL;
1087 test->test_data_in = &transform_test_data;
1088 test->test_data_out_all = &transform_test_data;
1089 test->test_data_out_vertex = &transform_default_data;
1090 test->test_data_out_pixel = &transform_default_data;
1091 test->default_data = &transform_default_data;
1092 test->initial_data = &transform_default_data;
1097 static void transform_queue_test(struct state_test *test)
1099 test->init = transform_test_init;
1100 test->cleanup = NULL;
1101 test->apply_data = transform_apply_data;
1102 test->check_data = transform_check_data;
1103 test->test_name = "set_get_transforms";
1104 test->test_arg = NULL;
1107 /* =================== State test: Render States ===================================== */
1109 const D3DRENDERSTATETYPE render_state_indices[] =
1115 D3DRS_ALPHATESTENABLE,
1124 D3DRS_ALPHABLENDENABLE,
1126 D3DRS_SPECULARENABLE,
1132 D3DRS_RANGEFOGENABLE,
1133 D3DRS_STENCILENABLE,
1140 D3DRS_STENCILWRITEMASK,
1141 D3DRS_TEXTUREFACTOR,
1153 D3DRS_FOGVERTEXMODE,
1156 D3DRS_NORMALIZENORMALS,
1157 D3DRS_DIFFUSEMATERIALSOURCE,
1158 D3DRS_SPECULARMATERIALSOURCE,
1159 D3DRS_AMBIENTMATERIALSOURCE,
1160 D3DRS_EMISSIVEMATERIALSOURCE,
1162 D3DRS_CLIPPLANEENABLE,
1163 #if 0 /* Driver dependent */
1166 D3DRS_POINTSIZE_MIN,
1167 D3DRS_POINTSPRITEENABLE,
1168 D3DRS_POINTSCALEENABLE,
1172 D3DRS_MULTISAMPLEANTIALIAS,
1173 D3DRS_MULTISAMPLEMASK,
1174 D3DRS_PATCHEDGESTYLE,
1175 #if 0 /* Apparently not recorded in the stateblock */
1176 D3DRS_DEBUGMONITORTOKEN,
1178 D3DRS_POINTSIZE_MAX,
1179 D3DRS_INDEXEDVERTEXBLENDENABLE,
1180 D3DRS_COLORWRITEENABLE,
1185 struct render_state_data
1187 DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1190 struct render_state_arg
1192 D3DPRESENT_PARAMETERS *device_pparams;
1193 float pointsize_max;
1196 struct render_state_context
1198 struct render_state_data default_data_buffer;
1199 struct render_state_data test_data_all_buffer;
1200 struct render_state_data test_data_vertex_buffer;
1201 struct render_state_data test_data_pixel_buffer;
1202 struct render_state_data poison_data_buffer;
1205 static void render_state_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
1207 const struct render_state_data *rsdata = data;
1211 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1213 hr = IDirect3DDevice8_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1214 ok(SUCCEEDED(hr), "SetRenderState returned %#x.\n", hr);
1218 static void render_state_check_data(IDirect3DDevice8 *device, const struct state_test *test,
1219 const void *expected_data, unsigned int chain_stage)
1221 const struct render_state_context *ctx = test->test_context;
1222 const struct render_state_data *rsdata = expected_data;
1226 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1228 DWORD value = ctx->poison_data_buffer.states[i];
1229 hr = IDirect3DDevice8_GetRenderState(device, render_state_indices[i], &value);
1230 ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1231 ok(value == rsdata->states[i], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1232 chain_stage, render_state_indices[i], rsdata->states[i], value);
1236 static inline DWORD to_dword(float fl)
1238 union {float f; DWORD d;} ret;
1244 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1246 DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1247 unsigned int idx = 0;
1249 data->states[idx++] = zenable; /* ZENABLE */
1250 data->states[idx++] = D3DFILL_SOLID; /* FILLMODE */
1251 data->states[idx++] = D3DSHADE_GOURAUD; /* SHADEMODE */
1252 data->states[idx++] = TRUE; /* ZWRITEENABLE */
1253 data->states[idx++] = FALSE; /* ALPHATESTENABLE */
1254 data->states[idx++] = TRUE; /* LASTPIXEL */
1255 data->states[idx++] = D3DBLEND_ONE; /* SRCBLEND */
1256 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLEND */
1257 data->states[idx++] = D3DCULL_CCW; /* CULLMODE */
1258 data->states[idx++] = D3DCMP_LESSEQUAL; /* ZFUNC */
1259 data->states[idx++] = 0; /* ALPHAREF */
1260 data->states[idx++] = D3DCMP_ALWAYS; /* ALPHAFUNC */
1261 data->states[idx++] = FALSE; /* DITHERENABLE */
1262 data->states[idx++] = FALSE; /* ALPHABLENDENABLE */
1263 data->states[idx++] = FALSE; /* FOGENABLE */
1264 data->states[idx++] = FALSE; /* SPECULARENABLE */
1265 data->states[idx++] = 0; /* FOGCOLOR */
1266 data->states[idx++] = D3DFOG_NONE; /* FOGTABLEMODE */
1267 data->states[idx++] = to_dword(0.0f); /* FOGSTART */
1268 data->states[idx++] = to_dword(1.0f); /* FOGEND */
1269 data->states[idx++] = to_dword(1.0f); /* FOGDENSITY */
1270 data->states[idx++] = FALSE; /* RANGEFOGENABLE */
1271 data->states[idx++] = FALSE; /* STENCILENABLE */
1272 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILFAIL */
1273 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILZFAIL */
1274 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILPASS */
1275 data->states[idx++] = D3DCMP_ALWAYS; /* STENCILFUNC */
1276 data->states[idx++] = 0; /* STENCILREF */
1277 data->states[idx++] = 0xFFFFFFFF; /* STENCILMASK */
1278 data->states[idx++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1279 data->states[idx++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1280 data->states[idx++] = 0; /* WRAP 0 */
1281 data->states[idx++] = 0; /* WRAP 1 */
1282 data->states[idx++] = 0; /* WRAP 2 */
1283 data->states[idx++] = 0; /* WRAP 3 */
1284 data->states[idx++] = 0; /* WRAP 4 */
1285 data->states[idx++] = 0; /* WRAP 5 */
1286 data->states[idx++] = 0; /* WRAP 6 */
1287 data->states[idx++] = 0; /* WRAP 7 */
1288 data->states[idx++] = TRUE; /* CLIPPING */
1289 data->states[idx++] = TRUE; /* LIGHTING */
1290 data->states[idx++] = 0; /* AMBIENT */
1291 data->states[idx++] = D3DFOG_NONE; /* FOGVERTEXMODE */
1292 data->states[idx++] = TRUE; /* COLORVERTEX */
1293 data->states[idx++] = TRUE; /* LOCALVIEWER */
1294 data->states[idx++] = FALSE; /* NORMALIZENORMALS */
1295 data->states[idx++] = D3DMCS_COLOR1; /* DIFFUSEMATERIALSOURCE */
1296 data->states[idx++] = D3DMCS_COLOR2; /* SPECULARMATERIALSOURCE */
1297 data->states[idx++] = D3DMCS_MATERIAL; /* AMBIENTMATERIALSOURCE */
1298 data->states[idx++] = D3DMCS_MATERIAL; /* EMISSIVEMATERIALSOURCE */
1299 data->states[idx++] = D3DVBF_DISABLE; /* VERTEXBLEND */
1300 data->states[idx++] = 0; /* CLIPPLANEENABLE */
1301 if (0) data->states[idx++] = to_dword(1.0f); /* POINTSIZE, driver dependent, increase array size to enable */
1302 data->states[idx++] = to_dword(0.0f); /* POINTSIZEMIN */
1303 data->states[idx++] = FALSE; /* POINTSPRITEENABLE */
1304 data->states[idx++] = FALSE; /* POINTSCALEENABLE */
1305 data->states[idx++] = to_dword(1.0f); /* POINTSCALE_A */
1306 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_B */
1307 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_C */
1308 data->states[idx++] = TRUE; /* MULTISAMPLEANTIALIAS */
1309 data->states[idx++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1310 data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1311 if (0) data->states[idx++] = 0xbaadcafe; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1312 data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1313 data->states[idx++] = FALSE; /* INDEXEDVERTEXBLENDENABLE */
1314 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE */
1315 data->states[idx++] = to_dword(0.0f); /* TWEENFACTOR */
1316 data->states[idx++] = D3DBLENDOP_ADD; /* BLENDOP */
1319 static void render_state_poison_data_init(struct render_state_data *data)
1323 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1325 data->states[i] = 0x1337c0de;
1329 static void render_state_test_data_init(struct render_state_data *data)
1331 unsigned int idx = 0;
1333 data->states[idx++] = D3DZB_USEW; /* ZENABLE */
1334 data->states[idx++] = D3DFILL_WIREFRAME; /* FILLMODE */
1335 data->states[idx++] = D3DSHADE_PHONG; /* SHADEMODE */
1336 data->states[idx++] = FALSE; /* ZWRITEENABLE */
1337 data->states[idx++] = TRUE; /* ALPHATESTENABLE */
1338 data->states[idx++] = FALSE; /* LASTPIXEL */
1339 data->states[idx++] = D3DBLEND_SRCALPHASAT; /* SRCBLEND */
1340 data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1341 data->states[idx++] = D3DCULL_CW; /* CULLMODE */
1342 data->states[idx++] = D3DCMP_NOTEQUAL; /* ZFUNC */
1343 data->states[idx++] = 10; /* ALPHAREF */
1344 data->states[idx++] = D3DCMP_GREATER; /* ALPHAFUNC */
1345 data->states[idx++] = TRUE; /* DITHERENABLE */
1346 data->states[idx++] = TRUE; /* ALPHABLENDENABLE */
1347 data->states[idx++] = TRUE; /* FOGENABLE */
1348 data->states[idx++] = TRUE; /* SPECULARENABLE */
1349 data->states[idx++] = 1 << 31; /* FOGCOLOR */
1350 data->states[idx++] = D3DFOG_EXP; /* FOGTABLEMODE */
1351 data->states[idx++] = to_dword(0.1f); /* FOGSTART */
1352 data->states[idx++] = to_dword(0.8f); /* FOGEND */
1353 data->states[idx++] = to_dword(0.5f); /* FOGDENSITY */
1354 data->states[idx++] = TRUE; /* RANGEFOGENABLE */
1355 data->states[idx++] = TRUE; /* STENCILENABLE */
1356 data->states[idx++] = D3DSTENCILOP_INCRSAT; /* STENCILFAIL */
1357 data->states[idx++] = D3DSTENCILOP_REPLACE; /* STENCILZFAIL */
1358 data->states[idx++] = D3DSTENCILOP_INVERT; /* STENCILPASS */
1359 data->states[idx++] = D3DCMP_LESS; /* STENCILFUNC */
1360 data->states[idx++] = 10; /* STENCILREF */
1361 data->states[idx++] = 0xFF00FF00; /* STENCILMASK */
1362 data->states[idx++] = 0x00FF00FF; /* STENCILWRITEMASK */
1363 data->states[idx++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1364 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 0 */
1365 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 1 */
1366 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 2 */
1367 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 4 */
1368 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 5 */
1369 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 6 */
1370 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 7 */
1371 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1372 data->states[idx++] = FALSE; /* CLIPPING */
1373 data->states[idx++] = FALSE; /* LIGHTING */
1374 data->states[idx++] = 255 << 16; /* AMBIENT */
1375 data->states[idx++] = D3DFOG_EXP2; /* FOGVERTEXMODE */
1376 data->states[idx++] = FALSE; /* COLORVERTEX */
1377 data->states[idx++] = FALSE; /* LOCALVIEWER */
1378 data->states[idx++] = TRUE; /* NORMALIZENORMALS */
1379 data->states[idx++] = D3DMCS_COLOR2; /* DIFFUSEMATERIALSOURCE */
1380 data->states[idx++] = D3DMCS_MATERIAL; /* SPECULARMATERIALSOURCE */
1381 data->states[idx++] = D3DMCS_COLOR1; /* AMBIENTMATERIALSOURCE */
1382 data->states[idx++] = D3DMCS_COLOR2; /* EMISSIVEMATERIALSOURCE */
1383 data->states[idx++] = D3DVBF_3WEIGHTS; /* VERTEXBLEND */
1384 data->states[idx++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1385 if (0) data->states[idx++] = to_dword(32.0f);/* POINTSIZE, driver dependent, increase array size to enable */
1386 data->states[idx++] = to_dword(0.7f); /* POINTSIZEMIN */
1387 data->states[idx++] = TRUE; /* POINTSPRITEENABLE */
1388 data->states[idx++] = TRUE; /* POINTSCALEENABLE */
1389 data->states[idx++] = to_dword(0.7f); /* POINTSCALE_A */
1390 data->states[idx++] = to_dword(0.5f); /* POINTSCALE_B */
1391 data->states[idx++] = to_dword(0.4f); /* POINTSCALE_C */
1392 data->states[idx++] = FALSE; /* MULTISAMPLEANTIALIAS */
1393 data->states[idx++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1394 data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1395 if (0) data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1396 data->states[idx++] = to_dword(77.0f); /* POINTSIZE_MAX */
1397 data->states[idx++] = TRUE; /* INDEXEDVERTEXBLENDENABLE */
1398 data->states[idx++] = 0x00000009; /* COLORWRITEENABLE */
1399 data->states[idx++] = to_dword(0.2f); /* TWEENFACTOR */
1400 data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1403 static HRESULT render_state_test_init(IDirect3DDevice8 *device, struct state_test *test)
1405 static const DWORD states_vertex[] =
1408 D3DRS_AMBIENTMATERIALSOURCE,
1410 D3DRS_CLIPPLANEENABLE,
1413 D3DRS_DIFFUSEMATERIALSOURCE,
1414 D3DRS_EMISSIVEMATERIALSOURCE,
1421 D3DRS_FOGVERTEXMODE,
1422 D3DRS_INDEXEDVERTEXBLENDENABLE,
1425 D3DRS_MULTISAMPLEANTIALIAS,
1426 D3DRS_MULTISAMPLEMASK,
1427 D3DRS_NORMALIZENORMALS,
1428 D3DRS_PATCHEDGESTYLE,
1432 D3DRS_POINTSCALEENABLE,
1434 D3DRS_POINTSIZE_MAX,
1435 D3DRS_POINTSIZE_MIN,
1436 D3DRS_POINTSPRITEENABLE,
1437 D3DRS_RANGEFOGENABLE,
1439 D3DRS_SPECULARENABLE,
1440 D3DRS_SPECULARMATERIALSOURCE,
1445 static const DWORD states_pixel[] =
1447 D3DRS_ALPHABLENDENABLE,
1450 D3DRS_ALPHATESTENABLE,
1452 D3DRS_COLORWRITEENABLE,
1462 D3DRS_STENCILENABLE,
1468 D3DRS_STENCILWRITEMASK,
1470 D3DRS_TEXTUREFACTOR,
1484 const struct render_state_arg *rsarg = test->test_arg;
1487 struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1488 if (!ctx) return E_FAIL;
1489 test->test_context = ctx;
1491 test->default_data = &ctx->default_data_buffer;
1492 test->initial_data = &ctx->default_data_buffer;
1493 test->test_data_in = &ctx->test_data_all_buffer;
1494 test->test_data_out_all = &ctx->test_data_all_buffer;
1495 test->test_data_out_vertex = &ctx->test_data_vertex_buffer;
1496 test->test_data_out_pixel = &ctx->test_data_pixel_buffer;
1498 render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1499 render_state_test_data_init(&ctx->test_data_all_buffer);
1500 render_state_poison_data_init(&ctx->poison_data_buffer);
1502 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1504 ctx->test_data_vertex_buffer.states[i] = ctx->default_data_buffer.states[i];
1505 for (j = 0; j < sizeof(states_vertex) / sizeof(*states_vertex); ++j)
1507 if (render_state_indices[i] == states_vertex[j])
1509 ctx->test_data_vertex_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1514 ctx->test_data_pixel_buffer.states[i] = ctx->default_data_buffer.states[i];
1515 for (j = 0; j < sizeof(states_pixel) / sizeof(*states_pixel); ++j)
1517 if (render_state_indices[i] == states_pixel[j])
1519 ctx->test_data_pixel_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1528 static void render_state_test_cleanup(IDirect3DDevice8 *device, struct state_test *test)
1530 HeapFree(GetProcessHeap(), 0, test->test_context);
1533 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1535 test->init = render_state_test_init;
1536 test->cleanup = render_state_test_cleanup;
1537 test->apply_data = render_state_apply_data;
1538 test->check_data = render_state_check_data;
1539 test->test_name = "set_get_render_states";
1540 test->test_arg = test_arg;
1543 /* resource tests */
1545 struct resource_test_arg
1553 struct resource_test_data
1557 IDirect3DIndexBuffer8 *ib;
1558 IDirect3DVertexBuffer8 **vb;
1559 IDirect3DTexture8 **tex;
1562 struct resource_test_context
1564 struct resource_test_data default_data;
1565 struct resource_test_data test_data_all;
1566 struct resource_test_data test_data_vertex;
1567 struct resource_test_data test_data_pixel;
1568 struct resource_test_data poison_data;
1571 static void resource_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
1573 const struct resource_test_arg *arg = test->test_arg;
1574 const struct resource_test_data *d = data;
1578 hr = IDirect3DDevice8_SetVertexShader(device, d->vs);
1579 ok(SUCCEEDED(hr), "SetVertexShader (%u) returned %#x.\n", d->vs, hr);
1581 hr = IDirect3DDevice8_SetPixelShader(device, d->ps);
1582 ok(SUCCEEDED(hr), "SetPixelShader (%u) returned %#x.\n", d->ps, hr);
1584 hr = IDirect3DDevice8_SetIndices(device, d->ib, 0);
1585 ok(SUCCEEDED(hr), "SetIndices (%p) returned %#x.\n", d->ib, hr);
1587 for (i = 0; i < arg->stream_count; ++i)
1589 hr = IDirect3DDevice8_SetStreamSource(device, i, d->vb[i], 64);
1590 ok(SUCCEEDED(hr), "SetStreamSource (%u, %p, 64) returned %#x.\n",
1594 for (i = 0; i < arg->tex_count; ++i)
1596 hr = IDirect3DDevice8_SetTexture(device, i, (IDirect3DBaseTexture8 *)d->tex[i]);
1597 ok(SUCCEEDED(hr), "SetTexture (%u, %p) returned %#x.\n", i, d->tex[i], hr);
1601 static void resource_check_data(IDirect3DDevice8 *device, const struct state_test *test,
1602 const void *expected_data, unsigned int chain_stage)
1604 const struct resource_test_context *ctx = test->test_context;
1605 const struct resource_test_data *poison = &ctx->poison_data;
1606 const struct resource_test_arg *arg = test->test_arg;
1607 const struct resource_test_data *d = expected_data;
1614 hr = IDirect3DDevice8_GetVertexShader(device, &v);
1615 ok(SUCCEEDED(hr), "GetVertexShader returned %#x.\n", hr);
1616 ok(v == d->vs, "Chain stage %u, expected vertex shader %#x, received %#x.\n",
1617 chain_stage, d->vs, v);
1620 hr = IDirect3DDevice8_GetPixelShader(device, &v);
1621 ok(SUCCEEDED(hr), "GetPixelShader returned %#x.\n", hr);
1622 ok(v == d->ps, "Chain stage %u, expected pixel shader %#x, received %#x.\n",
1623 chain_stage, d->ps, v);
1626 hr = IDirect3DDevice8_GetIndices(device, (IDirect3DIndexBuffer8 **)&ptr, &v);
1627 ok(SUCCEEDED(hr), "GetIndices returned %#x.\n", hr);
1628 ok(ptr == d->ib, "Chain stage %u, expected index buffer %p, received %p.\n",
1629 chain_stage, d->ib, ptr);
1630 if (SUCCEEDED(hr) && ptr)
1632 IDirect3DIndexBuffer8_Release((IDirect3DIndexBuffer8 *)ptr);
1635 for (i = 0; i < arg->stream_count; ++i)
1637 ptr = poison->vb[i];
1638 hr = IDirect3DDevice8_GetStreamSource(device, i, (IDirect3DVertexBuffer8 **)&ptr, &v);
1639 ok(SUCCEEDED(hr), "GetStreamSource (%u) returned %#x.\n", i, hr);
1640 ok(ptr == d->vb[i], "Chain stage %u, stream %u, expected vertex buffer %p, received %p.\n",
1641 chain_stage, i, d->vb[i], ptr);
1642 if (SUCCEEDED(hr) && ptr)
1644 IDirect3DIndexBuffer8_Release((IDirect3DVertexBuffer8 *)ptr);
1648 for (i = 0; i < arg->tex_count; ++i)
1650 ptr = poison->tex[i];
1651 hr = IDirect3DDevice8_GetTexture(device, i, (IDirect3DBaseTexture8 **)&ptr);
1652 ok(SUCCEEDED(hr), "SetTexture (%u) returned %#x.\n", i, hr);
1653 ok(ptr == d->tex[i], "Chain stage %u, texture stage %u, expected texture %p, received %p.\n",
1654 chain_stage, i, d->tex[i], ptr);
1655 if (SUCCEEDED(hr) && ptr)
1657 IDirect3DBaseTexture8_Release((IDirect3DBaseTexture8 *)ptr);
1662 static void resource_default_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1669 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1670 for (i = 0; i < arg->stream_count; ++i)
1674 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1675 for (i = 0; i < arg->tex_count; ++i)
1677 data->tex[i] = NULL;
1681 static void resource_test_data_init(IDirect3DDevice8 *device,
1682 struct resource_test_data *data, const struct resource_test_arg *arg)
1684 static const DWORD vs_code[] =
1686 0xfffe0101, /* vs_1_1 */
1687 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
1688 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
1689 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
1690 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
1691 0x0000ffff, /* END */
1693 static const DWORD ps_code[] =
1695 0xffff0101, /* ps_1_1 */
1696 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
1697 0x00000042, 0xb00f0000, /* tex t0 */
1698 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
1699 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
1700 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
1701 0x0000ffff, /* END */
1703 static const DWORD decl[] =
1706 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
1707 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
1714 if (arg->vs_version)
1716 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &data->vs, 0);
1717 ok(SUCCEEDED(hr), "CreateVertexShader returned hr %#x.\n", hr);
1720 if (arg->ps_version)
1722 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &data->ps);
1723 ok(SUCCEEDED(hr), "CreatePixelShader returned hr %#x.\n", hr);
1726 hr = IDirect3DDevice8_CreateIndexBuffer(device, 64, D3DUSAGE_DYNAMIC, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &data->ib);
1727 ok(SUCCEEDED(hr), "CreateIndexBuffer returned hr %#x.\n", hr);
1729 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1730 for (i = 0; i < arg->stream_count; ++i)
1732 hr = IDirect3DDevice8_CreateVertexBuffer(device, 64, D3DUSAGE_DYNAMIC,
1733 0, D3DPOOL_DEFAULT, &data->vb[i]);
1734 ok(SUCCEEDED(hr), "CreateVertexBuffer (%u) returned hr %#x.\n", i, hr);
1737 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1738 for (i = 0; i < arg->tex_count; ++i)
1740 hr = IDirect3DDevice8_CreateTexture(device, 64, 64, 0, 0,
1741 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &data->tex[i]);
1742 ok(SUCCEEDED(hr), "CreateTexture (%u) returned hr %#x.\n", i, hr);
1746 static void resource_poison_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1748 DWORD_PTR poison = 0xdeadbeef;
1751 data->vs = poison++;
1752 data->ps = poison++;
1753 data->ib = (IDirect3DIndexBuffer8 *)poison++;
1754 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1755 for (i = 0; i < arg->stream_count; ++i)
1757 data->vb[i] = (IDirect3DVertexBuffer8 *)poison++;
1759 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1760 for (i = 0; i < arg->tex_count; ++i)
1762 data->tex[i] = (IDirect3DTexture8 *)poison++;
1766 static HRESULT resource_test_init(IDirect3DDevice8 *device, struct state_test *test)
1768 const struct resource_test_arg *arg = test->test_arg;
1769 struct resource_test_context *ctx;
1771 ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1772 if (!ctx) return E_OUTOFMEMORY;
1774 test->test_context = ctx;
1775 test->test_data_in = &ctx->test_data_all;
1776 test->test_data_out_all = &ctx->test_data_all;
1777 test->test_data_out_vertex = &ctx->test_data_vertex;
1778 test->test_data_out_pixel = &ctx->test_data_pixel;
1779 test->default_data = &ctx->default_data;
1780 test->initial_data = &ctx->default_data;
1782 resource_default_data_init(&ctx->default_data, arg);
1783 resource_test_data_init(device, &ctx->test_data_all, arg);
1784 resource_default_data_init(&ctx->test_data_vertex, arg);
1785 resource_default_data_init(&ctx->test_data_pixel, arg);
1786 resource_poison_data_init(&ctx->poison_data, arg);
1788 ctx->test_data_vertex.vs = ctx->test_data_all.vs;
1789 ctx->test_data_pixel.ps = ctx->test_data_all.ps;
1794 static void resource_test_cleanup(IDirect3DDevice8 *device, struct state_test *test)
1796 struct resource_test_context *ctx = test->test_context;
1797 const struct resource_test_arg *arg = test->test_arg;
1801 resource_apply_data(device, test, &ctx->default_data);
1803 if (ctx->test_data_all.vs)
1805 hr = IDirect3DDevice8_DeleteVertexShader(device, ctx->test_data_all.vs);
1806 ok(SUCCEEDED(hr), "DeleteVertexShader (%u) returned %#x.\n", ctx->test_data_all.vs, hr);
1809 if (ctx->test_data_all.ps)
1811 hr = IDirect3DDevice8_DeletePixelShader(device, ctx->test_data_all.ps);
1812 ok(SUCCEEDED(hr), "DeletePixelShader (%u) returned %#x.\n", ctx->test_data_all.ps, hr);
1815 IDirect3DIndexBuffer8_Release(ctx->test_data_all.ib);
1816 for (i = 0; i < arg->stream_count; ++i)
1818 IDirect3DVertexBuffer8_Release(ctx->test_data_all.vb[i]);
1821 for (i = 0; i < arg->tex_count; ++i)
1823 IDirect3DBaseTexture8_Release(ctx->test_data_all.tex[i]);
1826 HeapFree(GetProcessHeap(), 0, ctx->default_data.vb);
1827 HeapFree(GetProcessHeap(), 0, ctx->default_data.tex);
1828 HeapFree(GetProcessHeap(), 0, ctx->test_data_all.vb);
1829 HeapFree(GetProcessHeap(), 0, ctx->test_data_all.tex);
1830 HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.vb);
1831 HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.tex);
1832 HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.vb);
1833 HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.tex);
1834 HeapFree(GetProcessHeap(), 0, ctx->poison_data.vb);
1835 HeapFree(GetProcessHeap(), 0, ctx->poison_data.tex);
1836 HeapFree(GetProcessHeap(), 0, ctx);
1839 static void resource_test_queue(struct state_test *test, const struct resource_test_arg *test_arg)
1841 test->init = resource_test_init;
1842 test->cleanup = resource_test_cleanup;
1843 test->apply_data = resource_apply_data;
1844 test->check_data = resource_check_data;
1845 test->test_name = "set_get_resources";
1846 test->test_arg = test_arg;
1849 /* =================== Main state tests function =============================== */
1851 static void test_state_management(IDirect3DDevice8 *device, D3DPRESENT_PARAMETERS *device_pparams)
1856 /* Test count: 2 for shader constants
1859 * 1 for render states
1862 struct state_test tests[6];
1863 unsigned int tcount = 0;
1865 struct shader_constant_arg pshader_constant_arg;
1866 struct shader_constant_arg vshader_constant_arg;
1867 struct resource_test_arg resource_test_arg;
1868 struct render_state_arg render_state_arg;
1869 struct light_arg light_arg;
1871 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1872 ok(SUCCEEDED(hr), "GetDeviceCaps returned %#x.\n", hr);
1873 if (FAILED(hr)) return;
1875 texture_stages = caps.MaxTextureBlendStages;
1877 /* Zero test memory */
1878 memset(tests, 0, sizeof(tests));
1880 if (caps.VertexShaderVersion & 0xffff)
1882 vshader_constant_arg.idx = 0;
1883 vshader_constant_arg.pshader = FALSE;
1884 shader_constants_queue_test(&tests[tcount++], &vshader_constant_arg);
1887 if (caps.PixelShaderVersion & 0xffff)
1889 pshader_constant_arg.idx = 0;
1890 pshader_constant_arg.pshader = TRUE;
1891 shader_constants_queue_test(&tests[tcount++], &pshader_constant_arg);
1895 lights_queue_test(&tests[tcount++], &light_arg);
1897 transform_queue_test(&tests[tcount++]);
1899 render_state_arg.device_pparams = device_pparams;
1900 render_state_arg.pointsize_max = caps.MaxPointSize;
1901 render_states_queue_test(&tests[tcount++], &render_state_arg);
1903 resource_test_arg.vs_version = caps.VertexShaderVersion & 0xffff;
1904 resource_test_arg.ps_version = caps.PixelShaderVersion & 0xffff;
1905 resource_test_arg.stream_count = caps.MaxStreams;
1906 resource_test_arg.tex_count = caps.MaxTextureBlendStages;
1907 resource_test_queue(&tests[tcount++], &resource_test_arg);
1909 execute_test_chain_all(device, tests, tcount);
1912 static void test_shader_constant_apply(IDirect3DDevice8 *device)
1914 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
1915 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
1916 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
1917 DWORD vs_version, ps_version;
1923 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1924 ok(SUCCEEDED(hr), "GetDeviceCaps returned %#x.\n", hr);
1925 vs_version = caps.VertexShaderVersion & 0xffff;
1926 ps_version = caps.PixelShaderVersion & 0xffff;
1930 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, initial, 1);
1931 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
1932 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 1, initial, 1);
1933 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
1935 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 0, ret, 1);
1936 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
1937 ok(!memcmp(ret, initial, sizeof(initial)),
1938 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1939 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1940 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 1, ret, 1);
1941 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1942 ok(!memcmp(ret, initial, sizeof(initial)),
1943 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1944 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1946 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_const, 1);
1947 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
1951 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 0, initial, 1);
1952 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
1953 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, initial, 1);
1954 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
1956 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 0, ret, 1);
1957 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
1958 ok(!memcmp(ret, initial, sizeof(initial)),
1959 "GetpixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1960 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1961 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 1, ret, 1);
1962 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
1963 ok(!memcmp(ret, initial, sizeof(initial)),
1964 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1965 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1967 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 0, ps_const, 1);
1968 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
1971 hr = IDirect3DDevice8_BeginStateBlock(device);
1972 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x\n", hr);
1976 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 1, vs_const, 1);
1977 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
1981 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, ps_const, 1);
1982 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
1985 hr = IDirect3DDevice8_EndStateBlock(device, &stateblock);
1986 ok(SUCCEEDED(hr), "EndStateBlock returned %#x\n", hr);
1990 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 0, ret, 1);
1991 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
1992 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1993 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1994 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1995 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 1, ret, 1);
1996 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
1997 ok(!memcmp(ret, initial, sizeof(initial)),
1998 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1999 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2003 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 0, ret, 1);
2004 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
2005 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2006 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2007 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2008 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 1, ret, 1);
2009 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
2010 ok(!memcmp(ret, initial, sizeof(initial)),
2011 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2012 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
2015 /* Apply doesn't overwrite constants that aren't explicitly set on the source stateblock. */
2016 hr = IDirect3DDevice8_ApplyStateBlock(device, stateblock);
2017 ok(SUCCEEDED(hr), "Apply returned %#x\n", hr);
2021 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 0, ret, 1);
2022 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
2023 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2024 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2025 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2026 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 1, ret, 1);
2027 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
2028 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
2029 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2030 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
2034 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 0, ret, 1);
2035 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
2036 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2037 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2038 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2039 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 1, ret, 1);
2040 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
2041 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
2042 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
2043 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
2046 IDirect3DDevice8_DeleteStateBlock(device, stateblock);
2049 START_TEST(stateblock)
2051 IDirect3DDevice8 *device = NULL;
2052 D3DPRESENT_PARAMETERS device_pparams;
2053 HMODULE d3d8_module;
2057 d3d8_module = LoadLibraryA("d3d8.dll");
2060 skip("Could not load d3d8.dll\n");
2064 hr = init_d3d8(d3d8_module, &device, &device_pparams);
2067 FreeLibrary(d3d8_module);
2071 test_begin_end_state_block(device);
2072 test_state_management(device, &device_pparams);
2073 test_shader_constant_apply(device);
2075 refcount = IDirect3DDevice8_Release(device);
2076 ok(!refcount, "Device has %u references left\n", refcount);
2078 FreeLibrary(d3d8_module);