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;
124 /* The poison data is the data to preinitialize the return buffer to */
125 const void *poison_data;
130 /* Size of the data samples above */
131 unsigned int data_size;
133 /* Test resource management handlers */
134 HRESULT (*setup_handler)(struct state_test *test);
135 void (*teardown_handler)(struct state_test *test);
137 /* Test data handlers */
138 void (*set_handler)(IDirect3DDevice8 *device, const struct state_test *test, const void *data_in);
139 void (*get_handler)(IDirect3DDevice8 *device, const struct state_test *test, void *data_out);
140 void (*print_handler)(const struct state_test *test, const void *data);
143 const void *test_arg;
145 /* Test-specific context data */
149 /* See below for explanation of the flags */
150 #define EVENT_OK 0x00
151 #define EVENT_CHECK_DEFAULT 0x01
152 #define EVENT_CHECK_INITIAL 0x02
153 #define EVENT_CHECK_TEST 0x04
154 #define EVENT_ERROR 0x08
155 #define EVENT_APPLY_DATA 0x10
159 int (*event_fn)(IDirect3DDevice8 *device, void *arg);
163 /* This is an event-machine, which tests things.
164 * It tests get and set operations for a batch of states, based on
165 * results from the event function, which directs what's to be done */
166 static void execute_test_chain(IDirect3DDevice8 *device, struct state_test *test,
167 unsigned int ntests, struct event *event, unsigned int nevents, void *event_arg)
169 unsigned int i = 0, j;
172 /* For each queued event */
173 for (j = 0; j < nevents; ++j)
175 /* Execute the next event handler (if available) or just set the supplied status */
176 outcome = event[j].status;
177 if (event[j].event_fn) outcome |= event[j].event_fn(device, event_arg);
179 /* Now verify correct outcome depending on what was signaled by the handler.
180 * An EVENT_CHECK_TEST signal means check the returned data against the test_data (out).
181 * An EVENT_CHECK_DEFAULT signal means check the returned data against the default_data.
182 * An EVENT_CHECK_INITIAL signal means check the returned data against the initial_data.
183 * An EVENT_ERROR signal means the test isn't going to work, exit the event loop.
184 * An EVENT_APPLY_DATA signal means load the test data (after checks) */
186 if (outcome & EVENT_ERROR)
188 trace("Test %s, Stage %u in error state, aborting\n", test[i].test_name, j);
191 else if (outcome & EVENT_CHECK_TEST || outcome & EVENT_CHECK_DEFAULT || outcome & EVENT_CHECK_INITIAL)
193 for (i = 0; i < ntests; ++i)
195 memcpy(test[i].return_data, test[i].poison_data, test[i].data_size);
196 test[i].get_handler(device, &test[i], test[i].return_data);
198 if (outcome & EVENT_CHECK_TEST)
200 BOOL test_failed = memcmp(test[i].test_data_out, test[i].return_data, test[i].data_size);
201 ok(!test_failed, "Test %s, Stage %u: returned data does not match test data [csize=%u]\n",
202 test[i].test_name, j, test[i].data_size);
204 if (test_failed && test[i].print_handler)
206 trace("Returned data was:\n");
207 test[i].print_handler(&test[i], test[i].return_data);
208 trace("Test data was:\n");
209 test[i].print_handler(&test[i], test[i].test_data_out);
212 else if (outcome & EVENT_CHECK_DEFAULT)
214 BOOL test_failed = memcmp(test[i].default_data, test[i].return_data, test[i].data_size);
215 ok(!test_failed, "Test %s, Stage %u: returned data does not match default data [csize=%u]\n",
216 test[i].test_name, j, test[i].data_size);
218 if (test_failed && test[i].print_handler)
220 trace("Returned data was:\n");
221 test[i].print_handler(&test[i], test[i].return_data);
222 trace("Default data was:\n");
223 test[i].print_handler(&test[i], test[i].default_data);
226 else if (outcome & EVENT_CHECK_INITIAL)
228 BOOL test_failed = memcmp(test[i].initial_data, test[i].return_data, test[i].data_size);
229 ok(!test_failed, "Test %s, Stage %u: returned data does not match initial data [csize=%u]\n",
230 test[i].test_name, j, test[i].data_size);
232 if (test_failed && test[i].print_handler)
234 trace("Returned data was:\n");
235 test[i].print_handler(&test[i], test[i].return_data);
236 trace("Initial data was:\n");
237 test[i].print_handler(&test[i], test[i].initial_data);
243 if (outcome & EVENT_APPLY_DATA)
245 for (i = 0; i < ntests; ++i)
247 test[i].set_handler(device, &test[i], test[i].test_data_in);
252 /* Attempt to reset any changes made */
253 for (i=0; i < ntests; i++)
255 test[i].set_handler(device, &test[i], test[i].default_data);
262 IDirect3DSurface8 *original_render_target;
263 IDirect3DSwapChain8 *new_swap_chain;
266 static int switch_render_target(IDirect3DDevice8* device, void *data)
268 D3DPRESENT_PARAMETERS present_parameters;
269 IDirect3DSwapChain8 *swapchain = NULL;
270 IDirect3DSurface8 *backbuffer = NULL;
271 struct event_data *edata = data;
272 D3DDISPLAYMODE d3ddm;
275 /* Parameters for new swapchain */
276 IDirect3DDevice8_GetDisplayMode(device, &d3ddm);
277 memset(&present_parameters, 0, sizeof(present_parameters));
278 present_parameters.Windowed = TRUE;
279 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
280 present_parameters.BackBufferFormat = d3ddm.Format;
282 /* Create new swapchain */
283 hr = IDirect3DDevice8_CreateAdditionalSwapChain(device, &present_parameters, &swapchain);
284 ok(SUCCEEDED(hr), "CreateAdditionalSwapChain returned %#x.\n", hr);
285 if (FAILED(hr)) goto error;
287 /* Get its backbuffer */
288 hr = IDirect3DSwapChain8_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
289 ok(SUCCEEDED(hr), "GetBackBuffer returned %#x.\n", hr);
290 if (FAILED(hr)) goto error;
292 /* Save the current render target */
293 hr = IDirect3DDevice8_GetRenderTarget(device, &edata->original_render_target);
294 ok(SUCCEEDED(hr), "GetRenderTarget returned %#x.\n", hr);
295 if (FAILED(hr)) goto error;
297 /* Set the new swapchain's backbuffer as a render target */
298 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
299 ok(SUCCEEDED(hr), "SetRenderTarget returned %#x.\n", hr);
300 if (FAILED(hr)) goto error;
302 IDirect3DSurface8_Release(backbuffer);
303 edata->new_swap_chain = swapchain;
307 if (backbuffer) IDirect3DSurface8_Release(backbuffer);
308 if (swapchain) IDirect3DSwapChain8_Release(swapchain);
312 static int revert_render_target(IDirect3DDevice8 *device, void *data)
314 struct event_data *edata = data;
317 /* Reset the old render target */
318 hr = IDirect3DDevice8_SetRenderTarget(device, edata->original_render_target, NULL);
319 ok(SUCCEEDED(hr), "SetRenderTarget returned %#x.\n", hr);
322 IDirect3DSurface8_Release(edata->original_render_target);
326 IDirect3DSurface8_Release(edata->original_render_target);
327 IDirect3DSwapChain8_Release(edata->new_swap_chain);
331 static int begin_stateblock(IDirect3DDevice8 *device, void *data)
335 hr = IDirect3DDevice8_BeginStateBlock(device);
336 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x.\n", hr);
337 if (FAILED(hr)) return EVENT_ERROR;
341 static int end_stateblock(IDirect3DDevice8 *device, void *data)
343 struct event_data *edata = data;
346 hr = IDirect3DDevice8_EndStateBlock(device, &edata->stateblock);
347 ok(SUCCEEDED(hr), "EndStateBlock returned %#x.\n", hr);
348 if (FAILED(hr)) return EVENT_ERROR;
352 static int abort_stateblock(IDirect3DDevice8 *device, void *data)
354 struct event_data *edata = data;
356 IDirect3DDevice8_DeleteStateBlock(device, edata->stateblock);
360 static int apply_stateblock(IDirect3DDevice8 *device, void *data)
362 struct event_data *edata = data;
365 hr = IDirect3DDevice8_ApplyStateBlock(device, edata->stateblock);
366 ok(SUCCEEDED(hr), "Apply returned %#x.\n", hr);
368 IDirect3DDevice8_DeleteStateBlock(device, edata->stateblock);
369 if (FAILED(hr)) return EVENT_ERROR;
373 static int capture_stateblock(IDirect3DDevice8 *device, void *data)
375 struct event_data *edata = data;
378 hr = IDirect3DDevice8_CaptureStateBlock(device, edata->stateblock);
379 ok(SUCCEEDED(hr), "Capture returned %#x.\n", hr);
380 if (FAILED(hr)) return EVENT_ERROR;
385 static void execute_test_chain_all(IDirect3DDevice8 *device, struct state_test *test, unsigned int ntests)
387 struct event_data arg;
391 struct event read_events[] =
393 {NULL, EVENT_CHECK_INITIAL},
396 struct event write_read_events[] =
398 {NULL, EVENT_APPLY_DATA},
399 {NULL, EVENT_CHECK_TEST},
402 struct event abort_stateblock_events[] =
404 {begin_stateblock, EVENT_APPLY_DATA},
405 {end_stateblock, EVENT_OK},
406 {abort_stateblock, EVENT_CHECK_DEFAULT},
409 struct event apply_stateblock_events[] =
411 {begin_stateblock, EVENT_APPLY_DATA},
412 {end_stateblock, EVENT_OK},
413 {apply_stateblock, EVENT_CHECK_TEST},
416 struct event capture_reapply_stateblock_events[] =
418 {begin_stateblock, EVENT_APPLY_DATA},
419 {end_stateblock, EVENT_OK},
420 {capture_stateblock, EVENT_CHECK_DEFAULT | EVENT_APPLY_DATA},
421 {apply_stateblock, EVENT_CHECK_DEFAULT},
424 struct event rendertarget_switch_events[] =
426 {NULL, EVENT_APPLY_DATA},
427 {switch_render_target, EVENT_CHECK_TEST},
428 {revert_render_target, EVENT_OK},
431 struct event rendertarget_stateblock_events[] =
433 {begin_stateblock, EVENT_APPLY_DATA},
434 {switch_render_target, EVENT_CHECK_DEFAULT},
435 {end_stateblock, EVENT_OK},
436 {revert_render_target, EVENT_OK},
437 {apply_stateblock, EVENT_CHECK_TEST},
440 /* Setup each test for execution */
441 for (i = 0; i < ntests; ++i)
443 hr = test[i].setup_handler(&test[i]);
444 ok(SUCCEEDED(hr), "Test \"%s\" failed setup, aborting\n", test[i].test_name);
445 if (FAILED(hr)) return;
448 trace("Running initial read state tests\n");
449 execute_test_chain(device, test, ntests, read_events, 1, NULL);
451 trace("Running write-read state tests\n");
452 execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
454 trace("Running stateblock abort state tests\n");
455 execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
457 trace("Running stateblock apply state tests\n");
458 execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
460 trace("Running stateblock capture/reapply state tests\n");
461 execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
463 trace("Running rendertarget switch state tests\n");
464 execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
466 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
467 execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
469 /* Cleanup resources */
470 for (i = 0; i < ntests; ++i)
472 test[i].teardown_handler(&test[i]);
476 /* =================== State test: Pixel and Vertex Shader constants ============ */
478 struct shader_constant_data
480 float float_constant[4]; /* 1x4 float constant */
483 struct shader_constant_arg
489 struct shader_constant_context
491 struct shader_constant_data return_data_buffer;
494 static void shader_constant_print_handler(const struct state_test *test, const void *data)
496 const struct shader_constant_data *scdata = data;
498 trace("Float constant = { %f, %f, %f, %f }\n",
499 scdata->float_constant[0], scdata->float_constant[1],
500 scdata->float_constant[2], scdata->float_constant[3]);
503 static void shader_constant_set_handler(IDirect3DDevice8* device, const struct state_test *test, const void *data)
505 const struct shader_constant_data *scdata = data;
506 const struct shader_constant_arg *scarg = test->test_arg;
507 unsigned int index = scarg->idx;
512 hr = IDirect3DDevice8_SetVertexShaderConstant(device, index, scdata->float_constant, 1);
513 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
517 hr = IDirect3DDevice8_SetPixelShaderConstant(device, index, scdata->float_constant, 1);
518 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
522 static void shader_constant_get_handler(IDirect3DDevice8* device, const struct state_test *test, void *data)
524 struct shader_constant_data *scdata = data;
525 const struct shader_constant_arg *scarg = test->test_arg;
526 unsigned int index = scarg->idx;
531 hr = IDirect3DDevice8_GetVertexShaderConstant(device, index, scdata->float_constant, 1);
532 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
537 hr = IDirect3DDevice8_GetPixelShaderConstant(device, index, scdata->float_constant, 1);
538 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
542 static const struct shader_constant_data shader_constant_poison_data =
544 {1.0f, 2.0f, 3.0f, 4.0f},
547 static const struct shader_constant_data shader_constant_default_data =
549 {0.0f, 0.0f, 0.0f, 0.0f},
552 static const struct shader_constant_data shader_constant_test_data =
554 {5.0f, 6.0f, 7.0f, 8.0f},
557 static HRESULT shader_constant_setup_handler(struct state_test *test)
559 struct shader_constant_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
560 if (!ctx) return E_FAIL;
561 test->test_context = ctx;
563 test->return_data = &ctx->return_data_buffer;
564 test->test_data_in = &shader_constant_test_data;
565 test->test_data_out = &shader_constant_test_data;
566 test->default_data = &shader_constant_default_data;
567 test->initial_data = &shader_constant_default_data;
568 test->poison_data = &shader_constant_poison_data;
570 test->data_size = sizeof(struct shader_constant_data);
575 static void shader_constant_teardown_handler(struct state_test *test)
577 HeapFree(GetProcessHeap(), 0, test->test_context);
580 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
582 test->setup_handler = shader_constant_setup_handler;
583 test->teardown_handler = shader_constant_teardown_handler;
584 test->set_handler = shader_constant_set_handler;
585 test->get_handler = shader_constant_get_handler;
586 test->print_handler = shader_constant_print_handler;
587 test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
588 test->test_arg = test_arg;
591 /* =================== State test: Lights ===================================== */
597 HRESULT get_light_result;
598 HRESULT get_enabled_result;
608 struct light_data return_data_buffer;
611 static void light_print_handler(const struct state_test *test, const void *data)
613 const struct light_data *ldata = data;
615 trace("Get Light return value: %#x\n", ldata->get_light_result);
616 trace("Get Light enable return value: %#x\n", ldata->get_enabled_result);
618 trace("Light Enabled = %u\n", ldata->enabled);
619 trace("Light Type = %u\n", ldata->light.Type);
620 trace("Light Diffuse = { %f, %f, %f, %f }\n",
621 ldata->light.Diffuse.r, ldata->light.Diffuse.g,
622 ldata->light.Diffuse.b, ldata->light.Diffuse.a);
623 trace("Light Specular = { %f, %f, %f, %f}\n",
624 ldata->light.Specular.r, ldata->light.Specular.g,
625 ldata->light.Specular.b, ldata->light.Specular.a);
626 trace("Light Ambient = { %f, %f, %f, %f }\n",
627 ldata->light.Ambient.r, ldata->light.Ambient.g,
628 ldata->light.Ambient.b, ldata->light.Ambient.a);
629 trace("Light Position = { %f, %f, %f }\n",
630 ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z);
631 trace("Light Direction = { %f, %f, %f }\n",
632 ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z);
633 trace("Light Range = %f\n", ldata->light.Range);
634 trace("Light Fallof = %f\n", ldata->light.Falloff);
635 trace("Light Attenuation0 = %f\n", ldata->light.Attenuation0);
636 trace("Light Attenuation1 = %f\n", ldata->light.Attenuation1);
637 trace("Light Attenuation2 = %f\n", ldata->light.Attenuation2);
638 trace("Light Theta = %f\n", ldata->light.Theta);
639 trace("Light Phi = %f\n", ldata->light.Phi);
642 static void light_set_handler(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
644 const struct light_data *ldata = data;
645 const struct light_arg *larg = test->test_arg;
646 unsigned int index = larg->idx;
649 hr = IDirect3DDevice8_SetLight(device, index, &ldata->light);
650 ok(SUCCEEDED(hr), "SetLight returned %#x.\n", hr);
652 hr = IDirect3DDevice8_LightEnable(device, index, ldata->enabled);
653 ok(SUCCEEDED(hr), "SetLightEnable returned %#x.\n", hr);
656 static void light_get_handler(IDirect3DDevice8 *device, const struct state_test *test, void *data)
658 struct light_data *ldata = data;
659 const struct light_arg *larg = test->test_arg;
660 unsigned int index = larg->idx;
663 hr = IDirect3DDevice8_GetLightEnable(device, index, &ldata->enabled);
664 ldata->get_enabled_result = hr;
666 hr = IDirect3DDevice8_GetLight(device, index, &ldata->light);
667 ldata->get_light_result = hr;
670 static const struct light_data light_poison_data =
674 {7.0, 4.0, 2.0, 1.0},
675 {7.0, 4.0, 2.0, 1.0},
676 {7.0, 4.0, 2.0, 1.0},
679 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
686 static const struct light_data light_default_data =
689 D3DLIGHT_DIRECTIONAL,
690 {1.0, 1.0, 1.0, 0.0},
691 {0.0, 0.0, 0.0, 0.0},
692 {0.0, 0.0, 0.0, 0.0},
695 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
702 /* This is used for the initial read state (before a write causes side effects)
703 * The proper return status is D3DERR_INVALIDCALL */
704 static const struct light_data light_initial_data =
708 {7.0, 4.0, 2.0, 1.0},
709 {7.0, 4.0, 2.0, 1.0},
710 {7.0, 4.0, 2.0, 1.0},
713 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
720 static const struct light_data light_test_data_in =
724 {2.0, 2.0, 2.0, 2.0},
725 {3.0, 3.0, 3.0, 3.0},
726 {4.0, 4.0, 4.0, 4.0},
729 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
736 /* SetLight will use 128 as the "enabled" value */
737 static const struct light_data light_test_data_out =
741 {2.0, 2.0, 2.0, 2.0},
742 {3.0, 3.0, 3.0, 3.0},
743 {4.0, 4.0, 4.0, 4.0},
746 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
753 static HRESULT light_setup_handler(struct state_test *test)
755 struct light_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
756 if (!ctx) return E_FAIL;
757 test->test_context = ctx;
759 test->return_data = &ctx->return_data_buffer;
760 test->test_data_in = &light_test_data_in;
761 test->test_data_out = &light_test_data_out;
762 test->default_data = &light_default_data;
763 test->initial_data = &light_initial_data;
764 test->poison_data = &light_poison_data;
766 test->data_size = sizeof(struct light_data);
771 static void light_teardown_handler(struct state_test *test)
773 HeapFree(GetProcessHeap(), 0, test->test_context);
776 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
778 test->setup_handler = light_setup_handler;
779 test->teardown_handler = light_teardown_handler;
780 test->set_handler = light_set_handler;
781 test->get_handler = light_get_handler;
782 test->print_handler = light_print_handler;
783 test->test_name = "set_get_light";
784 test->test_arg = test_arg;
787 /* =================== State test: Transforms ===================================== */
789 struct transform_data
792 D3DMATRIX projection;
799 struct transform_context
801 struct transform_data return_data_buffer;
804 static inline void print_matrix(const char *name, const D3DMATRIX *matrix)
806 trace("%s Matrix =\n{\n", name);
807 trace(" %f %f %f %f\n", U(*matrix).m[0][0], U(*matrix).m[1][0], U(*matrix).m[2][0], U(*matrix).m[3][0]);
808 trace(" %f %f %f %f\n", U(*matrix).m[0][1], U(*matrix).m[1][1], U(*matrix).m[2][1], U(*matrix).m[3][1]);
809 trace(" %f %f %f %f\n", U(*matrix).m[0][2], U(*matrix).m[1][2], U(*matrix).m[2][2], U(*matrix).m[3][2]);
810 trace(" %f %f %f %f\n", U(*matrix).m[0][3], U(*matrix).m[1][3], U(*matrix).m[2][3], U(*matrix).m[3][3]);
814 static void transform_print_handler(const struct state_test *test, const void *data)
816 const struct transform_data *tdata = data;
818 print_matrix("View", &tdata->view);
819 print_matrix("Projection", &tdata->projection);
820 print_matrix("Texture0", &tdata->texture0);
821 print_matrix("Texture7", &tdata->texture7);
822 print_matrix("World0", &tdata->world0);
823 print_matrix("World255", &tdata->world255);
826 static void transform_set_handler(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
828 const struct transform_data *tdata = data;
831 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &tdata->view);
832 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
834 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
835 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
837 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
838 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
840 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
841 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
843 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &tdata->world0);
844 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
846 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
847 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
850 static void transform_get_handler(IDirect3DDevice8 *device, const struct state_test *test, void *data)
852 struct transform_data *tdata = data;
855 hr = IDirect3DDevice8_GetTransform(device, D3DTS_VIEW, &tdata->view);
856 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
858 hr = IDirect3DDevice8_GetTransform(device, D3DTS_PROJECTION, &tdata->projection);
859 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
861 hr = IDirect3DDevice8_GetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
862 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
864 hr = IDirect3DDevice8_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
865 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
867 hr = IDirect3DDevice8_GetTransform(device, D3DTS_WORLD, &tdata->world0);
868 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
870 hr = IDirect3DDevice8_GetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
871 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
874 static const struct transform_data transform_default_data =
877 1.0f, 0.0f, 0.0f, 0.0f,
878 0.0f, 1.0f, 0.0f, 0.0f,
879 0.0f, 0.0f, 1.0f, 0.0f,
880 0.0f, 0.0f, 0.0f, 1.0f,
883 1.0f, 0.0f, 0.0f, 0.0f,
884 0.0f, 1.0f, 0.0f, 0.0f,
885 0.0f, 0.0f, 1.0f, 0.0f,
886 0.0f, 0.0f, 0.0f, 1.0f,
889 1.0f, 0.0f, 0.0f, 0.0f,
890 0.0f, 1.0f, 0.0f, 0.0f,
891 0.0f, 0.0f, 1.0f, 0.0f,
892 0.0f, 0.0f, 0.0f, 1.0f,
895 1.0f, 0.0f, 0.0f, 0.0f,
896 0.0f, 1.0f, 0.0f, 0.0f,
897 0.0f, 0.0f, 1.0f, 0.0f,
898 0.0f, 0.0f, 0.0f, 1.0f,
901 1.0f, 0.0f, 0.0f, 0.0f,
902 0.0f, 1.0f, 0.0f, 0.0f,
903 0.0f, 0.0f, 1.0f, 0.0f,
904 0.0f, 0.0f, 0.0f, 1.0f,
907 1.0f, 0.0f, 0.0f, 0.0f,
908 0.0f, 1.0f, 0.0f, 0.0f,
909 0.0f, 0.0f, 1.0f, 0.0f,
910 0.0f, 0.0f, 0.0f, 1.0f,
914 static const struct transform_data transform_poison_data =
917 1.0f, 2.0f, 3.0f, 4.0f,
918 5.0f, 6.0f, 7.0f, 8.0f,
919 9.0f, 10.0f, 11.0f, 12.0f,
920 13.0f, 14.0f, 15.0f, 16.0f,
923 17.0f, 18.0f, 19.0f, 20.0f,
924 21.0f, 22.0f, 23.0f, 24.0f,
925 25.0f, 26.0f, 27.0f, 28.0f,
926 29.0f, 30.0f, 31.0f, 32.0f,
929 33.0f, 34.0f, 35.0f, 36.0f,
930 37.0f, 38.0f, 39.0f, 40.0f,
931 41.0f, 42.0f, 43.0f, 44.0f,
932 45.0f, 46.0f, 47.0f, 48.0f,
935 49.0f, 50.0f, 51.0f, 52.0f,
936 53.0f, 54.0f, 55.0f, 56.0f,
937 57.0f, 58.0f, 59.0f, 60.0f,
938 61.0f, 62.0f, 63.0f, 64.0f,
941 64.0f, 66.0f, 67.0f, 68.0f,
942 69.0f, 70.0f, 71.0f, 72.0f,
943 73.0f, 74.0f, 75.0f, 76.0f,
944 77.0f, 78.0f, 79.0f, 80.0f,
947 81.0f, 82.0f, 83.0f, 84.0f,
948 85.0f, 86.0f, 87.0f, 88.0f,
949 89.0f, 90.0f, 91.0f, 92.0f,
950 93.0f, 94.0f, 95.0f, 96.0f,
954 static const struct transform_data transform_test_data =
957 1.2f, 3.4f, -5.6f, 7.2f,
958 10.11f, -12.13f, 14.15f, -1.5f,
959 23.56f, 12.89f, 44.56f, -1.0f,
960 2.3f, 0.0f, 4.4f, 5.5f,
963 9.2f, 38.7f, -6.6f, 7.2f,
964 10.11f, -12.13f, 77.15f, -1.5f,
965 23.56f, 12.89f, 14.56f, -1.0f,
966 12.3f, 0.0f, 4.4f, 5.5f,
969 10.2f, 3.4f, 0.6f, 7.2f,
970 10.11f, -12.13f, 14.15f, -1.5f,
971 23.54f, 12.9f, 44.56f, -1.0f,
972 2.3f, 0.0f, 4.4f, 5.5f,
975 1.2f, 3.4f, -5.6f, 7.2f,
976 10.11f, -12.13f, -14.5f, -1.5f,
977 2.56f, 12.89f, 23.56f, -1.0f,
978 112.3f, 0.0f, 4.4f, 2.5f,
981 1.2f, 31.41f, 58.6f, 7.2f,
982 10.11f, -12.13f, -14.5f, -1.5f,
983 2.56f, 12.89f, 11.56f, -1.0f,
984 112.3f, 0.0f, 44.4f, 2.5f,
988 1.20f, 3.4f, -5.6f, 7.0f,
989 10.11f, -12.156f, -14.5f, -1.5f,
990 2.56f, 1.829f, 23.6f, -1.0f,
991 112.3f, 0.0f, 41.4f, 2.5f,
995 static HRESULT transform_setup_handler(struct state_test *test)
997 struct transform_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
998 if (!ctx) return E_FAIL;
999 test->test_context = ctx;
1001 test->return_data = &ctx->return_data_buffer;
1002 test->test_data_in = &transform_test_data;
1003 test->test_data_out = &transform_test_data;
1004 test->default_data = &transform_default_data;
1005 test->initial_data = &transform_default_data;
1006 test->poison_data = &transform_poison_data;
1008 test->data_size = sizeof(struct transform_data);
1013 static void transform_teardown_handler(struct state_test *test)
1015 HeapFree(GetProcessHeap(), 0, test->test_context);
1018 static void transform_queue_test(struct state_test *test)
1020 test->setup_handler = transform_setup_handler;
1021 test->teardown_handler = transform_teardown_handler;
1022 test->set_handler = transform_set_handler;
1023 test->get_handler = transform_get_handler;
1024 test->print_handler = transform_print_handler;
1025 test->test_name = "set_get_transforms";
1026 test->test_arg = NULL;
1029 /* =================== State test: Render States ===================================== */
1031 const D3DRENDERSTATETYPE render_state_indices[] =
1037 D3DRS_ALPHATESTENABLE,
1046 D3DRS_ALPHABLENDENABLE,
1048 D3DRS_SPECULARENABLE,
1054 D3DRS_RANGEFOGENABLE,
1055 D3DRS_STENCILENABLE,
1062 D3DRS_STENCILWRITEMASK,
1063 D3DRS_TEXTUREFACTOR,
1075 D3DRS_FOGVERTEXMODE,
1078 D3DRS_NORMALIZENORMALS,
1079 D3DRS_DIFFUSEMATERIALSOURCE,
1080 D3DRS_SPECULARMATERIALSOURCE,
1081 D3DRS_AMBIENTMATERIALSOURCE,
1082 D3DRS_EMISSIVEMATERIALSOURCE,
1084 D3DRS_CLIPPLANEENABLE,
1085 #if 0 /* Driver dependent, increase array size to enable */
1088 D3DRS_POINTSIZE_MIN,
1089 D3DRS_POINTSPRITEENABLE,
1090 D3DRS_POINTSCALEENABLE,
1094 D3DRS_MULTISAMPLEANTIALIAS,
1095 D3DRS_MULTISAMPLEMASK,
1096 D3DRS_PATCHEDGESTYLE,
1097 D3DRS_DEBUGMONITORTOKEN,
1098 D3DRS_POINTSIZE_MAX,
1099 D3DRS_INDEXEDVERTEXBLENDENABLE,
1100 D3DRS_COLORWRITEENABLE,
1105 struct render_state_data
1107 DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1110 struct render_state_arg
1112 D3DPRESENT_PARAMETERS *device_pparams;
1113 float pointsize_max;
1116 struct render_state_context
1118 struct render_state_data return_data_buffer;
1119 struct render_state_data default_data_buffer;
1120 struct render_state_data test_data_buffer;
1121 struct render_state_data poison_data_buffer;
1124 static void render_state_set_handler(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
1126 const struct render_state_data *rsdata = data;
1130 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1132 hr = IDirect3DDevice8_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1133 ok(SUCCEEDED(hr), "SetRenderState returned %#x.\n", hr);
1137 static void render_state_get_handler(IDirect3DDevice8 *device, const struct state_test *test, void *data)
1139 struct render_state_data* rsdata = data;
1143 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1145 hr = IDirect3DDevice8_GetRenderState(device, render_state_indices[i], &rsdata->states[i]);
1146 ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1150 static void render_state_print_handler(const struct state_test *test, const void *data)
1152 const struct render_state_data *rsdata = data;
1155 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1157 trace("Index = %u, Value = %#x\n", i, rsdata->states[i]);
1161 static inline DWORD to_dword(float fl)
1163 union {float f; DWORD d;} ret;
1169 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1171 DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1172 unsigned int idx = 0;
1174 data->states[idx++] = zenable; /* ZENABLE */
1175 data->states[idx++] = D3DFILL_SOLID; /* FILLMODE */
1176 data->states[idx++] = D3DSHADE_GOURAUD; /* SHADEMODE */
1177 data->states[idx++] = TRUE; /* ZWRITEENABLE */
1178 data->states[idx++] = FALSE; /* ALPHATESTENABLE */
1179 data->states[idx++] = TRUE; /* LASTPIXEL */
1180 data->states[idx++] = D3DBLEND_ONE; /* SRCBLEND */
1181 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLEND */
1182 data->states[idx++] = D3DCULL_CCW; /* CULLMODE */
1183 data->states[idx++] = D3DCMP_LESSEQUAL; /* ZFUNC */
1184 data->states[idx++] = 0; /* ALPHAREF */
1185 data->states[idx++] = D3DCMP_ALWAYS; /* ALPHAFUNC */
1186 data->states[idx++] = FALSE; /* DITHERENABLE */
1187 data->states[idx++] = FALSE; /* ALPHABLENDENABLE */
1188 data->states[idx++] = FALSE; /* FOGENABLE */
1189 data->states[idx++] = FALSE; /* SPECULARENABLE */
1190 data->states[idx++] = 0; /* FOGCOLOR */
1191 data->states[idx++] = D3DFOG_NONE; /* FOGTABLEMODE */
1192 data->states[idx++] = to_dword(0.0f); /* FOGSTART */
1193 data->states[idx++] = to_dword(1.0f); /* FOGEND */
1194 data->states[idx++] = to_dword(1.0f); /* FOGDENSITY */
1195 data->states[idx++] = FALSE; /* RANGEFOGENABLE */
1196 data->states[idx++] = FALSE; /* STENCILENABLE */
1197 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILFAIL */
1198 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILZFAIL */
1199 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILPASS */
1200 data->states[idx++] = D3DCMP_ALWAYS; /* STENCILFUNC */
1201 data->states[idx++] = 0; /* STENCILREF */
1202 data->states[idx++] = 0xFFFFFFFF; /* STENCILMASK */
1203 data->states[idx++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1204 data->states[idx++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1205 data->states[idx++] = 0; /* WRAP 0 */
1206 data->states[idx++] = 0; /* WRAP 1 */
1207 data->states[idx++] = 0; /* WRAP 2 */
1208 data->states[idx++] = 0; /* WRAP 3 */
1209 data->states[idx++] = 0; /* WRAP 4 */
1210 data->states[idx++] = 0; /* WRAP 5 */
1211 data->states[idx++] = 0; /* WRAP 6 */
1212 data->states[idx++] = 0; /* WRAP 7 */
1213 data->states[idx++] = TRUE; /* CLIPPING */
1214 data->states[idx++] = TRUE; /* LIGHTING */
1215 data->states[idx++] = 0; /* AMBIENT */
1216 data->states[idx++] = D3DFOG_NONE; /* FOGVERTEXMODE */
1217 data->states[idx++] = TRUE; /* COLORVERTEX */
1218 data->states[idx++] = TRUE; /* LOCALVIEWER */
1219 data->states[idx++] = FALSE; /* NORMALIZENORMALS */
1220 data->states[idx++] = D3DMCS_COLOR1; /* DIFFUSEMATERIALSOURCE */
1221 data->states[idx++] = D3DMCS_COLOR2; /* SPECULARMATERIALSOURCE */
1222 data->states[idx++] = D3DMCS_MATERIAL; /* AMBIENTMATERIALSOURCE */
1223 data->states[idx++] = D3DMCS_MATERIAL; /* EMISSIVEMATERIALSOURCE */
1224 data->states[idx++] = D3DVBF_DISABLE; /* VERTEXBLEND */
1225 data->states[idx++] = 0; /* CLIPPLANEENABLE */
1226 if (0) data->states[idx++] = to_dword(1.0f); /* POINTSIZE, driver dependent, increase array size to enable */
1227 data->states[idx++] = to_dword(0.0f); /* POINTSIZEMIN */
1228 data->states[idx++] = FALSE; /* POINTSPRITEENABLE */
1229 data->states[idx++] = FALSE; /* POINTSCALEENABLE */
1230 data->states[idx++] = to_dword(1.0f); /* POINTSCALE_A */
1231 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_B */
1232 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_C */
1233 data->states[idx++] = TRUE; /* MULTISAMPLEANTIALIAS */
1234 data->states[idx++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1235 data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1236 data->states[idx++] = 0xbaadcafe; /* DEBUGMONITORTOKEN */
1237 data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1238 data->states[idx++] = FALSE; /* INDEXEDVERTEXBLENDENABLE */
1239 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE */
1240 data->states[idx++] = to_dword(0.0f); /* TWEENFACTOR */
1241 data->states[idx++] = D3DBLENDOP_ADD; /* BLENDOP */
1244 static void render_state_poison_data_init(struct render_state_data *data)
1248 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1250 data->states[i] = 0x1337c0de;
1254 static void render_state_test_data_init(struct render_state_data *data)
1256 unsigned int idx = 0;
1258 data->states[idx++] = D3DZB_USEW; /* ZENABLE */
1259 data->states[idx++] = D3DFILL_WIREFRAME; /* FILLMODE */
1260 data->states[idx++] = D3DSHADE_PHONG; /* SHADEMODE */
1261 data->states[idx++] = FALSE; /* ZWRITEENABLE */
1262 data->states[idx++] = TRUE; /* ALPHATESTENABLE */
1263 data->states[idx++] = FALSE; /* LASTPIXEL */
1264 data->states[idx++] = D3DBLEND_SRCALPHASAT; /* SRCBLEND */
1265 data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1266 data->states[idx++] = D3DCULL_CW; /* CULLMODE */
1267 data->states[idx++] = D3DCMP_NOTEQUAL; /* ZFUNC */
1268 data->states[idx++] = 10; /* ALPHAREF */
1269 data->states[idx++] = D3DCMP_GREATER; /* ALPHAFUNC */
1270 data->states[idx++] = TRUE; /* DITHERENABLE */
1271 data->states[idx++] = TRUE; /* ALPHABLENDENABLE */
1272 data->states[idx++] = TRUE; /* FOGENABLE */
1273 data->states[idx++] = TRUE; /* SPECULARENABLE */
1274 data->states[idx++] = 255 << 31; /* FOGCOLOR */
1275 data->states[idx++] = D3DFOG_EXP; /* FOGTABLEMODE */
1276 data->states[idx++] = to_dword(0.1f); /* FOGSTART */
1277 data->states[idx++] = to_dword(0.8f); /* FOGEND */
1278 data->states[idx++] = to_dword(0.5f); /* FOGDENSITY */
1279 data->states[idx++] = TRUE; /* RANGEFOGENABLE */
1280 data->states[idx++] = TRUE; /* STENCILENABLE */
1281 data->states[idx++] = D3DSTENCILOP_INCRSAT; /* STENCILFAIL */
1282 data->states[idx++] = D3DSTENCILOP_REPLACE; /* STENCILZFAIL */
1283 data->states[idx++] = D3DSTENCILOP_INVERT; /* STENCILPASS */
1284 data->states[idx++] = D3DCMP_LESS; /* STENCILFUNC */
1285 data->states[idx++] = 10; /* STENCILREF */
1286 data->states[idx++] = 0xFF00FF00; /* STENCILMASK */
1287 data->states[idx++] = 0x00FF00FF; /* STENCILWRITEMASK */
1288 data->states[idx++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1289 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 0 */
1290 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 1 */
1291 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 2 */
1292 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 4 */
1293 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 5 */
1294 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 6 */
1295 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 7 */
1296 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1297 data->states[idx++] = FALSE; /* CLIPPING */
1298 data->states[idx++] = FALSE; /* LIGHTING */
1299 data->states[idx++] = 255 << 16; /* AMBIENT */
1300 data->states[idx++] = D3DFOG_EXP2; /* FOGVERTEXMODE */
1301 data->states[idx++] = FALSE; /* COLORVERTEX */
1302 data->states[idx++] = FALSE; /* LOCALVIEWER */
1303 data->states[idx++] = TRUE; /* NORMALIZENORMALS */
1304 data->states[idx++] = D3DMCS_COLOR2; /* DIFFUSEMATERIALSOURCE */
1305 data->states[idx++] = D3DMCS_MATERIAL; /* SPECULARMATERIALSOURCE */
1306 data->states[idx++] = D3DMCS_COLOR1; /* AMBIENTMATERIALSOURCE */
1307 data->states[idx++] = D3DMCS_COLOR2; /* EMISSIVEMATERIALSOURCE */
1308 data->states[idx++] = D3DVBF_3WEIGHTS; /* VERTEXBLEND */
1309 data->states[idx++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1310 if (0) data->states[idx++] = to_dword(32.0f);/* POINTSIZE, driver dependent, increase array size to enable */
1311 data->states[idx++] = to_dword(0.7f); /* POINTSIZEMIN */
1312 data->states[idx++] = TRUE; /* POINTSPRITEENABLE */
1313 data->states[idx++] = TRUE; /* POINTSCALEENABLE */
1314 data->states[idx++] = to_dword(0.7f); /* POINTSCALE_A */
1315 data->states[idx++] = to_dword(0.5f); /* POINTSCALE_B */
1316 data->states[idx++] = to_dword(0.4f); /* POINTSCALE_C */
1317 data->states[idx++] = FALSE; /* MULTISAMPLEANTIALIAS */
1318 data->states[idx++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1319 data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1320 data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN */
1321 data->states[idx++] = to_dword(77.0f); /* POINTSIZE_MAX */
1322 data->states[idx++] = TRUE; /* INDEXEDVERTEXBLENDENABLE */
1323 data->states[idx++] = 0x00000009; /* COLORWRITEENABLE */
1324 data->states[idx++] = to_dword(0.2f); /* TWEENFACTOR */
1325 data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1328 static HRESULT render_state_setup_handler(struct state_test *test)
1330 const struct render_state_arg *rsarg = test->test_arg;
1332 struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1333 if (!ctx) return E_FAIL;
1334 test->test_context = ctx;
1336 test->return_data = &ctx->return_data_buffer;
1337 test->default_data = &ctx->default_data_buffer;
1338 test->initial_data = &ctx->default_data_buffer;
1339 test->test_data_in = &ctx->test_data_buffer;
1340 test->test_data_out = &ctx->test_data_buffer;
1341 test->poison_data = &ctx->poison_data_buffer;
1343 render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1344 render_state_test_data_init(&ctx->test_data_buffer);
1345 render_state_poison_data_init(&ctx->poison_data_buffer);
1347 test->data_size = sizeof(struct render_state_data);
1352 static void render_state_teardown_handler(struct state_test *test)
1354 HeapFree(GetProcessHeap(), 0, test->test_context);
1357 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1359 test->setup_handler = render_state_setup_handler;
1360 test->teardown_handler = render_state_teardown_handler;
1361 test->set_handler = render_state_set_handler;
1362 test->get_handler = render_state_get_handler;
1363 test->print_handler = render_state_print_handler;
1364 test->test_name = "set_get_render_states";
1365 test->test_arg = test_arg;
1368 /* =================== Main state tests function =============================== */
1370 static void test_state_management(IDirect3DDevice8 *device, D3DPRESENT_PARAMETERS *device_pparams)
1375 /* Test count: 2 for shader constants
1378 * 1 for render states
1380 const int max_tests = 5;
1381 struct state_test tests[5];
1382 unsigned int tcount = 0;
1384 struct shader_constant_arg pshader_constant_arg;
1385 struct shader_constant_arg vshader_constant_arg;
1386 struct render_state_arg render_state_arg;
1387 struct light_arg light_arg;
1389 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1390 ok(SUCCEEDED(hr), "GetDeviceCaps returned %#x.\n", hr);
1391 if (FAILED(hr)) return;
1393 texture_stages = caps.MaxTextureBlendStages;
1395 /* Zero test memory */
1396 memset(tests, 0, max_tests * sizeof(*tests));
1398 if (caps.VertexShaderVersion & 0xffff)
1400 vshader_constant_arg.idx = 0;
1401 vshader_constant_arg.pshader = FALSE;
1402 shader_constants_queue_test(&tests[tcount++], &vshader_constant_arg);
1405 if (caps.PixelShaderVersion & 0xffff)
1407 pshader_constant_arg.idx = 0;
1408 pshader_constant_arg.pshader = TRUE;
1409 shader_constants_queue_test(&tests[tcount++], &pshader_constant_arg);
1413 lights_queue_test(&tests[tcount++], &light_arg);
1415 transform_queue_test(&tests[tcount++]);
1417 render_state_arg.device_pparams = device_pparams;
1418 render_state_arg.pointsize_max = caps.MaxPointSize;
1419 render_states_queue_test(&tests[tcount++], &render_state_arg);
1421 execute_test_chain_all(device, tests, tcount);
1424 static void test_shader_constant_apply(IDirect3DDevice8 *device)
1426 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
1427 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
1428 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
1433 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, initial, 1);
1434 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x\n", hr);
1435 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 1, initial, 1);
1436 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x\n", hr);
1437 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 0, initial, 1);
1438 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x\n", hr);
1439 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, initial, 1);
1440 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x\n", hr);
1442 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 0, ret, 1);
1443 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1444 ok(!memcmp(ret, initial, sizeof(initial)),
1445 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1446 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1447 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 1, ret, 1);
1448 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1449 ok(!memcmp(ret, initial, sizeof(initial)),
1450 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1451 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1452 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 0, ret, 1);
1453 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x\n", hr);
1454 ok(!memcmp(ret, initial, sizeof(initial)),
1455 "GetpixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1456 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1457 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 1, ret, 1);
1458 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x\n", hr);
1459 ok(!memcmp(ret, initial, sizeof(initial)),
1460 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1461 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1463 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_const, 1);
1464 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x\n", hr);
1465 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 0, ps_const, 1);
1466 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x\n", hr);
1468 hr = IDirect3DDevice8_BeginStateBlock(device);
1469 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x\n", hr);
1471 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 1, vs_const, 1);
1472 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x\n", hr);
1473 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, ps_const, 1);
1474 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x\n", hr);
1476 hr = IDirect3DDevice8_EndStateBlock(device, &stateblock);
1477 ok(SUCCEEDED(hr), "EndStateBlock returned %#x\n", hr);
1479 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 0, ret, 1);
1480 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1481 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1482 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1483 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1484 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 1, ret, 1);
1485 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1486 ok(!memcmp(ret, initial, sizeof(initial)),
1487 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1488 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1489 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 0, ret, 1);
1490 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x\n", hr);
1491 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1492 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1493 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1494 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 1, ret, 1);
1495 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x\n", hr);
1496 ok(!memcmp(ret, initial, sizeof(initial)),
1497 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1498 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
1500 hr = IDirect3DDevice8_ApplyStateBlock(device, stateblock);
1501 ok(SUCCEEDED(hr), "Apply returned %#x\n", hr);
1503 /* Apply doesn't overwrite constants that aren't explicitly set on the source stateblock. */
1504 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 0, ret, 1);
1505 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1506 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1507 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1508 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1509 hr = IDirect3DDevice8_GetVertexShaderConstant(device, 1, ret, 1);
1510 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x\n", hr);
1511 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
1512 "GetVertexShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1513 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
1514 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 0, ret, 1);
1515 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x\n", hr);
1516 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1517 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1518 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1519 hr = IDirect3DDevice8_GetPixelShaderConstant(device, 1, ret, 1);
1520 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x\n", hr);
1521 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
1522 "GetPixelShaderConstant got {%f, %f, %f, %f}, expected {%f, %f, %f, %f}\n",
1523 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
1525 IDirect3DDevice8_DeleteStateBlock(device, stateblock);
1528 START_TEST(stateblock)
1530 IDirect3DDevice8 *device = NULL;
1531 D3DPRESENT_PARAMETERS device_pparams;
1532 HMODULE d3d8_module;
1536 d3d8_module = LoadLibraryA("d3d8.dll");
1539 skip("Could not load d3d8.dll\n");
1543 hr = init_d3d8(d3d8_module, &device, &device_pparams);
1546 FreeLibrary(d3d8_module);
1550 test_begin_end_state_block(device);
1551 test_state_management(device, &device_pparams);
1552 test_shader_constant_apply(device);
1554 refcount = IDirect3DDevice8_Release(device);
1555 ok(!refcount, "Device has %u references left\n", refcount);
1557 FreeLibrary(d3d8_module);