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