TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / d3d8 / tests / stateblock.c
blob3ad9c1c140bc14d5174dbfbb061bbc2b4588a6ce
1 /*
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
20 #define COBJMACROS
21 #include <d3d8.h>
22 #include "wine/test.h"
24 static DWORD texture_stages;
26 /* ============================ State Testing Framework ========================== */
28 struct state_test
30 const char *test_name;
32 /* The initial data is usually the same
33 * as the default data, but a write can have side effects.
34 * The initial data is tested first, before any writes take place
35 * The default data can be tested after a write */
36 const void *initial_data;
38 /* The default data is the standard state to compare
39 * against, and restore to */
40 const void *default_data;
42 /* The test data is the experiment data to try
43 * in - what we want to write
44 * out - what windows will actually write (not necessarily the same) */
45 const void *test_data_in;
46 const void *test_data_out_all;
47 const void *test_data_out_vertex;
48 const void *test_data_out_pixel;
50 HRESULT (*init)(IDirect3DDevice8 *device, struct state_test *test);
51 void (*cleanup)(IDirect3DDevice8 *device, struct state_test *test);
52 void (*apply_data)(IDirect3DDevice8 *device, const struct state_test *test,
53 const void *data);
54 void (*check_data)(IDirect3DDevice8 *device, const struct state_test *test,
55 const void *data_expected, unsigned int chain_stage);
57 /* Test arguments */
58 const void *test_arg;
60 /* Test-specific context data */
61 void *test_context;
64 /* See below for explanation of the flags */
65 #define EVENT_OK 0
66 #define EVENT_ERROR -1
68 struct event_data
70 DWORD stateblock;
71 IDirect3DSurface8 *original_render_target;
72 IDirect3DSwapChain8 *new_swap_chain;
75 enum stateblock_data
77 SB_DATA_NONE = 0,
78 SB_DATA_DEFAULT,
79 SB_DATA_INITIAL,
80 SB_DATA_TEST_IN,
81 SB_DATA_TEST_ALL,
82 SB_DATA_TEST_VERTEX,
83 SB_DATA_TEST_PIXEL,
86 struct event
88 int (*event_fn)(IDirect3DDevice8 *device, struct event_data *event_data);
89 enum stateblock_data check;
90 enum stateblock_data apply;
93 static const void *get_event_data(const struct state_test *test, enum stateblock_data data)
95 switch (data)
97 case SB_DATA_DEFAULT:
98 return test->default_data;
100 case SB_DATA_INITIAL:
101 return test->initial_data;
103 case SB_DATA_TEST_IN:
104 return test->test_data_in;
106 case SB_DATA_TEST_ALL:
107 return test->test_data_out_all;
109 case SB_DATA_TEST_VERTEX:
110 return test->test_data_out_vertex;
112 case SB_DATA_TEST_PIXEL:
113 return test->test_data_out_pixel;
115 default:
116 return NULL;
120 /* This is an event-machine, which tests things.
121 * It tests get and set operations for a batch of states, based on
122 * results from the event function, which directs what's to be done */
123 static void execute_test_chain(IDirect3DDevice8 *device, struct state_test *test,
124 unsigned int ntests, struct event *event, unsigned int nevents, struct event_data *event_data)
126 unsigned int i, j;
128 /* For each queued event */
129 for (j = 0; j < nevents; ++j)
131 const void *data;
133 /* Execute the next event handler (if available). */
134 if (event[j].event_fn)
136 if (event[j].event_fn(device, event_data) == EVENT_ERROR)
138 trace("Stage %u in error state, aborting.\n", j);
139 break;
143 if (event[j].check != SB_DATA_NONE)
145 for (i = 0; i < ntests; ++i)
147 data = get_event_data(&test[i], event[j].check);
148 test[i].check_data(device, &test[i], data, j);
152 if (event[j].apply != SB_DATA_NONE)
154 for (i = 0; i < ntests; ++i)
156 data = get_event_data(&test[i], event[j].apply);
157 test[i].apply_data(device, &test[i], data);
162 /* Attempt to reset any changes made. */
163 for (i = 0; i < ntests; ++i)
165 test[i].apply_data(device, &test[i], test[i].default_data);
169 static int switch_render_target(IDirect3DDevice8* device, struct event_data *event_data)
171 D3DPRESENT_PARAMETERS present_parameters;
172 IDirect3DSwapChain8 *swapchain = NULL;
173 IDirect3DSurface8 *backbuffer = NULL;
174 D3DDISPLAYMODE d3ddm;
175 HRESULT hr;
177 /* Parameters for new swapchain */
178 IDirect3DDevice8_GetDisplayMode(device, &d3ddm);
179 memset(&present_parameters, 0, sizeof(present_parameters));
180 present_parameters.Windowed = TRUE;
181 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
182 present_parameters.BackBufferFormat = d3ddm.Format;
184 /* Create new swapchain */
185 hr = IDirect3DDevice8_CreateAdditionalSwapChain(device, &present_parameters, &swapchain);
186 ok(SUCCEEDED(hr), "CreateAdditionalSwapChain returned %#x.\n", hr);
187 if (FAILED(hr)) goto error;
189 /* Get its backbuffer */
190 hr = IDirect3DSwapChain8_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
191 ok(SUCCEEDED(hr), "GetBackBuffer returned %#x.\n", hr);
192 if (FAILED(hr)) goto error;
194 /* Save the current render target */
195 hr = IDirect3DDevice8_GetRenderTarget(device, &event_data->original_render_target);
196 ok(SUCCEEDED(hr), "GetRenderTarget returned %#x.\n", hr);
197 if (FAILED(hr)) goto error;
199 /* Set the new swapchain's backbuffer as a render target */
200 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
201 ok(SUCCEEDED(hr), "SetRenderTarget returned %#x.\n", hr);
202 if (FAILED(hr)) goto error;
204 IDirect3DSurface8_Release(backbuffer);
205 event_data->new_swap_chain = swapchain;
206 return EVENT_OK;
208 error:
209 if (backbuffer) IDirect3DSurface8_Release(backbuffer);
210 if (swapchain) IDirect3DSwapChain8_Release(swapchain);
211 return EVENT_ERROR;
214 static int revert_render_target(IDirect3DDevice8 *device, struct event_data *event_data)
216 HRESULT hr;
218 /* Reset the old render target */
219 hr = IDirect3DDevice8_SetRenderTarget(device, event_data->original_render_target, NULL);
220 ok(SUCCEEDED(hr), "SetRenderTarget returned %#x.\n", hr);
221 if (FAILED(hr))
223 IDirect3DSurface8_Release(event_data->original_render_target);
224 return EVENT_ERROR;
227 IDirect3DSurface8_Release(event_data->original_render_target);
228 IDirect3DSwapChain8_Release(event_data->new_swap_chain);
229 return EVENT_OK;
232 static int create_stateblock_all(IDirect3DDevice8 *device, struct event_data *event_data)
234 HRESULT hr;
236 hr = IDirect3DDevice8_CreateStateBlock(device, D3DSBT_ALL, &event_data->stateblock);
237 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
238 if (FAILED(hr)) return EVENT_ERROR;
239 return EVENT_OK;
242 static int create_stateblock_vertex(IDirect3DDevice8 *device, struct event_data *event_data)
244 HRESULT hr;
246 hr = IDirect3DDevice8_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &event_data->stateblock);
247 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
248 if (FAILED(hr)) return EVENT_ERROR;
249 return EVENT_OK;
252 static int create_stateblock_pixel(IDirect3DDevice8 *device, struct event_data *event_data)
254 HRESULT hr;
256 hr = IDirect3DDevice8_CreateStateBlock(device, D3DSBT_PIXELSTATE, &event_data->stateblock);
257 ok(SUCCEEDED(hr), "CreateStateBlock returned %#x.\n", hr);
258 if (FAILED(hr)) return EVENT_ERROR;
259 return EVENT_OK;
262 static int begin_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
264 HRESULT hr;
266 hr = IDirect3DDevice8_BeginStateBlock(device);
267 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x.\n", hr);
268 if (FAILED(hr)) return EVENT_ERROR;
269 return EVENT_OK;
272 static int end_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
274 HRESULT hr;
276 hr = IDirect3DDevice8_EndStateBlock(device, &event_data->stateblock);
277 ok(SUCCEEDED(hr), "EndStateBlock returned %#x.\n", hr);
278 if (FAILED(hr)) return EVENT_ERROR;
279 return EVENT_OK;
282 static int delete_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
284 IDirect3DDevice8_DeleteStateBlock(device, event_data->stateblock);
285 return EVENT_OK;
288 static int apply_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
290 HRESULT hr;
292 hr = IDirect3DDevice8_ApplyStateBlock(device, event_data->stateblock);
293 ok(SUCCEEDED(hr), "Apply returned %#x.\n", hr);
295 IDirect3DDevice8_DeleteStateBlock(device, event_data->stateblock);
296 if (FAILED(hr)) return EVENT_ERROR;
297 return EVENT_OK;
300 static int capture_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
302 HRESULT hr;
304 hr = IDirect3DDevice8_CaptureStateBlock(device, event_data->stateblock);
305 ok(SUCCEEDED(hr), "Capture returned %#x.\n", hr);
306 if (FAILED(hr)) return EVENT_ERROR;
308 return EVENT_OK;
311 static void execute_test_chain_all(IDirect3DDevice8 *device, struct state_test *test, unsigned int ntests)
313 struct event_data arg;
314 unsigned int i;
315 HRESULT hr;
317 struct event read_events[] =
319 {NULL, SB_DATA_INITIAL, SB_DATA_NONE},
322 struct event write_read_events[] =
324 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
325 {NULL, SB_DATA_TEST_ALL, SB_DATA_NONE},
328 struct event abort_stateblock_events[] =
330 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
331 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
332 {delete_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
335 struct event apply_stateblock_events[] =
337 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
338 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
339 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
342 struct event capture_reapply_stateblock_events[] =
344 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
345 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
346 {capture_stateblock, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
347 {apply_stateblock, SB_DATA_DEFAULT, SB_DATA_NONE},
350 struct event create_stateblock_capture_apply_all_events[] =
352 {create_stateblock_all, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
353 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
354 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
357 struct event create_stateblock_apply_all_events[] =
359 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
360 {create_stateblock_all, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
361 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
364 struct event create_stateblock_capture_apply_vertex_events[] =
366 {create_stateblock_vertex, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
367 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
368 {apply_stateblock, SB_DATA_TEST_VERTEX, SB_DATA_NONE},
371 struct event create_stateblock_apply_vertex_events[] =
373 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
374 {create_stateblock_vertex, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
375 {apply_stateblock, SB_DATA_TEST_VERTEX, SB_DATA_NONE},
378 struct event create_stateblock_capture_apply_pixel_events[] =
380 {create_stateblock_pixel, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
381 {capture_stateblock, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
382 {apply_stateblock, SB_DATA_TEST_PIXEL, SB_DATA_NONE},
385 struct event create_stateblock_apply_pixel_events[] =
387 {NULL, SB_DATA_DEFAULT, SB_DATA_TEST_IN},
388 {create_stateblock_pixel, SB_DATA_TEST_ALL, SB_DATA_DEFAULT},
389 {apply_stateblock, SB_DATA_TEST_PIXEL, SB_DATA_NONE},
392 struct event rendertarget_switch_events[] =
394 {NULL, SB_DATA_NONE, SB_DATA_TEST_IN},
395 {switch_render_target, SB_DATA_TEST_ALL, SB_DATA_NONE},
396 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
399 struct event rendertarget_stateblock_events[] =
401 {begin_stateblock, SB_DATA_NONE, SB_DATA_TEST_IN},
402 {switch_render_target, SB_DATA_DEFAULT, SB_DATA_NONE},
403 {end_stateblock, SB_DATA_NONE, SB_DATA_NONE},
404 {revert_render_target, SB_DATA_NONE, SB_DATA_NONE},
405 {apply_stateblock, SB_DATA_TEST_ALL, SB_DATA_NONE},
408 /* Setup each test for execution */
409 for (i = 0; i < ntests; ++i)
411 hr = test[i].init(device, &test[i]);
412 ok(SUCCEEDED(hr), "Test \"%s\" failed setup, aborting\n", test[i].test_name);
413 if (FAILED(hr)) return;
416 trace("Running initial read state tests\n");
417 execute_test_chain(device, test, ntests, read_events, 1, NULL);
419 trace("Running write-read state tests\n");
420 execute_test_chain(device, test, ntests, write_read_events, 2, NULL);
422 trace("Running stateblock abort state tests\n");
423 execute_test_chain(device, test, ntests, abort_stateblock_events, 3, &arg);
425 trace("Running stateblock apply state tests\n");
426 execute_test_chain(device, test, ntests, apply_stateblock_events, 3, &arg);
428 trace("Running stateblock capture/reapply state tests\n");
429 execute_test_chain(device, test, ntests, capture_reapply_stateblock_events, 4, &arg);
431 trace("Running create stateblock capture/apply all state tests\n");
432 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_all_events, 3, &arg);
434 trace("Running create stateblock apply all state tests\n");
435 execute_test_chain(device, test, ntests, create_stateblock_apply_all_events, 3, &arg);
437 trace("Running create stateblock capture/apply vertex state tests\n");
438 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_vertex_events, 3, &arg);
440 trace("Running create stateblock apply vertex state tests\n");
441 execute_test_chain(device, test, ntests, create_stateblock_apply_vertex_events, 3, &arg);
443 trace("Running create stateblock capture/apply pixel state tests\n");
444 execute_test_chain(device, test, ntests, create_stateblock_capture_apply_pixel_events, 3, &arg);
446 trace("Running create stateblock apply pixel state tests\n");
447 execute_test_chain(device, test, ntests, create_stateblock_apply_pixel_events, 3, &arg);
449 trace("Running rendertarget switch state tests\n");
450 execute_test_chain(device, test, ntests, rendertarget_switch_events, 3, &arg);
452 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
453 execute_test_chain(device, test, ntests, rendertarget_stateblock_events, 5, &arg);
455 /* Cleanup resources */
456 for (i = 0; i < ntests; ++i)
458 if (test[i].cleanup) test[i].cleanup(device, &test[i]);
462 /* =================== State test: Pixel and Vertex Shader constants ============ */
464 struct shader_constant_data
466 float float_constant[4]; /* 1x4 float constant */
469 struct shader_constant_arg
471 unsigned int idx;
472 BOOL pshader;
475 static const struct shader_constant_data shader_constant_poison_data =
477 {1.0f, 2.0f, 3.0f, 4.0f},
480 static const struct shader_constant_data shader_constant_default_data =
482 {0.0f, 0.0f, 0.0f, 0.0f},
485 static const struct shader_constant_data shader_constant_test_data =
487 {5.0f, 6.0f, 7.0f, 8.0f},
490 static void shader_constant_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
492 const struct shader_constant_data *scdata = data;
493 const struct shader_constant_arg *scarg = test->test_arg;
494 unsigned int index = scarg->idx;
495 HRESULT hr;
497 if (!scarg->pshader)
499 hr = IDirect3DDevice8_SetVertexShaderConstant(device, index, scdata->float_constant, 1);
500 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
502 else
504 hr = IDirect3DDevice8_SetPixelShaderConstant(device, index, scdata->float_constant, 1);
505 ok(SUCCEEDED(hr), "SetPixelShaderConstant returned %#x.\n", hr);
509 static void shader_constant_check_data(IDirect3DDevice8 *device, const struct state_test *test,
510 const void *expected_data, unsigned int chain_stage)
512 const struct shader_constant_data *scdata = expected_data;
513 const struct shader_constant_arg *scarg = test->test_arg;
514 struct shader_constant_data value;
515 HRESULT hr;
517 value = shader_constant_poison_data;
519 if (!scarg->pshader)
521 hr = IDirect3DDevice8_GetVertexShaderConstant(device, scarg->idx, value.float_constant, 1);
522 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
524 else
526 hr = IDirect3DDevice8_GetPixelShaderConstant(device, scarg->idx, value.float_constant, 1);
527 ok(SUCCEEDED(hr), "GetPixelShaderConstant returned %#x.\n", hr);
530 ok(!memcmp(value.float_constant, scdata->float_constant, sizeof(scdata->float_constant)),
531 "Chain stage %u, %s constant:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e, %.8e} received\n",
532 chain_stage, scarg->pshader ? "pixel shader" : "vertex shader",
533 scdata->float_constant[0], scdata->float_constant[1],
534 scdata->float_constant[2], scdata->float_constant[3],
535 value.float_constant[0], value.float_constant[1],
536 value.float_constant[2], value.float_constant[3]);
539 static HRESULT shader_constant_test_init(IDirect3DDevice8 *device, struct state_test *test)
541 const struct shader_constant_arg *test_arg = test->test_arg;
543 test->test_context = NULL;
544 test->test_data_in = &shader_constant_test_data;
545 test->test_data_out_all = &shader_constant_test_data;
546 if (test_arg->pshader)
548 test->test_data_out_vertex = &shader_constant_default_data;
549 test->test_data_out_pixel = &shader_constant_test_data;
551 else
553 test->test_data_out_vertex = &shader_constant_test_data;
554 test->test_data_out_pixel = &shader_constant_default_data;
556 test->default_data = &shader_constant_default_data;
557 test->initial_data = &shader_constant_default_data;
559 return D3D_OK;
562 static void shader_constants_queue_test(struct state_test *test, const struct shader_constant_arg *test_arg)
564 test->init = shader_constant_test_init;
565 test->cleanup = NULL;
566 test->apply_data = shader_constant_apply_data;
567 test->check_data = shader_constant_check_data;
568 test->test_name = test_arg->pshader ? "set_get_pshader_constants" : "set_get_vshader_constants";
569 test->test_arg = test_arg;
572 /* =================== State test: Lights ===================================== */
574 struct light_data
576 D3DLIGHT8 light;
577 BOOL enabled;
578 HRESULT get_light_result;
579 HRESULT get_enabled_result;
582 struct light_arg
584 unsigned int idx;
587 static const struct light_data light_poison_data =
590 0x1337c0de,
591 {7.0, 4.0, 2.0, 1.0},
592 {7.0, 4.0, 2.0, 1.0},
593 {7.0, 4.0, 2.0, 1.0},
594 {3.3f, 4.4f, 5.5f},
595 {6.6f, 7.7f, 8.8f},
596 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
598 TRUE,
599 0x1337c0de,
600 0x1337c0de,
603 static const struct light_data light_default_data =
606 D3DLIGHT_DIRECTIONAL,
607 {1.0, 1.0, 1.0, 0.0},
608 {0.0, 0.0, 0.0, 0.0},
609 {0.0, 0.0, 0.0, 0.0},
610 {0.0, 0.0, 0.0},
611 {0.0, 0.0, 1.0},
612 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
614 FALSE,
615 D3D_OK,
616 D3D_OK,
619 /* This is used for the initial read state (before a write causes side effects)
620 * The proper return status is D3DERR_INVALIDCALL */
621 static const struct light_data light_initial_data =
624 0x1337c0de,
625 {7.0, 4.0, 2.0, 1.0},
626 {7.0, 4.0, 2.0, 1.0},
627 {7.0, 4.0, 2.0, 1.0},
628 {3.3f, 4.4f, 5.5f},
629 {6.6f, 7.7f, 8.8f},
630 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
632 TRUE,
633 D3DERR_INVALIDCALL,
634 D3DERR_INVALIDCALL,
637 static const struct light_data light_test_data_in =
641 {2.0, 2.0, 2.0, 2.0},
642 {3.0, 3.0, 3.0, 3.0},
643 {4.0, 4.0, 4.0, 4.0},
644 {5.0, 5.0, 5.0},
645 {6.0, 6.0, 6.0},
646 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
648 TRUE,
649 D3D_OK,
650 D3D_OK,
653 /* SetLight will use 128 as the "enabled" value */
654 static const struct light_data light_test_data_out =
658 {2.0, 2.0, 2.0, 2.0},
659 {3.0, 3.0, 3.0, 3.0},
660 {4.0, 4.0, 4.0, 4.0},
661 {5.0, 5.0, 5.0},
662 {6.0, 6.0, 6.0},
663 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
665 128,
666 D3D_OK,
667 D3D_OK,
670 static void light_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
672 const struct light_data *ldata = data;
673 const struct light_arg *larg = test->test_arg;
674 unsigned int index = larg->idx;
675 HRESULT hr;
677 hr = IDirect3DDevice8_SetLight(device, index, &ldata->light);
678 ok(SUCCEEDED(hr), "SetLight returned %#x.\n", hr);
680 hr = IDirect3DDevice8_LightEnable(device, index, ldata->enabled);
681 ok(SUCCEEDED(hr), "SetLightEnable returned %#x.\n", hr);
684 static void light_check_data(IDirect3DDevice8 *device, const struct state_test *test,
685 const void *expected_data, unsigned int chain_stage)
687 const struct light_arg *larg = test->test_arg;
688 const struct light_data *ldata = expected_data;
689 struct light_data value;
691 value = light_poison_data;
693 value.get_enabled_result = IDirect3DDevice8_GetLightEnable(device, larg->idx, &value.enabled);
694 value.get_light_result = IDirect3DDevice8_GetLight(device, larg->idx, &value.light);
696 ok(value.get_enabled_result == ldata->get_enabled_result,
697 "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
698 chain_stage, ldata->get_enabled_result, value.get_enabled_result);
699 ok(value.get_light_result == ldata->get_light_result,
700 "Chain stage %u: expected get_light_result %#x, got %#x.\n",
701 chain_stage, ldata->get_light_result, value.get_light_result);
703 ok(value.enabled == ldata->enabled,
704 "Chain stage %u: expected enabled %#x, got %#x.\n",
705 chain_stage, ldata->enabled, value.enabled);
706 ok(value.light.Type == ldata->light.Type,
707 "Chain stage %u: expected light.Type %#x, got %#x.\n",
708 chain_stage, ldata->light.Type, value.light.Type);
709 ok(!memcmp(&value.light.Diffuse, &ldata->light.Diffuse, sizeof(value.light.Diffuse)),
710 "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
711 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
712 ldata->light.Diffuse.r, ldata->light.Diffuse.g,
713 ldata->light.Diffuse.b, ldata->light.Diffuse.a,
714 value.light.Diffuse.r, value.light.Diffuse.g,
715 value.light.Diffuse.b, value.light.Diffuse.a);
716 ok(!memcmp(&value.light.Specular, &ldata->light.Specular, sizeof(value.light.Specular)),
717 "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
718 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
719 ldata->light.Specular.r, ldata->light.Specular.g,
720 ldata->light.Specular.b, ldata->light.Specular.a,
721 value.light.Specular.r, value.light.Specular.g,
722 value.light.Specular.b, value.light.Specular.a);
723 ok(!memcmp(&value.light.Ambient, &ldata->light.Ambient, sizeof(value.light.Ambient)),
724 "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
725 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage,
726 ldata->light.Ambient.r, ldata->light.Ambient.g,
727 ldata->light.Ambient.b, ldata->light.Ambient.a,
728 value.light.Ambient.r, value.light.Ambient.g,
729 value.light.Ambient.b, value.light.Ambient.a);
730 ok(!memcmp(&value.light.Position, &ldata->light.Position, sizeof(value.light.Position)),
731 "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
732 chain_stage, ldata->light.Position.x, ldata->light.Position.y, ldata->light.Position.z,
733 value.light.Position.x, value.light.Position.y, value.light.Position.z);
734 ok(!memcmp(&value.light.Direction, &ldata->light.Direction, sizeof(value.light.Direction)),
735 "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
736 chain_stage, ldata->light.Direction.x, ldata->light.Direction.y, ldata->light.Direction.z,
737 value.light.Direction.x, value.light.Direction.y, value.light.Direction.z);
738 ok(value.light.Range == ldata->light.Range,
739 "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
740 chain_stage, ldata->light.Range, value.light.Range);
741 ok(value.light.Falloff == ldata->light.Falloff,
742 "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
743 chain_stage, ldata->light.Falloff, value.light.Falloff);
744 ok(value.light.Attenuation0 == ldata->light.Attenuation0,
745 "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
746 chain_stage, ldata->light.Attenuation0, value.light.Attenuation0);
747 ok(value.light.Attenuation1 == ldata->light.Attenuation1,
748 "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
749 chain_stage, ldata->light.Attenuation1, value.light.Attenuation1);
750 ok(value.light.Attenuation2 == ldata->light.Attenuation2,
751 "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
752 chain_stage, ldata->light.Attenuation2, value.light.Attenuation2);
753 ok(value.light.Theta == ldata->light.Theta,
754 "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
755 chain_stage, ldata->light.Theta, value.light.Theta);
756 ok(value.light.Phi == ldata->light.Phi,
757 "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
758 chain_stage, ldata->light.Phi, value.light.Phi);
761 static HRESULT light_test_init(IDirect3DDevice8 *device, struct state_test *test)
763 test->test_context = NULL;
764 test->test_data_in = &light_test_data_in;
765 test->test_data_out_all = &light_test_data_out;
766 test->test_data_out_vertex = &light_test_data_out;
767 test->test_data_out_pixel = &light_default_data;
768 test->default_data = &light_default_data;
769 test->initial_data = &light_initial_data;
771 return D3D_OK;
774 static void lights_queue_test(struct state_test *test, const struct light_arg *test_arg)
776 test->init = light_test_init;
777 test->cleanup = NULL;
778 test->apply_data = light_apply_data;
779 test->check_data = light_check_data;
780 test->test_name = "set_get_light";
781 test->test_arg = test_arg;
784 /* =================== State test: Transforms ===================================== */
786 struct transform_data
788 D3DMATRIX view;
789 D3DMATRIX projection;
790 D3DMATRIX texture0;
791 D3DMATRIX texture7;
792 D3DMATRIX world0;
793 D3DMATRIX world255;
796 static const struct transform_data transform_default_data =
799 1.0f, 0.0f, 0.0f, 0.0f,
800 0.0f, 1.0f, 0.0f, 0.0f,
801 0.0f, 0.0f, 1.0f, 0.0f,
802 0.0f, 0.0f, 0.0f, 1.0f,
803 }}},
805 1.0f, 0.0f, 0.0f, 0.0f,
806 0.0f, 1.0f, 0.0f, 0.0f,
807 0.0f, 0.0f, 1.0f, 0.0f,
808 0.0f, 0.0f, 0.0f, 1.0f,
809 }}},
811 1.0f, 0.0f, 0.0f, 0.0f,
812 0.0f, 1.0f, 0.0f, 0.0f,
813 0.0f, 0.0f, 1.0f, 0.0f,
814 0.0f, 0.0f, 0.0f, 1.0f,
815 }}},
817 1.0f, 0.0f, 0.0f, 0.0f,
818 0.0f, 1.0f, 0.0f, 0.0f,
819 0.0f, 0.0f, 1.0f, 0.0f,
820 0.0f, 0.0f, 0.0f, 1.0f,
821 }}},
823 1.0f, 0.0f, 0.0f, 0.0f,
824 0.0f, 1.0f, 0.0f, 0.0f,
825 0.0f, 0.0f, 1.0f, 0.0f,
826 0.0f, 0.0f, 0.0f, 1.0f,
827 }}},
829 1.0f, 0.0f, 0.0f, 0.0f,
830 0.0f, 1.0f, 0.0f, 0.0f,
831 0.0f, 0.0f, 1.0f, 0.0f,
832 0.0f, 0.0f, 0.0f, 1.0f,
833 }}},
836 static const struct transform_data transform_poison_data =
839 1.0f, 2.0f, 3.0f, 4.0f,
840 5.0f, 6.0f, 7.0f, 8.0f,
841 9.0f, 10.0f, 11.0f, 12.0f,
842 13.0f, 14.0f, 15.0f, 16.0f,
843 }}},
845 17.0f, 18.0f, 19.0f, 20.0f,
846 21.0f, 22.0f, 23.0f, 24.0f,
847 25.0f, 26.0f, 27.0f, 28.0f,
848 29.0f, 30.0f, 31.0f, 32.0f,
849 }}},
851 33.0f, 34.0f, 35.0f, 36.0f,
852 37.0f, 38.0f, 39.0f, 40.0f,
853 41.0f, 42.0f, 43.0f, 44.0f,
854 45.0f, 46.0f, 47.0f, 48.0f,
855 }}},
857 49.0f, 50.0f, 51.0f, 52.0f,
858 53.0f, 54.0f, 55.0f, 56.0f,
859 57.0f, 58.0f, 59.0f, 60.0f,
860 61.0f, 62.0f, 63.0f, 64.0f,
861 }}},
863 64.0f, 66.0f, 67.0f, 68.0f,
864 69.0f, 70.0f, 71.0f, 72.0f,
865 73.0f, 74.0f, 75.0f, 76.0f,
866 77.0f, 78.0f, 79.0f, 80.0f,
867 }}},
869 81.0f, 82.0f, 83.0f, 84.0f,
870 85.0f, 86.0f, 87.0f, 88.0f,
871 89.0f, 90.0f, 91.0f, 92.0f,
872 93.0f, 94.0f, 95.0f, 96.0f,
873 }}},
876 static const struct transform_data transform_test_data =
879 1.2f, 3.4f, -5.6f, 7.2f,
880 10.11f, -12.13f, 14.15f, -1.5f,
881 23.56f, 12.89f, 44.56f, -1.0f,
882 2.3f, 0.0f, 4.4f, 5.5f,
883 }}},
885 9.2f, 38.7f, -6.6f, 7.2f,
886 10.11f, -12.13f, 77.15f, -1.5f,
887 23.56f, 12.89f, 14.56f, -1.0f,
888 12.3f, 0.0f, 4.4f, 5.5f,
889 }}},
891 10.2f, 3.4f, 0.6f, 7.2f,
892 10.11f, -12.13f, 14.15f, -1.5f,
893 23.54f, 12.9f, 44.56f, -1.0f,
894 2.3f, 0.0f, 4.4f, 5.5f,
895 }}},
897 1.2f, 3.4f, -5.6f, 7.2f,
898 10.11f, -12.13f, -14.5f, -1.5f,
899 2.56f, 12.89f, 23.56f, -1.0f,
900 112.3f, 0.0f, 4.4f, 2.5f,
901 }}},
903 1.2f, 31.41f, 58.6f, 7.2f,
904 10.11f, -12.13f, -14.5f, -1.5f,
905 2.56f, 12.89f, 11.56f, -1.0f,
906 112.3f, 0.0f, 44.4f, 2.5f,
907 }}},
910 1.20f, 3.4f, -5.6f, 7.0f,
911 10.11f, -12.156f, -14.5f, -1.5f,
912 2.56f, 1.829f, 23.6f, -1.0f,
913 112.3f, 0.0f, 41.4f, 2.5f,
914 }}},
918 static void transform_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
920 const struct transform_data *tdata = data;
921 HRESULT hr;
923 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &tdata->view);
924 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
926 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &tdata->projection);
927 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
929 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE0, &tdata->texture0);
930 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
932 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &tdata->texture7);
933 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
935 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &tdata->world0);
936 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
938 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(255), &tdata->world255);
939 ok(SUCCEEDED(hr), "SetTransform returned %#x.\n", hr);
942 static void compare_matrix(const char *name, unsigned int chain_stage,
943 const D3DMATRIX *received, const D3DMATRIX *expected)
945 ok(!memcmp(expected, received, sizeof(*expected)),
946 "Chain stage %u, matrix %s:\n"
947 "\t{\n"
948 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
949 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
950 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
951 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
952 "\t} expected\n"
953 "\t{\n"
954 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
955 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
956 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
957 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
958 "\t} received\n",
959 chain_stage, name,
960 U(*expected).m[0][0], U(*expected).m[1][0], U(*expected).m[2][0], U(*expected).m[3][0],
961 U(*expected).m[0][1], U(*expected).m[1][1], U(*expected).m[2][1], U(*expected).m[3][1],
962 U(*expected).m[0][2], U(*expected).m[1][2], U(*expected).m[2][2], U(*expected).m[3][2],
963 U(*expected).m[0][3], U(*expected).m[1][3], U(*expected).m[2][3], U(*expected).m[3][3],
964 U(*received).m[0][0], U(*received).m[1][0], U(*received).m[2][0], U(*received).m[3][0],
965 U(*received).m[0][1], U(*received).m[1][1], U(*received).m[2][1], U(*received).m[3][1],
966 U(*received).m[0][2], U(*received).m[1][2], U(*received).m[2][2], U(*received).m[3][2],
967 U(*received).m[0][3], U(*received).m[1][3], U(*received).m[2][3], U(*received).m[3][3]);
970 static void transform_check_data(IDirect3DDevice8 *device, const struct state_test *test,
971 const void *expected_data, unsigned int chain_stage)
973 const struct transform_data *tdata = expected_data;
974 D3DMATRIX value;
975 HRESULT hr;
977 value = transform_poison_data.view;
978 hr = IDirect3DDevice8_GetTransform(device, D3DTS_VIEW, &value);
979 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
980 compare_matrix("View", chain_stage, &value, &tdata->view);
982 value = transform_poison_data.projection;
983 hr = IDirect3DDevice8_GetTransform(device, D3DTS_PROJECTION, &value);
984 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
985 compare_matrix("Projection", chain_stage, &value, &tdata->projection);
987 value = transform_poison_data.texture0;
988 hr = IDirect3DDevice8_GetTransform(device, D3DTS_TEXTURE0, &value);
989 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
990 compare_matrix("Texture0", chain_stage, &value, &tdata->texture0);
992 value = transform_poison_data.texture7;
993 hr = IDirect3DDevice8_GetTransform(device, D3DTS_TEXTURE0 + texture_stages - 1, &value);
994 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
995 compare_matrix("Texture7", chain_stage, &value, &tdata->texture7);
997 value = transform_poison_data.world0;
998 hr = IDirect3DDevice8_GetTransform(device, D3DTS_WORLD, &value);
999 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1000 compare_matrix("World0", chain_stage, &value, &tdata->world0);
1002 value = transform_poison_data.world255;
1003 hr = IDirect3DDevice8_GetTransform(device, D3DTS_WORLDMATRIX(255), &value);
1004 ok(SUCCEEDED(hr), "GetTransform returned %#x.\n", hr);
1005 compare_matrix("World255", chain_stage, &value, &tdata->world255);
1008 static HRESULT transform_test_init(IDirect3DDevice8 *device, struct state_test *test)
1010 test->test_context = NULL;
1011 test->test_data_in = &transform_test_data;
1012 test->test_data_out_all = &transform_test_data;
1013 test->test_data_out_vertex = &transform_default_data;
1014 test->test_data_out_pixel = &transform_default_data;
1015 test->default_data = &transform_default_data;
1016 test->initial_data = &transform_default_data;
1018 return D3D_OK;
1021 static void transform_queue_test(struct state_test *test)
1023 test->init = transform_test_init;
1024 test->cleanup = NULL;
1025 test->apply_data = transform_apply_data;
1026 test->check_data = transform_check_data;
1027 test->test_name = "set_get_transforms";
1028 test->test_arg = NULL;
1031 /* =================== State test: Render States ===================================== */
1033 const D3DRENDERSTATETYPE render_state_indices[] =
1035 D3DRS_ZENABLE,
1036 D3DRS_FILLMODE,
1037 D3DRS_SHADEMODE,
1038 D3DRS_ZWRITEENABLE,
1039 D3DRS_ALPHATESTENABLE,
1040 D3DRS_LASTPIXEL,
1041 D3DRS_SRCBLEND,
1042 D3DRS_DESTBLEND,
1043 D3DRS_CULLMODE,
1044 D3DRS_ZFUNC,
1045 D3DRS_ALPHAREF,
1046 D3DRS_ALPHAFUNC,
1047 D3DRS_DITHERENABLE,
1048 D3DRS_ALPHABLENDENABLE,
1049 D3DRS_FOGENABLE,
1050 D3DRS_SPECULARENABLE,
1051 D3DRS_FOGCOLOR,
1052 D3DRS_FOGTABLEMODE,
1053 D3DRS_FOGSTART,
1054 D3DRS_FOGEND,
1055 D3DRS_FOGDENSITY,
1056 D3DRS_RANGEFOGENABLE,
1057 D3DRS_STENCILENABLE,
1058 D3DRS_STENCILFAIL,
1059 D3DRS_STENCILZFAIL,
1060 D3DRS_STENCILPASS,
1061 D3DRS_STENCILFUNC,
1062 D3DRS_STENCILREF,
1063 D3DRS_STENCILMASK,
1064 D3DRS_STENCILWRITEMASK,
1065 D3DRS_TEXTUREFACTOR,
1066 D3DRS_WRAP0,
1067 D3DRS_WRAP1,
1068 D3DRS_WRAP2,
1069 D3DRS_WRAP3,
1070 D3DRS_WRAP4,
1071 D3DRS_WRAP5,
1072 D3DRS_WRAP6,
1073 D3DRS_WRAP7,
1074 D3DRS_CLIPPING,
1075 D3DRS_LIGHTING,
1076 D3DRS_AMBIENT,
1077 D3DRS_FOGVERTEXMODE,
1078 D3DRS_COLORVERTEX,
1079 D3DRS_LOCALVIEWER,
1080 D3DRS_NORMALIZENORMALS,
1081 D3DRS_DIFFUSEMATERIALSOURCE,
1082 D3DRS_SPECULARMATERIALSOURCE,
1083 D3DRS_AMBIENTMATERIALSOURCE,
1084 D3DRS_EMISSIVEMATERIALSOURCE,
1085 D3DRS_VERTEXBLEND,
1086 D3DRS_CLIPPLANEENABLE,
1087 #if 0 /* Driver dependent */
1088 D3DRS_POINTSIZE,
1089 #endif
1090 D3DRS_POINTSIZE_MIN,
1091 D3DRS_POINTSPRITEENABLE,
1092 D3DRS_POINTSCALEENABLE,
1093 D3DRS_POINTSCALE_A,
1094 D3DRS_POINTSCALE_B,
1095 D3DRS_POINTSCALE_C,
1096 D3DRS_MULTISAMPLEANTIALIAS,
1097 D3DRS_MULTISAMPLEMASK,
1098 D3DRS_PATCHEDGESTYLE,
1099 #if 0 /* Apparently not recorded in the stateblock */
1100 D3DRS_DEBUGMONITORTOKEN,
1101 #endif
1102 D3DRS_POINTSIZE_MAX,
1103 D3DRS_INDEXEDVERTEXBLENDENABLE,
1104 D3DRS_COLORWRITEENABLE,
1105 D3DRS_TWEENFACTOR,
1106 D3DRS_BLENDOP,
1109 struct render_state_data
1111 DWORD states[sizeof(render_state_indices) / sizeof(*render_state_indices)];
1114 struct render_state_arg
1116 D3DPRESENT_PARAMETERS *device_pparams;
1117 float pointsize_max;
1120 struct render_state_context
1122 struct render_state_data default_data_buffer;
1123 struct render_state_data test_data_all_buffer;
1124 struct render_state_data test_data_vertex_buffer;
1125 struct render_state_data test_data_pixel_buffer;
1126 struct render_state_data poison_data_buffer;
1129 static void render_state_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
1131 const struct render_state_data *rsdata = data;
1132 unsigned int i;
1133 HRESULT hr;
1135 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1137 hr = IDirect3DDevice8_SetRenderState(device, render_state_indices[i], rsdata->states[i]);
1138 ok(SUCCEEDED(hr), "SetRenderState returned %#x.\n", hr);
1142 static void render_state_check_data(IDirect3DDevice8 *device, const struct state_test *test,
1143 const void *expected_data, unsigned int chain_stage)
1145 const struct render_state_context *ctx = test->test_context;
1146 const struct render_state_data *rsdata = expected_data;
1147 unsigned int i;
1148 HRESULT hr;
1150 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1152 DWORD value = ctx->poison_data_buffer.states[i];
1153 hr = IDirect3DDevice8_GetRenderState(device, render_state_indices[i], &value);
1154 ok(SUCCEEDED(hr), "GetRenderState returned %#x.\n", hr);
1155 ok(value == rsdata->states[i], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1156 chain_stage, render_state_indices[i], rsdata->states[i], value);
1160 static inline DWORD to_dword(float fl)
1162 union {float f; DWORD d;} ret;
1164 ret.f = fl;
1165 return ret.d;
1168 static void render_state_default_data_init(const struct render_state_arg *rsarg, struct render_state_data *data)
1170 DWORD zenable = rsarg->device_pparams->EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE;
1171 unsigned int idx = 0;
1173 data->states[idx++] = zenable; /* ZENABLE */
1174 data->states[idx++] = D3DFILL_SOLID; /* FILLMODE */
1175 data->states[idx++] = D3DSHADE_GOURAUD; /* SHADEMODE */
1176 data->states[idx++] = TRUE; /* ZWRITEENABLE */
1177 data->states[idx++] = FALSE; /* ALPHATESTENABLE */
1178 data->states[idx++] = TRUE; /* LASTPIXEL */
1179 data->states[idx++] = D3DBLEND_ONE; /* SRCBLEND */
1180 data->states[idx++] = D3DBLEND_ZERO; /* DESTBLEND */
1181 data->states[idx++] = D3DCULL_CCW; /* CULLMODE */
1182 data->states[idx++] = D3DCMP_LESSEQUAL; /* ZFUNC */
1183 data->states[idx++] = 0; /* ALPHAREF */
1184 data->states[idx++] = D3DCMP_ALWAYS; /* ALPHAFUNC */
1185 data->states[idx++] = FALSE; /* DITHERENABLE */
1186 data->states[idx++] = FALSE; /* ALPHABLENDENABLE */
1187 data->states[idx++] = FALSE; /* FOGENABLE */
1188 data->states[idx++] = FALSE; /* SPECULARENABLE */
1189 data->states[idx++] = 0; /* FOGCOLOR */
1190 data->states[idx++] = D3DFOG_NONE; /* FOGTABLEMODE */
1191 data->states[idx++] = to_dword(0.0f); /* FOGSTART */
1192 data->states[idx++] = to_dword(1.0f); /* FOGEND */
1193 data->states[idx++] = to_dword(1.0f); /* FOGDENSITY */
1194 data->states[idx++] = FALSE; /* RANGEFOGENABLE */
1195 data->states[idx++] = FALSE; /* STENCILENABLE */
1196 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILFAIL */
1197 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILZFAIL */
1198 data->states[idx++] = D3DSTENCILOP_KEEP; /* STENCILPASS */
1199 data->states[idx++] = D3DCMP_ALWAYS; /* STENCILFUNC */
1200 data->states[idx++] = 0; /* STENCILREF */
1201 data->states[idx++] = 0xFFFFFFFF; /* STENCILMASK */
1202 data->states[idx++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1203 data->states[idx++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1204 data->states[idx++] = 0; /* WRAP 0 */
1205 data->states[idx++] = 0; /* WRAP 1 */
1206 data->states[idx++] = 0; /* WRAP 2 */
1207 data->states[idx++] = 0; /* WRAP 3 */
1208 data->states[idx++] = 0; /* WRAP 4 */
1209 data->states[idx++] = 0; /* WRAP 5 */
1210 data->states[idx++] = 0; /* WRAP 6 */
1211 data->states[idx++] = 0; /* WRAP 7 */
1212 data->states[idx++] = TRUE; /* CLIPPING */
1213 data->states[idx++] = TRUE; /* LIGHTING */
1214 data->states[idx++] = 0; /* AMBIENT */
1215 data->states[idx++] = D3DFOG_NONE; /* FOGVERTEXMODE */
1216 data->states[idx++] = TRUE; /* COLORVERTEX */
1217 data->states[idx++] = TRUE; /* LOCALVIEWER */
1218 data->states[idx++] = FALSE; /* NORMALIZENORMALS */
1219 data->states[idx++] = D3DMCS_COLOR1; /* DIFFUSEMATERIALSOURCE */
1220 data->states[idx++] = D3DMCS_COLOR2; /* SPECULARMATERIALSOURCE */
1221 data->states[idx++] = D3DMCS_MATERIAL; /* AMBIENTMATERIALSOURCE */
1222 data->states[idx++] = D3DMCS_MATERIAL; /* EMISSIVEMATERIALSOURCE */
1223 data->states[idx++] = D3DVBF_DISABLE; /* VERTEXBLEND */
1224 data->states[idx++] = 0; /* CLIPPLANEENABLE */
1225 if (0) data->states[idx++] = to_dword(1.0f); /* POINTSIZE, driver dependent, increase array size to enable */
1226 data->states[idx++] = to_dword(0.0f); /* POINTSIZEMIN */
1227 data->states[idx++] = FALSE; /* POINTSPRITEENABLE */
1228 data->states[idx++] = FALSE; /* POINTSCALEENABLE */
1229 data->states[idx++] = to_dword(1.0f); /* POINTSCALE_A */
1230 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_B */
1231 data->states[idx++] = to_dword(0.0f); /* POINTSCALE_C */
1232 data->states[idx++] = TRUE; /* MULTISAMPLEANTIALIAS */
1233 data->states[idx++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1234 data->states[idx++] = D3DPATCHEDGE_DISCRETE; /* PATCHEDGESTYLE */
1235 if (0) data->states[idx++] = 0xbaadcafe; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1236 data->states[idx++] = to_dword(rsarg->pointsize_max); /* POINTSIZE_MAX */
1237 data->states[idx++] = FALSE; /* INDEXEDVERTEXBLENDENABLE */
1238 data->states[idx++] = 0x0000000F; /* COLORWRITEENABLE */
1239 data->states[idx++] = to_dword(0.0f); /* TWEENFACTOR */
1240 data->states[idx++] = D3DBLENDOP_ADD; /* BLENDOP */
1243 static void render_state_poison_data_init(struct render_state_data *data)
1245 unsigned int i;
1247 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1249 data->states[i] = 0x1337c0de;
1253 static void render_state_test_data_init(struct render_state_data *data)
1255 unsigned int idx = 0;
1257 data->states[idx++] = D3DZB_USEW; /* ZENABLE */
1258 data->states[idx++] = D3DFILL_WIREFRAME; /* FILLMODE */
1259 data->states[idx++] = D3DSHADE_PHONG; /* SHADEMODE */
1260 data->states[idx++] = FALSE; /* ZWRITEENABLE */
1261 data->states[idx++] = TRUE; /* ALPHATESTENABLE */
1262 data->states[idx++] = FALSE; /* LASTPIXEL */
1263 data->states[idx++] = D3DBLEND_SRCALPHASAT; /* SRCBLEND */
1264 data->states[idx++] = D3DBLEND_INVDESTALPHA; /* DESTBLEND */
1265 data->states[idx++] = D3DCULL_CW; /* CULLMODE */
1266 data->states[idx++] = D3DCMP_NOTEQUAL; /* ZFUNC */
1267 data->states[idx++] = 10; /* ALPHAREF */
1268 data->states[idx++] = D3DCMP_GREATER; /* ALPHAFUNC */
1269 data->states[idx++] = TRUE; /* DITHERENABLE */
1270 data->states[idx++] = TRUE; /* ALPHABLENDENABLE */
1271 data->states[idx++] = TRUE; /* FOGENABLE */
1272 data->states[idx++] = TRUE; /* SPECULARENABLE */
1273 data->states[idx++] = 1u << 31; /* FOGCOLOR */
1274 data->states[idx++] = D3DFOG_EXP; /* FOGTABLEMODE */
1275 data->states[idx++] = to_dword(0.1f); /* FOGSTART */
1276 data->states[idx++] = to_dword(0.8f); /* FOGEND */
1277 data->states[idx++] = to_dword(0.5f); /* FOGDENSITY */
1278 data->states[idx++] = TRUE; /* RANGEFOGENABLE */
1279 data->states[idx++] = TRUE; /* STENCILENABLE */
1280 data->states[idx++] = D3DSTENCILOP_INCRSAT; /* STENCILFAIL */
1281 data->states[idx++] = D3DSTENCILOP_REPLACE; /* STENCILZFAIL */
1282 data->states[idx++] = D3DSTENCILOP_INVERT; /* STENCILPASS */
1283 data->states[idx++] = D3DCMP_LESS; /* STENCILFUNC */
1284 data->states[idx++] = 10; /* STENCILREF */
1285 data->states[idx++] = 0xFF00FF00; /* STENCILMASK */
1286 data->states[idx++] = 0x00FF00FF; /* STENCILWRITEMASK */
1287 data->states[idx++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1288 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_2; /* WRAP 0 */
1289 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3; /* WRAP 1 */
1290 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 2 */
1291 data->states[idx++] = D3DWRAPCOORD_3 | D3DWRAPCOORD_0; /* WRAP 4 */
1292 data->states[idx++] = D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2; /* WRAP 5 */
1293 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_3 | D3DWRAPCOORD_2; /* WRAP 6 */
1294 data->states[idx++] = D3DWRAPCOORD_2 | D3DWRAPCOORD_1 | D3DWRAPCOORD_0; /* WRAP 7 */
1295 data->states[idx++] = D3DWRAPCOORD_1 | D3DWRAPCOORD_0 | D3DWRAPCOORD_2 | D3DWRAPCOORD_3; /* WRAP 8 */
1296 data->states[idx++] = FALSE; /* CLIPPING */
1297 data->states[idx++] = FALSE; /* LIGHTING */
1298 data->states[idx++] = 255 << 16; /* AMBIENT */
1299 data->states[idx++] = D3DFOG_EXP2; /* FOGVERTEXMODE */
1300 data->states[idx++] = FALSE; /* COLORVERTEX */
1301 data->states[idx++] = FALSE; /* LOCALVIEWER */
1302 data->states[idx++] = TRUE; /* NORMALIZENORMALS */
1303 data->states[idx++] = D3DMCS_COLOR2; /* DIFFUSEMATERIALSOURCE */
1304 data->states[idx++] = D3DMCS_MATERIAL; /* SPECULARMATERIALSOURCE */
1305 data->states[idx++] = D3DMCS_COLOR1; /* AMBIENTMATERIALSOURCE */
1306 data->states[idx++] = D3DMCS_COLOR2; /* EMISSIVEMATERIALSOURCE */
1307 data->states[idx++] = D3DVBF_3WEIGHTS; /* VERTEXBLEND */
1308 data->states[idx++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1309 if (0) data->states[idx++] = to_dword(32.0f);/* POINTSIZE, driver dependent, increase array size to enable */
1310 data->states[idx++] = to_dword(0.7f); /* POINTSIZEMIN */
1311 data->states[idx++] = TRUE; /* POINTSPRITEENABLE */
1312 data->states[idx++] = TRUE; /* POINTSCALEENABLE */
1313 data->states[idx++] = to_dword(0.7f); /* POINTSCALE_A */
1314 data->states[idx++] = to_dword(0.5f); /* POINTSCALE_B */
1315 data->states[idx++] = to_dword(0.4f); /* POINTSCALE_C */
1316 data->states[idx++] = FALSE; /* MULTISAMPLEANTIALIAS */
1317 data->states[idx++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1318 data->states[idx++] = D3DPATCHEDGE_CONTINUOUS; /* PATCHEDGESTYLE */
1319 if (0) data->states[idx++] = D3DDMT_DISABLE; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1320 data->states[idx++] = to_dword(77.0f); /* POINTSIZE_MAX */
1321 data->states[idx++] = TRUE; /* INDEXEDVERTEXBLENDENABLE */
1322 data->states[idx++] = 0x00000009; /* COLORWRITEENABLE */
1323 data->states[idx++] = to_dword(0.2f); /* TWEENFACTOR */
1324 data->states[idx++] = D3DBLENDOP_REVSUBTRACT;/* BLENDOP */
1327 static HRESULT render_state_test_init(IDirect3DDevice8 *device, struct state_test *test)
1329 static const DWORD states_vertex[] =
1331 D3DRS_AMBIENT,
1332 D3DRS_AMBIENTMATERIALSOURCE,
1333 D3DRS_CLIPPING,
1334 D3DRS_CLIPPLANEENABLE,
1335 D3DRS_COLORVERTEX,
1336 D3DRS_CULLMODE,
1337 D3DRS_DIFFUSEMATERIALSOURCE,
1338 D3DRS_EMISSIVEMATERIALSOURCE,
1339 D3DRS_FOGCOLOR,
1340 D3DRS_FOGDENSITY,
1341 D3DRS_FOGENABLE,
1342 D3DRS_FOGEND,
1343 D3DRS_FOGSTART,
1344 D3DRS_FOGTABLEMODE,
1345 D3DRS_FOGVERTEXMODE,
1346 D3DRS_INDEXEDVERTEXBLENDENABLE,
1347 D3DRS_LIGHTING,
1348 D3DRS_LOCALVIEWER,
1349 D3DRS_MULTISAMPLEANTIALIAS,
1350 D3DRS_MULTISAMPLEMASK,
1351 D3DRS_NORMALIZENORMALS,
1352 D3DRS_PATCHEDGESTYLE,
1353 D3DRS_POINTSCALE_A,
1354 D3DRS_POINTSCALE_B,
1355 D3DRS_POINTSCALE_C,
1356 D3DRS_POINTSCALEENABLE,
1357 D3DRS_POINTSIZE,
1358 D3DRS_POINTSIZE_MAX,
1359 D3DRS_POINTSIZE_MIN,
1360 D3DRS_POINTSPRITEENABLE,
1361 D3DRS_RANGEFOGENABLE,
1362 D3DRS_SHADEMODE,
1363 D3DRS_SPECULARENABLE,
1364 D3DRS_SPECULARMATERIALSOURCE,
1365 D3DRS_TWEENFACTOR,
1366 D3DRS_VERTEXBLEND,
1369 static const DWORD states_pixel[] =
1371 D3DRS_ALPHABLENDENABLE,
1372 D3DRS_ALPHAFUNC,
1373 D3DRS_ALPHAREF,
1374 D3DRS_ALPHATESTENABLE,
1375 D3DRS_BLENDOP,
1376 D3DRS_COLORWRITEENABLE,
1377 D3DRS_DESTBLEND,
1378 D3DRS_DITHERENABLE,
1379 D3DRS_FILLMODE,
1380 D3DRS_FOGDENSITY,
1381 D3DRS_FOGEND,
1382 D3DRS_FOGSTART,
1383 D3DRS_LASTPIXEL,
1384 D3DRS_SHADEMODE,
1385 D3DRS_SRCBLEND,
1386 D3DRS_STENCILENABLE,
1387 D3DRS_STENCILFAIL,
1388 D3DRS_STENCILFUNC,
1389 D3DRS_STENCILMASK,
1390 D3DRS_STENCILPASS,
1391 D3DRS_STENCILREF,
1392 D3DRS_STENCILWRITEMASK,
1393 D3DRS_STENCILZFAIL,
1394 D3DRS_TEXTUREFACTOR,
1395 D3DRS_WRAP0,
1396 D3DRS_WRAP1,
1397 D3DRS_WRAP2,
1398 D3DRS_WRAP3,
1399 D3DRS_WRAP4,
1400 D3DRS_WRAP5,
1401 D3DRS_WRAP6,
1402 D3DRS_WRAP7,
1403 D3DRS_ZENABLE,
1404 D3DRS_ZFUNC,
1405 D3DRS_ZWRITEENABLE,
1408 const struct render_state_arg *rsarg = test->test_arg;
1409 unsigned int i, j;
1411 struct render_state_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1412 if (!ctx) return E_FAIL;
1413 test->test_context = ctx;
1415 test->default_data = &ctx->default_data_buffer;
1416 test->initial_data = &ctx->default_data_buffer;
1417 test->test_data_in = &ctx->test_data_all_buffer;
1418 test->test_data_out_all = &ctx->test_data_all_buffer;
1419 test->test_data_out_vertex = &ctx->test_data_vertex_buffer;
1420 test->test_data_out_pixel = &ctx->test_data_pixel_buffer;
1422 render_state_default_data_init(rsarg, &ctx->default_data_buffer);
1423 render_state_test_data_init(&ctx->test_data_all_buffer);
1424 render_state_poison_data_init(&ctx->poison_data_buffer);
1426 for (i = 0; i < sizeof(render_state_indices) / sizeof(*render_state_indices); ++i)
1428 ctx->test_data_vertex_buffer.states[i] = ctx->default_data_buffer.states[i];
1429 for (j = 0; j < sizeof(states_vertex) / sizeof(*states_vertex); ++j)
1431 if (render_state_indices[i] == states_vertex[j])
1433 ctx->test_data_vertex_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1434 break;
1438 ctx->test_data_pixel_buffer.states[i] = ctx->default_data_buffer.states[i];
1439 for (j = 0; j < sizeof(states_pixel) / sizeof(*states_pixel); ++j)
1441 if (render_state_indices[i] == states_pixel[j])
1443 ctx->test_data_pixel_buffer.states[i] = ctx->test_data_all_buffer.states[i];
1444 break;
1449 return D3D_OK;
1452 static void render_state_test_cleanup(IDirect3DDevice8 *device, struct state_test *test)
1454 HeapFree(GetProcessHeap(), 0, test->test_context);
1457 static void render_states_queue_test(struct state_test *test, const struct render_state_arg *test_arg)
1459 test->init = render_state_test_init;
1460 test->cleanup = render_state_test_cleanup;
1461 test->apply_data = render_state_apply_data;
1462 test->check_data = render_state_check_data;
1463 test->test_name = "set_get_render_states";
1464 test->test_arg = test_arg;
1467 /* resource tests */
1469 struct resource_test_arg
1471 DWORD vs_version;
1472 DWORD ps_version;
1473 UINT stream_count;
1474 UINT tex_count;
1477 struct resource_test_data
1479 DWORD vs;
1480 DWORD ps;
1481 IDirect3DIndexBuffer8 *ib;
1482 IDirect3DVertexBuffer8 **vb;
1483 IDirect3DTexture8 **tex;
1486 struct resource_test_context
1488 struct resource_test_data default_data;
1489 struct resource_test_data test_data_all;
1490 struct resource_test_data test_data_vertex;
1491 struct resource_test_data test_data_pixel;
1492 struct resource_test_data poison_data;
1495 static void resource_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
1497 const struct resource_test_arg *arg = test->test_arg;
1498 const struct resource_test_data *d = data;
1499 unsigned int i;
1500 HRESULT hr;
1502 hr = IDirect3DDevice8_SetVertexShader(device, d->vs);
1503 ok(SUCCEEDED(hr), "SetVertexShader (%u) returned %#x.\n", d->vs, hr);
1505 hr = IDirect3DDevice8_SetPixelShader(device, d->ps);
1506 ok(SUCCEEDED(hr), "SetPixelShader (%u) returned %#x.\n", d->ps, hr);
1508 hr = IDirect3DDevice8_SetIndices(device, d->ib, 0);
1509 ok(SUCCEEDED(hr), "SetIndices (%p) returned %#x.\n", d->ib, hr);
1511 for (i = 0; i < arg->stream_count; ++i)
1513 hr = IDirect3DDevice8_SetStreamSource(device, i, d->vb[i], 64);
1514 ok(SUCCEEDED(hr), "SetStreamSource (%u, %p, 64) returned %#x.\n",
1515 i, d->vb[i], hr);
1518 for (i = 0; i < arg->tex_count; ++i)
1520 hr = IDirect3DDevice8_SetTexture(device, i, (IDirect3DBaseTexture8 *)d->tex[i]);
1521 ok(SUCCEEDED(hr), "SetTexture (%u, %p) returned %#x.\n", i, d->tex[i], hr);
1525 static void resource_check_data(IDirect3DDevice8 *device, const struct state_test *test,
1526 const void *expected_data, unsigned int chain_stage)
1528 const struct resource_test_context *ctx = test->test_context;
1529 const struct resource_test_data *poison = &ctx->poison_data;
1530 const struct resource_test_arg *arg = test->test_arg;
1531 const struct resource_test_data *d = expected_data;
1532 unsigned int i;
1533 HRESULT hr;
1534 void *ptr;
1535 DWORD v;
1537 v = poison->vs;
1538 hr = IDirect3DDevice8_GetVertexShader(device, &v);
1539 ok(SUCCEEDED(hr), "GetVertexShader returned %#x.\n", hr);
1540 ok(v == d->vs, "Chain stage %u, expected vertex shader %#x, received %#x.\n",
1541 chain_stage, d->vs, v);
1543 v = poison->ps;
1544 hr = IDirect3DDevice8_GetPixelShader(device, &v);
1545 ok(SUCCEEDED(hr), "GetPixelShader returned %#x.\n", hr);
1546 ok(v == d->ps, "Chain stage %u, expected pixel shader %#x, received %#x.\n",
1547 chain_stage, d->ps, v);
1549 ptr = poison->ib;
1550 hr = IDirect3DDevice8_GetIndices(device, (IDirect3DIndexBuffer8 **)&ptr, &v);
1551 ok(SUCCEEDED(hr), "GetIndices returned %#x.\n", hr);
1552 ok(ptr == d->ib, "Chain stage %u, expected index buffer %p, received %p.\n",
1553 chain_stage, d->ib, ptr);
1554 if (SUCCEEDED(hr) && ptr)
1556 IDirect3DIndexBuffer8_Release((IDirect3DIndexBuffer8 *)ptr);
1559 for (i = 0; i < arg->stream_count; ++i)
1561 ptr = poison->vb[i];
1562 hr = IDirect3DDevice8_GetStreamSource(device, i, (IDirect3DVertexBuffer8 **)&ptr, &v);
1563 ok(SUCCEEDED(hr), "GetStreamSource (%u) returned %#x.\n", i, hr);
1564 ok(ptr == d->vb[i], "Chain stage %u, stream %u, expected vertex buffer %p, received %p.\n",
1565 chain_stage, i, d->vb[i], ptr);
1566 if (SUCCEEDED(hr) && ptr)
1568 IDirect3DIndexBuffer8_Release((IDirect3DVertexBuffer8 *)ptr);
1572 for (i = 0; i < arg->tex_count; ++i)
1574 ptr = poison->tex[i];
1575 hr = IDirect3DDevice8_GetTexture(device, i, (IDirect3DBaseTexture8 **)&ptr);
1576 ok(SUCCEEDED(hr), "SetTexture (%u) returned %#x.\n", i, hr);
1577 ok(ptr == d->tex[i], "Chain stage %u, texture stage %u, expected texture %p, received %p.\n",
1578 chain_stage, i, d->tex[i], ptr);
1579 if (SUCCEEDED(hr) && ptr)
1581 IDirect3DBaseTexture8_Release((IDirect3DBaseTexture8 *)ptr);
1586 static void resource_default_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1588 unsigned int i;
1590 data->vs = 0;
1591 data->ps = 0;
1592 data->ib = NULL;
1593 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1594 for (i = 0; i < arg->stream_count; ++i)
1596 data->vb[i] = NULL;
1598 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1599 for (i = 0; i < arg->tex_count; ++i)
1601 data->tex[i] = NULL;
1605 static void resource_test_data_init(IDirect3DDevice8 *device,
1606 struct resource_test_data *data, const struct resource_test_arg *arg)
1608 static const DWORD vs_code[] =
1610 0xfffe0101, /* vs_1_1 */
1611 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
1612 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
1613 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
1614 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
1615 0x0000ffff, /* END */
1617 static const DWORD ps_code[] =
1619 0xffff0101, /* ps_1_1 */
1620 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
1621 0x00000042, 0xb00f0000, /* tex t0 */
1622 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
1623 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
1624 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
1625 0x0000ffff, /* END */
1627 static const DWORD decl[] =
1629 D3DVSD_STREAM(0),
1630 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
1631 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
1632 D3DVSD_END(),
1635 unsigned int i;
1636 HRESULT hr;
1638 if (arg->vs_version)
1640 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &data->vs, 0);
1641 ok(SUCCEEDED(hr), "CreateVertexShader returned hr %#x.\n", hr);
1644 if (arg->ps_version)
1646 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &data->ps);
1647 ok(SUCCEEDED(hr), "CreatePixelShader returned hr %#x.\n", hr);
1650 hr = IDirect3DDevice8_CreateIndexBuffer(device, 64, D3DUSAGE_DYNAMIC, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &data->ib);
1651 ok(SUCCEEDED(hr), "CreateIndexBuffer returned hr %#x.\n", hr);
1653 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1654 for (i = 0; i < arg->stream_count; ++i)
1656 hr = IDirect3DDevice8_CreateVertexBuffer(device, 64, D3DUSAGE_DYNAMIC,
1657 0, D3DPOOL_DEFAULT, &data->vb[i]);
1658 ok(SUCCEEDED(hr), "CreateVertexBuffer (%u) returned hr %#x.\n", i, hr);
1661 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1662 for (i = 0; i < arg->tex_count; ++i)
1664 hr = IDirect3DDevice8_CreateTexture(device, 64, 64, 0, 0,
1665 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &data->tex[i]);
1666 ok(SUCCEEDED(hr), "CreateTexture (%u) returned hr %#x.\n", i, hr);
1670 static void resource_poison_data_init(struct resource_test_data *data, const struct resource_test_arg *arg)
1672 DWORD_PTR poison = 0xdeadbeef;
1673 unsigned int i;
1675 data->vs = poison++;
1676 data->ps = poison++;
1677 data->ib = (IDirect3DIndexBuffer8 *)poison++;
1678 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1679 for (i = 0; i < arg->stream_count; ++i)
1681 data->vb[i] = (IDirect3DVertexBuffer8 *)poison++;
1683 data->tex = HeapAlloc(GetProcessHeap(), 0, arg->tex_count * sizeof(*data->tex));
1684 for (i = 0; i < arg->tex_count; ++i)
1686 data->tex[i] = (IDirect3DTexture8 *)poison++;
1690 static HRESULT resource_test_init(IDirect3DDevice8 *device, struct state_test *test)
1692 const struct resource_test_arg *arg = test->test_arg;
1693 struct resource_test_context *ctx;
1695 ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx));
1696 if (!ctx) return E_OUTOFMEMORY;
1698 test->test_context = ctx;
1699 test->test_data_in = &ctx->test_data_all;
1700 test->test_data_out_all = &ctx->test_data_all;
1701 test->test_data_out_vertex = &ctx->test_data_vertex;
1702 test->test_data_out_pixel = &ctx->test_data_pixel;
1703 test->default_data = &ctx->default_data;
1704 test->initial_data = &ctx->default_data;
1706 resource_default_data_init(&ctx->default_data, arg);
1707 resource_test_data_init(device, &ctx->test_data_all, arg);
1708 resource_default_data_init(&ctx->test_data_vertex, arg);
1709 resource_default_data_init(&ctx->test_data_pixel, arg);
1710 resource_poison_data_init(&ctx->poison_data, arg);
1712 ctx->test_data_vertex.vs = ctx->test_data_all.vs;
1713 ctx->test_data_pixel.ps = ctx->test_data_all.ps;
1715 return D3D_OK;
1718 static void resource_test_cleanup(IDirect3DDevice8 *device, struct state_test *test)
1720 struct resource_test_context *ctx = test->test_context;
1721 const struct resource_test_arg *arg = test->test_arg;
1722 unsigned int i;
1723 HRESULT hr;
1725 resource_apply_data(device, test, &ctx->default_data);
1727 if (ctx->test_data_all.vs)
1729 hr = IDirect3DDevice8_DeleteVertexShader(device, ctx->test_data_all.vs);
1730 ok(SUCCEEDED(hr), "DeleteVertexShader (%u) returned %#x.\n", ctx->test_data_all.vs, hr);
1733 if (ctx->test_data_all.ps)
1735 hr = IDirect3DDevice8_DeletePixelShader(device, ctx->test_data_all.ps);
1736 ok(SUCCEEDED(hr), "DeletePixelShader (%u) returned %#x.\n", ctx->test_data_all.ps, hr);
1739 IDirect3DIndexBuffer8_Release(ctx->test_data_all.ib);
1740 for (i = 0; i < arg->stream_count; ++i)
1742 IDirect3DVertexBuffer8_Release(ctx->test_data_all.vb[i]);
1745 for (i = 0; i < arg->tex_count; ++i)
1747 IDirect3DBaseTexture8_Release(ctx->test_data_all.tex[i]);
1750 HeapFree(GetProcessHeap(), 0, ctx->default_data.vb);
1751 HeapFree(GetProcessHeap(), 0, ctx->default_data.tex);
1752 HeapFree(GetProcessHeap(), 0, ctx->test_data_all.vb);
1753 HeapFree(GetProcessHeap(), 0, ctx->test_data_all.tex);
1754 HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.vb);
1755 HeapFree(GetProcessHeap(), 0, ctx->test_data_vertex.tex);
1756 HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.vb);
1757 HeapFree(GetProcessHeap(), 0, ctx->test_data_pixel.tex);
1758 HeapFree(GetProcessHeap(), 0, ctx->poison_data.vb);
1759 HeapFree(GetProcessHeap(), 0, ctx->poison_data.tex);
1760 HeapFree(GetProcessHeap(), 0, ctx);
1763 static void resource_test_queue(struct state_test *test, const struct resource_test_arg *test_arg)
1765 test->init = resource_test_init;
1766 test->cleanup = resource_test_cleanup;
1767 test->apply_data = resource_apply_data;
1768 test->check_data = resource_check_data;
1769 test->test_name = "set_get_resources";
1770 test->test_arg = test_arg;
1773 /* =================== Main state tests function =============================== */
1775 static void test_state_management(void)
1777 struct shader_constant_arg pshader_constant_arg;
1778 struct shader_constant_arg vshader_constant_arg;
1779 struct resource_test_arg resource_test_arg;
1780 struct render_state_arg render_state_arg;
1781 D3DPRESENT_PARAMETERS present_parameters;
1782 struct light_arg light_arg;
1783 IDirect3DDevice8 *device;
1784 IDirect3D8 *d3d;
1785 ULONG refcount;
1786 D3DCAPS8 caps;
1787 HWND window;
1788 HRESULT hr;
1790 /* Test count: 2 for shader constants
1791 * 1 for lights
1792 * 1 for transforms
1793 * 1 for render states
1794 * 1 for resources
1796 struct state_test tests[6];
1797 unsigned int tcount = 0;
1799 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW,
1800 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1801 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
1803 skip("Failed to create a D3D object, skipping tests.\n");
1804 DestroyWindow(window);
1805 return;
1807 memset(&present_parameters, 0, sizeof(present_parameters));
1808 present_parameters.Windowed = TRUE;
1809 present_parameters.hDeviceWindow = window;
1810 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1811 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
1812 if (FAILED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
1813 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
1815 skip("Failed to create a 3D device, skipping test.\n");
1816 IDirect3D8_Release(d3d);
1817 DestroyWindow(window);
1818 return;
1821 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1822 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1824 texture_stages = caps.MaxTextureBlendStages;
1826 /* Zero test memory */
1827 memset(tests, 0, sizeof(tests));
1829 if (caps.VertexShaderVersion & 0xffff)
1831 vshader_constant_arg.idx = 0;
1832 vshader_constant_arg.pshader = FALSE;
1833 shader_constants_queue_test(&tests[tcount++], &vshader_constant_arg);
1836 if (caps.PixelShaderVersion & 0xffff)
1838 pshader_constant_arg.idx = 0;
1839 pshader_constant_arg.pshader = TRUE;
1840 shader_constants_queue_test(&tests[tcount++], &pshader_constant_arg);
1843 light_arg.idx = 0;
1844 lights_queue_test(&tests[tcount++], &light_arg);
1846 transform_queue_test(&tests[tcount++]);
1848 render_state_arg.device_pparams = &present_parameters;
1849 render_state_arg.pointsize_max = caps.MaxPointSize;
1850 render_states_queue_test(&tests[tcount++], &render_state_arg);
1852 resource_test_arg.vs_version = caps.VertexShaderVersion & 0xffff;
1853 resource_test_arg.ps_version = caps.PixelShaderVersion & 0xffff;
1854 resource_test_arg.stream_count = caps.MaxStreams;
1855 resource_test_arg.tex_count = caps.MaxTextureBlendStages;
1856 resource_test_queue(&tests[tcount++], &resource_test_arg);
1858 execute_test_chain_all(device, tests, tcount);
1860 refcount = IDirect3DDevice8_Release(device);
1861 ok(!refcount, "Device has %u references left\n", refcount);
1862 IDirect3D8_Release(d3d);
1863 DestroyWindow(window);
1866 START_TEST(stateblock)
1868 test_state_management();