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 /* ============================ State Testing Framework ========================== */
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
,
54 void (*check_data
)(IDirect3DDevice8
*device
, const struct state_test
*test
,
55 const void *data_expected
, unsigned int chain_stage
);
60 /* Test-specific context data */
64 /* See below for explanation of the flags */
66 #define EVENT_ERROR -1
71 IDirect3DSurface8
*original_render_target
;
72 IDirect3DSwapChain8
*new_swap_chain
;
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
)
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
;
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
)
128 /* For each queued event */
129 for (j
= 0; j
< nevents
; ++j
)
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
);
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
;
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
;
209 if (backbuffer
) IDirect3DSurface8_Release(backbuffer
);
210 if (swapchain
) IDirect3DSwapChain8_Release(swapchain
);
214 static int revert_render_target(IDirect3DDevice8
*device
, struct event_data
*event_data
)
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
);
223 IDirect3DSurface8_Release(event_data
->original_render_target
);
227 IDirect3DSurface8_Release(event_data
->original_render_target
);
228 IDirect3DSwapChain8_Release(event_data
->new_swap_chain
);
232 static int create_stateblock_all(IDirect3DDevice8
*device
, struct event_data
*event_data
)
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
;
242 static int create_stateblock_vertex(IDirect3DDevice8
*device
, struct event_data
*event_data
)
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
;
252 static int create_stateblock_pixel(IDirect3DDevice8
*device
, struct event_data
*event_data
)
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
;
262 static int begin_stateblock(IDirect3DDevice8
*device
, struct event_data
*event_data
)
266 hr
= IDirect3DDevice8_BeginStateBlock(device
);
267 ok(SUCCEEDED(hr
), "BeginStateBlock returned %#x.\n", hr
);
268 if (FAILED(hr
)) return EVENT_ERROR
;
272 static int end_stateblock(IDirect3DDevice8
*device
, struct event_data
*event_data
)
276 hr
= IDirect3DDevice8_EndStateBlock(device
, &event_data
->stateblock
);
277 ok(SUCCEEDED(hr
), "EndStateBlock returned %#x.\n", hr
);
278 if (FAILED(hr
)) return EVENT_ERROR
;
282 static int delete_stateblock(IDirect3DDevice8
*device
, struct event_data
*event_data
)
284 IDirect3DDevice8_DeleteStateBlock(device
, event_data
->stateblock
);
288 static int apply_stateblock(IDirect3DDevice8
*device
, struct event_data
*event_data
)
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
;
300 static int capture_stateblock(IDirect3DDevice8
*device
, struct event_data
*event_data
)
304 hr
= IDirect3DDevice8_CaptureStateBlock(device
, event_data
->stateblock
);
305 ok(SUCCEEDED(hr
), "Capture returned %#x.\n", hr
);
306 if (FAILED(hr
)) return EVENT_ERROR
;
311 static void execute_test_chain_all(IDirect3DDevice8
*device
, struct state_test
*test
, unsigned int ntests
)
313 struct event_data arg
;
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
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
;
499 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, index
, scdata
->float_constant
, 1);
500 ok(SUCCEEDED(hr
), "SetVertexShaderConstant returned %#x.\n", hr
);
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
;
517 value
= shader_constant_poison_data
;
521 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, scarg
->idx
, value
.float_constant
, 1);
522 ok(SUCCEEDED(hr
), "GetVertexShaderConstant returned %#x.\n", hr
);
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
;
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
;
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 ===================================== */
578 HRESULT get_light_result
;
579 HRESULT get_enabled_result
;
587 static const struct light_data light_poison_data
=
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},
596 12.12f
, 13.13f
, 14.14f
, 15.15f
, 16.16f
, 17.17f
, 18.18f
,
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},
612 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
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
=
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},
630 12.12f
, 13.13f
, 14.14f
, 15.15f
, 16.16f
, 17.17f
, 18.18f
,
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},
646 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
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},
663 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
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
;
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
;
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
789 D3DMATRIX projection
;
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
918 static void transform_apply_data(IDirect3DDevice8
*device
, const struct state_test
*test
, const void *data
)
920 const struct transform_data
*tdata
= data
;
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"
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"
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"
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
;
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
;
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
[] =
1039 D3DRS_ALPHATESTENABLE
,
1048 D3DRS_ALPHABLENDENABLE
,
1050 D3DRS_SPECULARENABLE
,
1056 D3DRS_RANGEFOGENABLE
,
1057 D3DRS_STENCILENABLE
,
1064 D3DRS_STENCILWRITEMASK
,
1065 D3DRS_TEXTUREFACTOR
,
1077 D3DRS_FOGVERTEXMODE
,
1080 D3DRS_NORMALIZENORMALS
,
1081 D3DRS_DIFFUSEMATERIALSOURCE
,
1082 D3DRS_SPECULARMATERIALSOURCE
,
1083 D3DRS_AMBIENTMATERIALSOURCE
,
1084 D3DRS_EMISSIVEMATERIALSOURCE
,
1086 D3DRS_CLIPPLANEENABLE
,
1087 #if 0 /* Driver dependent */
1090 D3DRS_POINTSIZE_MIN
,
1091 D3DRS_POINTSPRITEENABLE
,
1092 D3DRS_POINTSCALEENABLE
,
1096 D3DRS_MULTISAMPLEANTIALIAS
,
1097 D3DRS_MULTISAMPLEMASK
,
1098 D3DRS_PATCHEDGESTYLE
,
1099 #if 0 /* Apparently not recorded in the stateblock */
1100 D3DRS_DEBUGMONITORTOKEN
,
1102 D3DRS_POINTSIZE_MAX
,
1103 D3DRS_INDEXEDVERTEXBLENDENABLE
,
1104 D3DRS_COLORWRITEENABLE
,
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
;
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
;
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
;
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
)
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
[] =
1332 D3DRS_AMBIENTMATERIALSOURCE
,
1334 D3DRS_CLIPPLANEENABLE
,
1337 D3DRS_DIFFUSEMATERIALSOURCE
,
1338 D3DRS_EMISSIVEMATERIALSOURCE
,
1345 D3DRS_FOGVERTEXMODE
,
1346 D3DRS_INDEXEDVERTEXBLENDENABLE
,
1349 D3DRS_MULTISAMPLEANTIALIAS
,
1350 D3DRS_MULTISAMPLEMASK
,
1351 D3DRS_NORMALIZENORMALS
,
1352 D3DRS_PATCHEDGESTYLE
,
1356 D3DRS_POINTSCALEENABLE
,
1358 D3DRS_POINTSIZE_MAX
,
1359 D3DRS_POINTSIZE_MIN
,
1360 D3DRS_POINTSPRITEENABLE
,
1361 D3DRS_RANGEFOGENABLE
,
1363 D3DRS_SPECULARENABLE
,
1364 D3DRS_SPECULARMATERIALSOURCE
,
1369 static const DWORD states_pixel
[] =
1371 D3DRS_ALPHABLENDENABLE
,
1374 D3DRS_ALPHATESTENABLE
,
1376 D3DRS_COLORWRITEENABLE
,
1386 D3DRS_STENCILENABLE
,
1392 D3DRS_STENCILWRITEMASK
,
1394 D3DRS_TEXTUREFACTOR
,
1408 const struct render_state_arg
*rsarg
= test
->test_arg
;
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
];
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
];
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
1477 struct resource_test_data
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
;
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",
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
;
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
);
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
);
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
)
1593 data
->vb
= HeapAlloc(GetProcessHeap(), 0, arg
->stream_count
* sizeof(*data
->vb
));
1594 for (i
= 0; i
< arg
->stream_count
; ++i
)
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
[] =
1630 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
1631 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
),
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;
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
;
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
;
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
;
1790 /* Test count: 2 for shader constants
1793 * 1 for render states
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
);
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
);
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
);
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();