2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2006 Ivan Gyurdiev
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
)(IDirect3DDevice9
*device
, struct state_test
*test
);
51 void (*cleanup
)(IDirect3DDevice9
*device
, struct state_test
*test
);
52 void (*apply_data
)(IDirect3DDevice9
*device
, const struct state_test
*test
,
54 void (*check_data
)(IDirect3DDevice9
*device
, const struct state_test
*test
,
55 const void *expected_data
, unsigned int chain_stage
, DWORD quirk
);
60 /* Test-specific context data */
65 #define EVENT_ERROR -1
67 /* Apparently recorded stateblocks record and apply vertex declarations,
68 * but don't capture them */
69 #define SB_QUIRK_RECORDED_VDECL_CAPTURE 0x00000001
73 IDirect3DStateBlock9
*stateblock
;
74 IDirect3DSurface9
*original_render_target
;
75 IDirect3DSwapChain9
*new_swap_chain
;
91 int (*event_fn
)(IDirect3DDevice9
*device
, struct event_data
*event_data
);
92 enum stateblock_data check
;
93 enum stateblock_data apply
;
97 static const void *get_event_data(const struct state_test
*test
, enum stateblock_data data
)
101 case SB_DATA_DEFAULT
:
102 return test
->default_data
;
104 case SB_DATA_INITIAL
:
105 return test
->initial_data
;
107 case SB_DATA_TEST_IN
:
108 return test
->test_data_in
;
110 case SB_DATA_TEST_ALL
:
111 return test
->test_data_out_all
;
113 case SB_DATA_TEST_VERTEX
:
114 return test
->test_data_out_vertex
;
116 case SB_DATA_TEST_PIXEL
:
117 return test
->test_data_out_pixel
;
124 /* This is an event-machine, which tests things.
125 * It tests get and set operations for a batch of states, based on
126 * results from the event function, which directs what's to be done */
128 static void execute_test_chain(IDirect3DDevice9
*device
, struct state_test
*test
,
129 unsigned int ntests
, struct event
*event
, unsigned int nevents
, struct event_data
*event_data
)
133 /* For each queued event */
134 for (j
= 0; j
< nevents
; ++j
)
138 /* Execute the next event handler (if available). */
139 if (event
[j
].event_fn
)
141 if (event
[j
].event_fn(device
, event_data
) == EVENT_ERROR
)
143 trace("Stage %u in error state, aborting.\n", j
);
148 if (event
[j
].check
!= SB_DATA_NONE
)
150 for (i
= 0; i
< ntests
; ++i
)
152 data
= get_event_data(&test
[i
], event
[j
].check
);
153 test
[i
].check_data(device
, &test
[i
], data
, j
, event
[j
].quirk
);
157 if (event
[j
].apply
!= SB_DATA_NONE
)
159 for (i
= 0; i
< ntests
; ++i
)
161 data
= get_event_data(&test
[i
], event
[j
].apply
);
162 test
[i
].apply_data(device
, &test
[i
], data
);
167 /* Attempt to reset any changes made. */
168 for (i
= 0; i
< ntests
; ++i
)
170 test
[i
].apply_data(device
, &test
[i
], test
[i
].default_data
);
174 static int switch_render_target(IDirect3DDevice9
*device
, struct event_data
*event_data
)
177 D3DPRESENT_PARAMETERS present_parameters
;
178 IDirect3DSwapChain9
* swapchain
= NULL
;
179 IDirect3DSurface9
* backbuffer
= NULL
;
181 /* Parameters for new swapchain */
182 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
183 present_parameters
.Windowed
= TRUE
;
184 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
186 /* Create new swapchain */
187 hret
= IDirect3DDevice9_CreateAdditionalSwapChain(device
, &present_parameters
, &swapchain
);
188 ok (hret
== D3D_OK
, "CreateAdditionalSwapChain returned %#x.\n", hret
);
189 if (hret
!= D3D_OK
) goto error
;
191 /* Get its backbuffer */
192 hret
= IDirect3DSwapChain9_GetBackBuffer(swapchain
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
193 ok (hret
== D3D_OK
, "GetBackBuffer returned %#x.\n", hret
);
194 if (hret
!= D3D_OK
) goto error
;
196 /* Save the current render target */
197 hret
= IDirect3DDevice9_GetRenderTarget(device
, 0, &event_data
->original_render_target
);
198 ok (hret
== D3D_OK
, "GetRenderTarget returned %#x.\n", hret
);
199 if (hret
!= D3D_OK
) goto error
;
201 /* Set the new swapchain's backbuffer as a render target */
202 hret
= IDirect3DDevice9_SetRenderTarget(device
, 0, backbuffer
);
203 ok (hret
== D3D_OK
, "SetRenderTarget returned %#x.\n", hret
);
204 if (hret
!= D3D_OK
) goto error
;
206 IDirect3DSurface9_Release(backbuffer
);
207 event_data
->new_swap_chain
= swapchain
;
211 if (backbuffer
) IDirect3DSurface9_Release(backbuffer
);
212 if (swapchain
) IDirect3DSwapChain9_Release(swapchain
);
216 static int revert_render_target(IDirect3DDevice9
*device
, struct event_data
*event_data
)
220 /* Reset the old render target */
221 hret
= IDirect3DDevice9_SetRenderTarget(device
, 0, event_data
->original_render_target
);
222 ok (hret
== D3D_OK
, "SetRenderTarget returned %#x.\n", hret
);
223 if (hret
!= D3D_OK
) {
224 IDirect3DSurface9_Release(event_data
->original_render_target
);
228 IDirect3DSurface9_Release(event_data
->original_render_target
);
229 IDirect3DSwapChain9_Release(event_data
->new_swap_chain
);
234 static int create_stateblock_all(IDirect3DDevice9
*device
, struct event_data
*event_data
)
238 hr
= IDirect3DDevice9_CreateStateBlock(device
, D3DSBT_ALL
, &event_data
->stateblock
);
239 ok(SUCCEEDED(hr
), "CreateStateBlock returned %#x.\n", hr
);
240 if (FAILED(hr
)) return EVENT_ERROR
;
244 static int create_stateblock_vertex(IDirect3DDevice9
*device
, struct event_data
*event_data
)
248 hr
= IDirect3DDevice9_CreateStateBlock(device
, D3DSBT_VERTEXSTATE
, &event_data
->stateblock
);
249 ok(SUCCEEDED(hr
), "CreateStateBlock returned %#x.\n", hr
);
250 if (FAILED(hr
)) return EVENT_ERROR
;
254 static int create_stateblock_pixel(IDirect3DDevice9
*device
, struct event_data
*event_data
)
258 hr
= IDirect3DDevice9_CreateStateBlock(device
, D3DSBT_PIXELSTATE
, &event_data
->stateblock
);
259 ok(SUCCEEDED(hr
), "CreateStateBlock returned %#x.\n", hr
);
260 if (FAILED(hr
)) return EVENT_ERROR
;
264 static int begin_stateblock(IDirect3DDevice9
*device
, struct event_data
*event_data
)
268 hret
= IDirect3DDevice9_BeginStateBlock(device
);
269 ok(hret
== D3D_OK
, "BeginStateBlock returned %#x.\n", hret
);
270 if (hret
!= D3D_OK
) return EVENT_ERROR
;
274 static int end_stateblock(IDirect3DDevice9
*device
, struct event_data
*event_data
)
278 hret
= IDirect3DDevice9_EndStateBlock(device
, &event_data
->stateblock
);
279 ok(hret
== D3D_OK
, "EndStateBlock returned %#x.\n", hret
);
280 if (hret
!= D3D_OK
) return EVENT_ERROR
;
284 static int release_stateblock(IDirect3DDevice9
*device
, struct event_data
*event_data
)
286 IDirect3DStateBlock9_Release(event_data
->stateblock
);
290 static int apply_stateblock(IDirect3DDevice9
*device
, struct event_data
*event_data
)
294 hret
= IDirect3DStateBlock9_Apply(event_data
->stateblock
);
295 ok(hret
== D3D_OK
, "Apply returned %#x.\n", hret
);
296 if (hret
!= D3D_OK
) {
297 IDirect3DStateBlock9_Release(event_data
->stateblock
);
301 IDirect3DStateBlock9_Release(event_data
->stateblock
);
306 static int capture_stateblock(IDirect3DDevice9
*device
, struct event_data
*event_data
)
310 hret
= IDirect3DStateBlock9_Capture(event_data
->stateblock
);
311 ok(hret
== D3D_OK
, "Capture returned %#x.\n", hret
);
318 static void execute_test_chain_all(IDirect3DDevice9
*device
, struct state_test
*test
, unsigned int ntests
)
320 struct event_data arg
;
324 struct event read_events
[] =
326 {NULL
, SB_DATA_INITIAL
, SB_DATA_NONE
},
329 struct event write_read_events
[] =
331 {NULL
, SB_DATA_NONE
, SB_DATA_TEST_IN
},
332 {NULL
, SB_DATA_TEST_ALL
, SB_DATA_NONE
},
335 struct event abort_stateblock_events
[] =
337 {begin_stateblock
, SB_DATA_NONE
, SB_DATA_TEST_IN
},
338 {end_stateblock
, SB_DATA_NONE
, SB_DATA_NONE
},
339 {release_stateblock
, SB_DATA_DEFAULT
, SB_DATA_NONE
},
342 struct event apply_stateblock_events
[] =
344 {begin_stateblock
, SB_DATA_NONE
, SB_DATA_TEST_IN
},
345 {end_stateblock
, SB_DATA_NONE
, SB_DATA_NONE
},
346 {apply_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_NONE
},
349 struct event capture_reapply_stateblock_events
[] =
351 {begin_stateblock
, SB_DATA_NONE
, SB_DATA_TEST_IN
},
352 {end_stateblock
, SB_DATA_NONE
, SB_DATA_NONE
},
353 {capture_stateblock
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
354 {apply_stateblock
, SB_DATA_DEFAULT
, SB_DATA_NONE
, SB_QUIRK_RECORDED_VDECL_CAPTURE
},
357 struct event create_stateblock_capture_apply_all_events
[] =
359 {create_stateblock_all
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
360 {capture_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_DEFAULT
},
361 {apply_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_NONE
},
364 struct event create_stateblock_apply_all_events
[] =
366 {NULL
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
367 {create_stateblock_all
, SB_DATA_TEST_ALL
, SB_DATA_DEFAULT
},
368 {apply_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_NONE
},
371 struct event create_stateblock_capture_apply_vertex_events
[] =
373 {create_stateblock_vertex
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
374 {capture_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_DEFAULT
},
375 {apply_stateblock
, SB_DATA_TEST_VERTEX
, SB_DATA_NONE
},
378 struct event create_stateblock_apply_vertex_events
[] =
380 {NULL
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
381 {create_stateblock_vertex
, SB_DATA_TEST_ALL
, SB_DATA_DEFAULT
},
382 {apply_stateblock
, SB_DATA_TEST_VERTEX
, SB_DATA_NONE
},
385 struct event create_stateblock_capture_apply_pixel_events
[] =
387 {create_stateblock_pixel
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
388 {capture_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_DEFAULT
},
389 {apply_stateblock
, SB_DATA_TEST_PIXEL
, SB_DATA_NONE
},
392 struct event create_stateblock_apply_pixel_events
[] =
394 {NULL
, SB_DATA_DEFAULT
, SB_DATA_TEST_IN
},
395 {create_stateblock_pixel
, SB_DATA_TEST_ALL
, SB_DATA_DEFAULT
},
396 {apply_stateblock
, SB_DATA_TEST_PIXEL
, SB_DATA_NONE
},
399 struct event rendertarget_switch_events
[] =
401 {NULL
, SB_DATA_NONE
, SB_DATA_TEST_IN
},
402 {switch_render_target
, SB_DATA_TEST_ALL
, SB_DATA_NONE
},
403 {revert_render_target
, SB_DATA_NONE
, SB_DATA_NONE
},
406 struct event rendertarget_stateblock_events
[] =
408 {begin_stateblock
, SB_DATA_NONE
, SB_DATA_TEST_IN
},
409 {switch_render_target
, SB_DATA_DEFAULT
, SB_DATA_NONE
},
410 {end_stateblock
, SB_DATA_NONE
, SB_DATA_NONE
},
411 {revert_render_target
, SB_DATA_NONE
, SB_DATA_NONE
},
412 {apply_stateblock
, SB_DATA_TEST_ALL
, SB_DATA_NONE
},
415 /* Setup each test for execution */
416 for (i
= 0; i
< ntests
; ++i
)
418 hr
= test
[i
].init(device
, &test
[i
]);
419 ok(SUCCEEDED(hr
), "Test \"%s\" failed setup, aborting\n", test
[i
].test_name
);
420 if (FAILED(hr
)) return;
423 trace("Running initial read state tests\n");
424 execute_test_chain(device
, test
, ntests
, read_events
, 1, NULL
);
426 trace("Running write-read state tests\n");
427 execute_test_chain(device
, test
, ntests
, write_read_events
, 2, NULL
);
429 trace("Running stateblock abort state tests\n");
430 execute_test_chain(device
, test
, ntests
, abort_stateblock_events
, 3, &arg
);
432 trace("Running stateblock apply state tests\n");
433 execute_test_chain(device
, test
, ntests
, apply_stateblock_events
, 3, &arg
);
435 trace("Running stateblock capture/reapply state tests\n");
436 execute_test_chain(device
, test
, ntests
, capture_reapply_stateblock_events
, 4, &arg
);
438 trace("Running create stateblock capture/apply all state tests\n");
439 execute_test_chain(device
, test
, ntests
, create_stateblock_capture_apply_all_events
, 3, &arg
);
441 trace("Running create stateblock apply state all tests\n");
442 execute_test_chain(device
, test
, ntests
, create_stateblock_apply_all_events
, 3, &arg
);
444 trace("Running create stateblock capture/apply vertex state tests\n");
445 execute_test_chain(device
, test
, ntests
, create_stateblock_capture_apply_vertex_events
, 3, &arg
);
447 trace("Running create stateblock apply vertex state tests\n");
448 execute_test_chain(device
, test
, ntests
, create_stateblock_apply_vertex_events
, 3, &arg
);
450 trace("Running create stateblock capture/apply pixel state tests\n");
451 execute_test_chain(device
, test
, ntests
, create_stateblock_capture_apply_pixel_events
, 3, &arg
);
453 trace("Running create stateblock apply pixel state tests\n");
454 execute_test_chain(device
, test
, ntests
, create_stateblock_apply_pixel_events
, 3, &arg
);
456 trace("Running rendertarget switch state tests\n");
457 execute_test_chain(device
, test
, ntests
, rendertarget_switch_events
, 3, &arg
);
459 trace("Running stateblock apply over rendertarget switch interrupt tests\n");
460 execute_test_chain(device
, test
, ntests
, rendertarget_stateblock_events
, 5, &arg
);
462 /* Cleanup resources */
463 for (i
= 0; i
< ntests
; ++i
)
465 if (test
[i
].cleanup
) test
[i
].cleanup(device
, &test
[i
]);
469 /* =================== State test: Pixel and Vertex Shader constants ============ */
471 struct shader_constant_data
473 int int_constant
[4]; /* 1x4 integer constant */
474 float float_constant
[4]; /* 1x4 float constant */
475 BOOL bool_constant
[4]; /* 4x1 boolean constants */
478 struct shader_constant_arg
484 static const struct shader_constant_data shader_constant_poison_data
=
486 {0x1337c0de, 0x1337c0de, 0x1337c0de, 0x1337c0de},
487 {1.0f
, 2.0f
, 3.0f
, 4.0f
},
488 {FALSE
, TRUE
, FALSE
, TRUE
},
491 static const struct shader_constant_data shader_constant_default_data
=
494 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
498 static const struct shader_constant_data shader_constant_test_data
=
500 {0xdead0000, 0xdead0001, 0xdead0002, 0xdead0003},
501 {5.0f
, 6.0f
, 7.0f
, 8.0f
},
502 {TRUE
, FALSE
, FALSE
, TRUE
},
505 static void shader_constant_apply_data(IDirect3DDevice9
*device
, const struct state_test
*test
, const void *data
)
507 const struct shader_constant_arg
*scarg
= test
->test_arg
;
508 const struct shader_constant_data
*scdata
= data
;
510 unsigned int index
= scarg
->idx
;
512 if (!scarg
->pshader
) {
513 hret
= IDirect3DDevice9_SetVertexShaderConstantI(device
, index
, scdata
->int_constant
, 1);
514 ok(hret
== D3D_OK
, "SetVertexShaderConstantI returned %#x.\n", hret
);
515 hret
= IDirect3DDevice9_SetVertexShaderConstantF(device
, index
, scdata
->float_constant
, 1);
516 ok(hret
== D3D_OK
, "SetVertexShaderConstantF returned %#x.\n", hret
);
517 hret
= IDirect3DDevice9_SetVertexShaderConstantB(device
, index
, scdata
->bool_constant
, 4);
518 ok(hret
== D3D_OK
, "SetVertexShaderConstantB returned %#x.\n", hret
);
521 hret
= IDirect3DDevice9_SetPixelShaderConstantI(device
, index
, scdata
->int_constant
, 1);
522 ok(hret
== D3D_OK
, "SetPixelShaderConstantI returned %#x.\n", hret
);
523 hret
= IDirect3DDevice9_SetPixelShaderConstantF(device
, index
, scdata
->float_constant
, 1);
524 ok(hret
== D3D_OK
, "SetPixelShaderConstantF returned %#x.\n", hret
);
525 hret
= IDirect3DDevice9_SetPixelShaderConstantB(device
, index
, scdata
->bool_constant
, 4);
526 ok(hret
== D3D_OK
, "SetPixelShaderConstantB returned %#x.\n", hret
);
530 static void shader_constant_check_data(IDirect3DDevice9
*device
, const struct state_test
*test
,
531 const void *expected_data
, unsigned int chain_stage
, DWORD quirk
)
533 struct shader_constant_data value
= shader_constant_poison_data
;
534 const struct shader_constant_data
*scdata
= expected_data
;
535 const struct shader_constant_arg
*scarg
= test
->test_arg
;
540 hr
= IDirect3DDevice9_GetVertexShaderConstantI(device
, scarg
->idx
, value
.int_constant
, 1);
541 ok(SUCCEEDED(hr
), "GetVertexShaderConstantI returned %#x.\n", hr
);
542 hr
= IDirect3DDevice9_GetVertexShaderConstantF(device
, scarg
->idx
, value
.float_constant
, 1);
543 ok(SUCCEEDED(hr
), "GetVertexShaderConstantF returned %#x.\n", hr
);
544 hr
= IDirect3DDevice9_GetVertexShaderConstantB(device
, scarg
->idx
, value
.bool_constant
, 4);
545 ok(SUCCEEDED(hr
), "GetVertexShaderConstantB returned %#x.\n", hr
);
549 hr
= IDirect3DDevice9_GetPixelShaderConstantI(device
, scarg
->idx
, value
.int_constant
, 1);
550 ok(SUCCEEDED(hr
), "GetPixelShaderConstantI returned %#x.\n", hr
);
551 hr
= IDirect3DDevice9_GetPixelShaderConstantF(device
, scarg
->idx
, value
.float_constant
, 1);
552 ok(SUCCEEDED(hr
), "GetPixelShaderConstantF returned %#x.\n", hr
);
553 hr
= IDirect3DDevice9_GetPixelShaderConstantB(device
, scarg
->idx
, value
.bool_constant
, 4);
554 ok(SUCCEEDED(hr
), "GetPixelShaderConstantB returned %#x.\n", hr
);
557 ok(!memcmp(scdata
->int_constant
, value
.int_constant
, sizeof(scdata
->int_constant
)),
558 "Chain stage %u, %s integer constant:\n"
559 "\t{%#x, %#x, %#x, %#x} expected\n"
560 "\t{%#x, %#x, %#x, %#x} received\n",
561 chain_stage
, scarg
->pshader
? "pixel shader" : "vertex_shader",
562 scdata
->int_constant
[0], scdata
->int_constant
[1],
563 scdata
->int_constant
[2], scdata
->int_constant
[3],
564 value
.int_constant
[0], value
.int_constant
[1],
565 value
.int_constant
[2], value
.int_constant
[3]);
567 ok(!memcmp(scdata
->float_constant
, value
.float_constant
, sizeof(scdata
->float_constant
)),
568 "Chain stage %u, %s float constant:\n"
569 "\t{%.8e, %.8e, %.8e, %.8e} expected\n"
570 "\t{%.8e, %.8e, %.8e, %.8e} received\n",
571 chain_stage
, scarg
->pshader
? "pixel shader" : "vertex_shader",
572 scdata
->float_constant
[0], scdata
->float_constant
[1],
573 scdata
->float_constant
[2], scdata
->float_constant
[3],
574 value
.float_constant
[0], value
.float_constant
[1],
575 value
.float_constant
[2], value
.float_constant
[3]);
577 ok(!memcmp(scdata
->bool_constant
, value
.bool_constant
, sizeof(scdata
->bool_constant
)),
578 "Chain stage %u, %s boolean constant:\n"
579 "\t{%#x, %#x, %#x, %#x} expected\n"
580 "\t{%#x, %#x, %#x, %#x} received\n",
581 chain_stage
, scarg
->pshader
? "pixel shader" : "vertex_shader",
582 scdata
->bool_constant
[0], scdata
->bool_constant
[1],
583 scdata
->bool_constant
[2], scdata
->bool_constant
[3],
584 value
.bool_constant
[0], value
.bool_constant
[1],
585 value
.bool_constant
[2], value
.bool_constant
[3]);
588 static HRESULT
shader_constant_test_init(IDirect3DDevice9
*device
, struct state_test
*test
)
590 const struct shader_constant_arg
*test_arg
= test
->test_arg
;
592 test
->test_context
= NULL
;
593 test
->test_data_in
= &shader_constant_test_data
;
594 test
->test_data_out_all
= &shader_constant_test_data
;
595 if (test_arg
->pshader
)
597 test
->test_data_out_vertex
= &shader_constant_default_data
;
598 test
->test_data_out_pixel
= &shader_constant_test_data
;
602 test
->test_data_out_vertex
= &shader_constant_test_data
;
603 test
->test_data_out_pixel
= &shader_constant_default_data
;
605 test
->default_data
= &shader_constant_default_data
;
606 test
->initial_data
= &shader_constant_default_data
;
611 static void shader_constants_queue_test(struct state_test
*test
, const struct shader_constant_arg
*test_arg
)
613 test
->init
= shader_constant_test_init
;
614 test
->cleanup
= NULL
;
615 test
->apply_data
= shader_constant_apply_data
;
616 test
->check_data
= shader_constant_check_data
;
617 test
->test_name
= test_arg
->pshader
? "set_get_pshader_constants" : "set_get_vshader_constants";
618 test
->test_arg
= test_arg
;
621 /* =================== State test: Lights ===================================== */
627 HRESULT get_light_result
;
628 HRESULT get_enabled_result
;
636 static const struct light_data light_poison_data
=
640 {7.0f
, 4.0f
, 2.0f
, 1.0f
},
641 {7.0f
, 4.0f
, 2.0f
, 1.0f
},
642 {7.0f
, 4.0f
, 2.0f
, 1.0f
},
645 12.12f
, 13.13f
, 14.14f
, 15.15f
, 16.16f
, 17.17f
, 18.18f
,
652 static const struct light_data light_default_data
=
655 D3DLIGHT_DIRECTIONAL
,
656 {1.0f
, 1.0f
, 1.0f
, 0.0f
},
657 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
658 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
661 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
,
668 /* This is used for the initial read state (before a write causes side effects).
669 * The proper return status is D3DERR_INVALIDCALL. */
670 static const struct light_data light_initial_data
=
674 {7.0f
, 4.0f
, 2.0f
, 1.0f
},
675 {7.0f
, 4.0f
, 2.0f
, 1.0f
},
676 {7.0f
, 4.0f
, 2.0f
, 1.0f
},
679 12.12f
, 13.13f
, 14.14f
, 15.15f
, 16.16f
, 17.17f
, 18.18f
,
686 static const struct light_data light_test_data_in
=
690 {2.0f
, 2.0f
, 2.0f
, 2.0f
},
691 {3.0f
, 3.0f
, 3.0f
, 3.0f
},
692 {4.0f
, 4.0f
, 4.0f
, 4.0f
},
695 7.0f
, 8.0f
, 9.0f
, 10.0f
, 11.0f
, 12.0f
, 13.0f
,
702 /* SetLight will use 128 as the "enabled" value */
703 static const struct light_data light_test_data_out
=
707 {2.0f
, 2.0f
, 2.0f
, 2.0f
},
708 {3.0f
, 3.0f
, 3.0f
, 3.0f
},
709 {4.0f
, 4.0f
, 4.0f
, 4.0f
},
712 7.0f
, 8.0f
, 9.0f
, 10.0f
, 11.0f
, 12.0f
, 13.0f
,
719 static void light_apply_data(IDirect3DDevice9
*device
, const struct state_test
*test
, const void *data
)
721 const struct light_arg
*larg
= test
->test_arg
;
722 const struct light_data
*ldata
= data
;
724 unsigned int index
= larg
->idx
;
726 hret
= IDirect3DDevice9_SetLight(device
, index
, &ldata
->light
);
727 ok(hret
== D3D_OK
, "SetLight returned %#x.\n", hret
);
729 hret
= IDirect3DDevice9_LightEnable(device
, index
, ldata
->enabled
);
730 ok(hret
== D3D_OK
, "SetLightEnable returned %#x.\n", hret
);
733 static void light_check_data(IDirect3DDevice9
*device
, const struct state_test
*test
,
734 const void *expected_data
, unsigned int chain_stage
, DWORD quirk
)
736 const struct light_arg
*larg
= test
->test_arg
;
737 const struct light_data
*ldata
= expected_data
;
738 struct light_data value
;
740 value
= light_poison_data
;
742 value
.get_enabled_result
= IDirect3DDevice9_GetLightEnable(device
, larg
->idx
, &value
.enabled
);
743 value
.get_light_result
= IDirect3DDevice9_GetLight(device
, larg
->idx
, &value
.light
);
745 ok(value
.get_enabled_result
== ldata
->get_enabled_result
,
746 "Chain stage %u: expected get_enabled_result %#x, got %#x.\n",
747 chain_stage
, ldata
->get_enabled_result
, value
.get_enabled_result
);
748 ok(value
.get_light_result
== ldata
->get_light_result
,
749 "Chain stage %u: expected get_light_result %#x, got %#x.\n",
750 chain_stage
, ldata
->get_light_result
, value
.get_light_result
);
752 ok(value
.enabled
== ldata
->enabled
,
753 "Chain stage %u: expected enabled %#x, got %#x.\n",
754 chain_stage
, ldata
->enabled
, value
.enabled
);
755 ok(value
.light
.Type
== ldata
->light
.Type
,
756 "Chain stage %u: expected light.Type %#x, got %#x.\n",
757 chain_stage
, ldata
->light
.Type
, value
.light
.Type
);
758 ok(!memcmp(&value
.light
.Diffuse
, &ldata
->light
.Diffuse
, sizeof(value
.light
.Diffuse
)),
759 "Chain stage %u, light.Diffuse:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
760 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage
,
761 ldata
->light
.Diffuse
.r
, ldata
->light
.Diffuse
.g
,
762 ldata
->light
.Diffuse
.b
, ldata
->light
.Diffuse
.a
,
763 value
.light
.Diffuse
.r
, value
.light
.Diffuse
.g
,
764 value
.light
.Diffuse
.b
, value
.light
.Diffuse
.a
);
765 ok(!memcmp(&value
.light
.Specular
, &ldata
->light
.Specular
, sizeof(value
.light
.Specular
)),
766 "Chain stage %u, light.Specular:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
767 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage
,
768 ldata
->light
.Specular
.r
, ldata
->light
.Specular
.g
,
769 ldata
->light
.Specular
.b
, ldata
->light
.Specular
.a
,
770 value
.light
.Specular
.r
, value
.light
.Specular
.g
,
771 value
.light
.Specular
.b
, value
.light
.Specular
.a
);
772 ok(!memcmp(&value
.light
.Ambient
, &ldata
->light
.Ambient
, sizeof(value
.light
.Ambient
)),
773 "Chain stage %u, light.Ambient:\n\t{%.8e, %.8e, %.8e, %.8e} expected\n"
774 "\t{%.8e, %.8e, %.8e, %.8e} received.\n", chain_stage
,
775 ldata
->light
.Ambient
.r
, ldata
->light
.Ambient
.g
,
776 ldata
->light
.Ambient
.b
, ldata
->light
.Ambient
.a
,
777 value
.light
.Ambient
.r
, value
.light
.Ambient
.g
,
778 value
.light
.Ambient
.b
, value
.light
.Ambient
.a
);
779 ok(!memcmp(&value
.light
.Position
, &ldata
->light
.Position
, sizeof(value
.light
.Position
)),
780 "Chain stage %u, light.Position:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
781 chain_stage
, ldata
->light
.Position
.x
, ldata
->light
.Position
.y
, ldata
->light
.Position
.z
,
782 value
.light
.Position
.x
, value
.light
.Position
.y
, value
.light
.Position
.z
);
783 ok(!memcmp(&value
.light
.Direction
, &ldata
->light
.Direction
, sizeof(value
.light
.Direction
)),
784 "Chain stage %u, light.Direction:\n\t{%.8e, %.8e, %.8e} expected\n\t{%.8e, %.8e, %.8e} received.\n",
785 chain_stage
, ldata
->light
.Direction
.x
, ldata
->light
.Direction
.y
, ldata
->light
.Direction
.z
,
786 value
.light
.Direction
.x
, value
.light
.Direction
.y
, value
.light
.Direction
.z
);
787 ok(value
.light
.Range
== ldata
->light
.Range
,
788 "Chain stage %u: expected light.Range %.8e, got %.8e.\n",
789 chain_stage
, ldata
->light
.Range
, value
.light
.Range
);
790 ok(value
.light
.Falloff
== ldata
->light
.Falloff
,
791 "Chain stage %u: expected light.Falloff %.8e, got %.8e.\n",
792 chain_stage
, ldata
->light
.Falloff
, value
.light
.Falloff
);
793 ok(value
.light
.Attenuation0
== ldata
->light
.Attenuation0
,
794 "Chain stage %u: expected light.Attenuation0 %.8e, got %.8e.\n",
795 chain_stage
, ldata
->light
.Attenuation0
, value
.light
.Attenuation0
);
796 ok(value
.light
.Attenuation1
== ldata
->light
.Attenuation1
,
797 "Chain stage %u: expected light.Attenuation1 %.8e, got %.8e.\n",
798 chain_stage
, ldata
->light
.Attenuation1
, value
.light
.Attenuation1
);
799 ok(value
.light
.Attenuation2
== ldata
->light
.Attenuation2
,
800 "Chain stage %u: expected light.Attenuation2 %.8e, got %.8e.\n",
801 chain_stage
, ldata
->light
.Attenuation2
, value
.light
.Attenuation2
);
802 ok(value
.light
.Theta
== ldata
->light
.Theta
,
803 "Chain stage %u: expected light.Theta %.8e, got %.8e.\n",
804 chain_stage
, ldata
->light
.Theta
, value
.light
.Theta
);
805 ok(value
.light
.Phi
== ldata
->light
.Phi
,
806 "Chain stage %u: expected light.Phi %.8e, got %.8e.\n",
807 chain_stage
, ldata
->light
.Phi
, value
.light
.Phi
);
810 static HRESULT
light_test_init(IDirect3DDevice9
*device
, struct state_test
*test
)
812 test
->test_context
= NULL
;
813 test
->test_data_in
= &light_test_data_in
;
814 test
->test_data_out_all
= &light_test_data_out
;
815 test
->test_data_out_vertex
= &light_test_data_out
;
816 test
->test_data_out_pixel
= &light_default_data
;
817 test
->default_data
= &light_default_data
;
818 test
->initial_data
= &light_initial_data
;
823 static void lights_queue_test(struct state_test
*test
, const struct light_arg
*test_arg
)
825 test
->init
= light_test_init
;
826 test
->cleanup
= NULL
;
827 test
->apply_data
= light_apply_data
;
828 test
->check_data
= light_check_data
;
829 test
->test_name
= "set_get_light";
830 test
->test_arg
= test_arg
;
833 /* =================== State test: Transforms ===================================== */
835 struct transform_data
838 D3DMATRIX projection
;
845 static const struct transform_data transform_default_data
=
848 1.0f
, 0.0f
, 0.0f
, 0.0f
,
849 0.0f
, 1.0f
, 0.0f
, 0.0f
,
850 0.0f
, 0.0f
, 1.0f
, 0.0f
,
851 0.0f
, 0.0f
, 0.0f
, 1.0f
,
854 1.0f
, 0.0f
, 0.0f
, 0.0f
,
855 0.0f
, 1.0f
, 0.0f
, 0.0f
,
856 0.0f
, 0.0f
, 1.0f
, 0.0f
,
857 0.0f
, 0.0f
, 0.0f
, 1.0f
,
860 1.0f
, 0.0f
, 0.0f
, 0.0f
,
861 0.0f
, 1.0f
, 0.0f
, 0.0f
,
862 0.0f
, 0.0f
, 1.0f
, 0.0f
,
863 0.0f
, 0.0f
, 0.0f
, 1.0f
,
866 1.0f
, 0.0f
, 0.0f
, 0.0f
,
867 0.0f
, 1.0f
, 0.0f
, 0.0f
,
868 0.0f
, 0.0f
, 1.0f
, 0.0f
,
869 0.0f
, 0.0f
, 0.0f
, 1.0f
,
872 1.0f
, 0.0f
, 0.0f
, 0.0f
,
873 0.0f
, 1.0f
, 0.0f
, 0.0f
,
874 0.0f
, 0.0f
, 1.0f
, 0.0f
,
875 0.0f
, 0.0f
, 0.0f
, 1.0f
,
878 1.0f
, 0.0f
, 0.0f
, 0.0f
,
879 0.0f
, 1.0f
, 0.0f
, 0.0f
,
880 0.0f
, 0.0f
, 1.0f
, 0.0f
,
881 0.0f
, 0.0f
, 0.0f
, 1.0f
,
885 static const struct transform_data transform_poison_data
=
888 1.0f
, 2.0f
, 3.0f
, 4.0f
,
889 5.0f
, 6.0f
, 7.0f
, 8.0f
,
890 9.0f
, 10.0f
, 11.0f
, 12.0f
,
891 13.0f
, 14.0f
, 15.0f
, 16.0f
,
894 17.0f
, 18.0f
, 19.0f
, 20.0f
,
895 21.0f
, 22.0f
, 23.0f
, 24.0f
,
896 25.0f
, 26.0f
, 27.0f
, 28.0f
,
897 29.0f
, 30.0f
, 31.0f
, 32.0f
,
900 33.0f
, 34.0f
, 35.0f
, 36.0f
,
901 37.0f
, 38.0f
, 39.0f
, 40.0f
,
902 41.0f
, 42.0f
, 43.0f
, 44.0f
,
903 45.0f
, 46.0f
, 47.0f
, 48.0f
906 49.0f
, 50.0f
, 51.0f
, 52.0f
,
907 53.0f
, 54.0f
, 55.0f
, 56.0f
,
908 57.0f
, 58.0f
, 59.0f
, 60.0f
,
909 61.0f
, 62.0f
, 63.0f
, 64.0f
,
912 64.0f
, 66.0f
, 67.0f
, 68.0f
,
913 69.0f
, 70.0f
, 71.0f
, 72.0f
,
914 73.0f
, 74.0f
, 75.0f
, 76.0f
,
915 77.0f
, 78.0f
, 79.0f
, 80.0f
,
918 81.0f
, 82.0f
, 83.0f
, 84.0f
,
919 85.0f
, 86.0f
, 87.0f
, 88.0f
,
920 89.0f
, 90.0f
, 91.0f
, 92.0f
,
921 93.0f
, 94.0f
, 95.0f
, 96.0f
,
925 static const struct transform_data transform_test_data
=
928 1.2f
, 3.4f
, -5.6f
, 7.2f
,
929 10.11f
, -12.13f
, 14.15f
, -1.5f
,
930 23.56f
, 12.89f
, 44.56f
, -1.0f
,
931 2.3f
, 0.0f
, 4.4f
, 5.5f
,
934 9.2f
, 38.7f
, -6.6f
, 7.2f
,
935 10.11f
, -12.13f
, 77.15f
, -1.5f
,
936 23.56f
, 12.89f
, 14.56f
, -1.0f
,
937 12.3f
, 0.0f
, 4.4f
, 5.5f
,
940 10.2f
, 3.4f
, 0.6f
, 7.2f
,
941 10.11f
, -12.13f
, 14.15f
, -1.5f
,
942 23.54f
, 12.9f
, 44.56f
, -1.0f
,
943 2.3f
, 0.0f
, 4.4f
, 5.5f
,
946 1.2f
, 3.4f
, -5.6f
, 7.2f
,
947 10.11f
, -12.13f
, -14.5f
, -1.5f
,
948 2.56f
, 12.89f
, 23.56f
, -1.0f
,
949 112.3f
, 0.0f
, 4.4f
, 2.5f
,
952 1.2f
, 31.41f
, 58.6f
, 7.2f
,
953 10.11f
, -12.13f
, -14.5f
, -1.5f
,
954 2.56f
, 12.89f
, 11.56f
, -1.0f
,
955 112.3f
, 0.0f
, 44.4f
, 2.5f
,
958 1.20f
, 3.4f
, -5.6f
, 7.0f
,
959 10.11f
, -12.156f
, -14.5f
, -1.5f
,
960 2.56f
, 1.829f
, 23.6f
, -1.0f
,
961 112.3f
, 0.0f
, 41.4f
, 2.5f
,
965 static void transform_apply_data(IDirect3DDevice9
*device
, const struct state_test
*test
, const void *data
)
967 const struct transform_data
*tdata
= data
;
970 hret
= IDirect3DDevice9_SetTransform(device
, D3DTS_VIEW
, &tdata
->view
);
971 ok(hret
== D3D_OK
, "SetTransform returned %#x.\n", hret
);
973 hret
= IDirect3DDevice9_SetTransform(device
, D3DTS_PROJECTION
, &tdata
->projection
);
974 ok(hret
== D3D_OK
, "SetTransform returned %#x.\n", hret
);
976 hret
= IDirect3DDevice9_SetTransform(device
, D3DTS_TEXTURE0
, &tdata
->texture0
);
977 ok(hret
== D3D_OK
, "SetTransform returned %#x.\n", hret
);
979 hret
= IDirect3DDevice9_SetTransform(device
, D3DTS_TEXTURE0
+ texture_stages
- 1, &tdata
->texture7
);
980 ok(hret
== D3D_OK
, "SetTransform returned %#x.\n", hret
);
982 hret
= IDirect3DDevice9_SetTransform(device
, D3DTS_WORLD
, &tdata
->world0
);
983 ok(hret
== D3D_OK
, "SetTransform returned %#x.\n", hret
);
985 hret
= IDirect3DDevice9_SetTransform(device
, D3DTS_WORLDMATRIX(255), &tdata
->world255
);
986 ok(hret
== D3D_OK
, "SetTransform returned %#x.\n", hret
);
989 static void compare_matrix(const char *name
, unsigned int chain_stage
,
990 const D3DMATRIX
*received
, const D3DMATRIX
*expected
)
992 ok(!memcmp(expected
, received
, sizeof(*expected
)),
993 "Chain stage %u, matrix %s:\n"
995 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
996 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
997 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
998 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1001 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1002 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1003 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1004 "\t\t%.8e, %.8e, %.8e, %.8e,\n"
1007 U(*expected
).m
[0][0], U(*expected
).m
[1][0], U(*expected
).m
[2][0], U(*expected
).m
[3][0],
1008 U(*expected
).m
[0][1], U(*expected
).m
[1][1], U(*expected
).m
[2][1], U(*expected
).m
[3][1],
1009 U(*expected
).m
[0][2], U(*expected
).m
[1][2], U(*expected
).m
[2][2], U(*expected
).m
[3][2],
1010 U(*expected
).m
[0][3], U(*expected
).m
[1][3], U(*expected
).m
[2][3], U(*expected
).m
[3][3],
1011 U(*received
).m
[0][0], U(*received
).m
[1][0], U(*received
).m
[2][0], U(*received
).m
[3][0],
1012 U(*received
).m
[0][1], U(*received
).m
[1][1], U(*received
).m
[2][1], U(*received
).m
[3][1],
1013 U(*received
).m
[0][2], U(*received
).m
[1][2], U(*received
).m
[2][2], U(*received
).m
[3][2],
1014 U(*received
).m
[0][3], U(*received
).m
[1][3], U(*received
).m
[2][3], U(*received
).m
[3][3]);
1017 static void transform_check_data(IDirect3DDevice9
*device
, const struct state_test
*test
,
1018 const void *expected_data
, unsigned int chain_stage
, DWORD quirk
)
1020 const struct transform_data
*tdata
= expected_data
;
1024 value
= transform_poison_data
.view
;
1025 hr
= IDirect3DDevice9_GetTransform(device
, D3DTS_VIEW
, &value
);
1026 ok(SUCCEEDED(hr
), "GetTransform returned %#x.\n", hr
);
1027 compare_matrix("View", chain_stage
, &value
, &tdata
->view
);
1029 value
= transform_poison_data
.projection
;
1030 hr
= IDirect3DDevice9_GetTransform(device
, D3DTS_PROJECTION
, &value
);
1031 ok(SUCCEEDED(hr
), "GetTransform returned %#x.\n", hr
);
1032 compare_matrix("Projection", chain_stage
, &value
, &tdata
->projection
);
1034 value
= transform_poison_data
.texture0
;
1035 hr
= IDirect3DDevice9_GetTransform(device
, D3DTS_TEXTURE0
, &value
);
1036 ok(SUCCEEDED(hr
), "GetTransform returned %#x.\n", hr
);
1037 compare_matrix("Texture0", chain_stage
, &value
, &tdata
->texture0
);
1039 value
= transform_poison_data
.texture7
;
1040 hr
= IDirect3DDevice9_GetTransform(device
, D3DTS_TEXTURE0
+ texture_stages
- 1, &value
);
1041 ok(SUCCEEDED(hr
), "GetTransform returned %#x.\n", hr
);
1042 compare_matrix("Texture7", chain_stage
, &value
, &tdata
->texture7
);
1044 value
= transform_poison_data
.world0
;
1045 hr
= IDirect3DDevice9_GetTransform(device
, D3DTS_WORLD
, &value
);
1046 ok(SUCCEEDED(hr
), "GetTransform returned %#x.\n", hr
);
1047 compare_matrix("World0", chain_stage
, &value
, &tdata
->world0
);
1049 value
= transform_poison_data
.world255
;
1050 hr
= IDirect3DDevice9_GetTransform(device
, D3DTS_WORLDMATRIX(255), &value
);
1051 ok(SUCCEEDED(hr
), "GetTransform returned %#x.\n", hr
);
1052 compare_matrix("World255", chain_stage
, &value
, &tdata
->world255
);
1055 static HRESULT
transform_test_init(IDirect3DDevice9
*device
, struct state_test
*test
)
1057 test
->test_context
= NULL
;
1058 test
->test_data_in
= &transform_test_data
;
1059 test
->test_data_out_all
= &transform_test_data
;
1060 test
->test_data_out_vertex
= &transform_default_data
;
1061 test
->test_data_out_pixel
= &transform_default_data
;
1062 test
->default_data
= &transform_default_data
;
1063 test
->initial_data
= &transform_default_data
;
1068 static void transform_queue_test(struct state_test
*test
)
1070 test
->init
= transform_test_init
;
1071 test
->cleanup
= NULL
;
1072 test
->apply_data
= transform_apply_data
;
1073 test
->check_data
= transform_check_data
;
1074 test
->test_name
= "set_get_transforms";
1075 test
->test_arg
= NULL
;
1078 /* =================== State test: Render States ===================================== */
1080 const D3DRENDERSTATETYPE render_state_indices
[] =
1086 D3DRS_ALPHATESTENABLE
,
1095 D3DRS_ALPHABLENDENABLE
,
1097 D3DRS_SPECULARENABLE
,
1103 D3DRS_RANGEFOGENABLE
,
1104 D3DRS_STENCILENABLE
,
1111 D3DRS_STENCILWRITEMASK
,
1112 D3DRS_TEXTUREFACTOR
,
1124 D3DRS_FOGVERTEXMODE
,
1127 D3DRS_NORMALIZENORMALS
,
1128 D3DRS_DIFFUSEMATERIALSOURCE
,
1129 D3DRS_SPECULARMATERIALSOURCE
,
1130 D3DRS_AMBIENTMATERIALSOURCE
,
1131 D3DRS_EMISSIVEMATERIALSOURCE
,
1133 D3DRS_CLIPPLANEENABLE
,
1134 #if 0 /* Driver dependent */
1137 D3DRS_POINTSIZE_MIN
,
1138 D3DRS_POINTSPRITEENABLE
,
1139 D3DRS_POINTSCALEENABLE
,
1143 D3DRS_MULTISAMPLEANTIALIAS
,
1144 D3DRS_MULTISAMPLEMASK
,
1145 D3DRS_PATCHEDGESTYLE
,
1146 #if 0 /* Apparently not recorded in the stateblock */
1147 D3DRS_DEBUGMONITORTOKEN
,
1149 D3DRS_POINTSIZE_MAX
,
1150 D3DRS_INDEXEDVERTEXBLENDENABLE
,
1151 D3DRS_COLORWRITEENABLE
,
1154 D3DRS_POSITIONDEGREE
,
1156 D3DRS_SCISSORTESTENABLE
,
1157 D3DRS_SLOPESCALEDEPTHBIAS
,
1158 D3DRS_ANTIALIASEDLINEENABLE
,
1159 D3DRS_MINTESSELLATIONLEVEL
,
1160 D3DRS_MAXTESSELLATIONLEVEL
,
1161 D3DRS_ADAPTIVETESS_X
,
1162 D3DRS_ADAPTIVETESS_Y
,
1163 D3DRS_ADAPTIVETESS_Z
,
1164 D3DRS_ADAPTIVETESS_W
,
1165 D3DRS_ENABLEADAPTIVETESSELLATION
,
1166 D3DRS_TWOSIDEDSTENCILMODE
,
1167 D3DRS_CCW_STENCILFAIL
,
1168 D3DRS_CCW_STENCILZFAIL
,
1169 D3DRS_CCW_STENCILPASS
,
1170 D3DRS_CCW_STENCILFUNC
,
1171 D3DRS_COLORWRITEENABLE1
,
1172 D3DRS_COLORWRITEENABLE2
,
1173 D3DRS_COLORWRITEENABLE3
,
1175 D3DRS_SRGBWRITEENABLE
,
1185 D3DRS_SEPARATEALPHABLENDENABLE
,
1186 D3DRS_SRCBLENDALPHA
,
1187 D3DRS_DESTBLENDALPHA
,
1191 struct render_state_data
1193 DWORD states
[sizeof(render_state_indices
) / sizeof(*render_state_indices
)];
1196 struct render_state_arg
1198 D3DPRESENT_PARAMETERS
*device_pparams
;
1199 float pointsize_max
;
1202 struct render_state_context
1204 struct render_state_data default_data_buffer
;
1205 struct render_state_data test_data_all_buffer
;
1206 struct render_state_data test_data_vertex_buffer
;
1207 struct render_state_data test_data_pixel_buffer
;
1208 struct render_state_data poison_data_buffer
;
1211 static void render_state_apply_data(IDirect3DDevice9
*device
, const struct state_test
*test
, const void *data
)
1213 const struct render_state_data
*rsdata
= data
;
1217 for (i
= 0; i
< sizeof(render_state_indices
) / sizeof(*render_state_indices
); ++i
)
1219 hret
= IDirect3DDevice9_SetRenderState(device
, render_state_indices
[i
], rsdata
->states
[i
]);
1220 ok(hret
== D3D_OK
, "SetRenderState returned %#x.\n", hret
);
1224 static void render_state_check_data(IDirect3DDevice9
*device
, const struct state_test
*test
,
1225 const void *expected_data
, unsigned int chain_stage
, DWORD quirk
)
1227 const struct render_state_context
*ctx
= test
->test_context
;
1228 const struct render_state_data
*rsdata
= expected_data
;
1232 for (i
= 0; i
< sizeof(render_state_indices
) / sizeof(*render_state_indices
); ++i
)
1234 DWORD value
= ctx
->poison_data_buffer
.states
[i
];
1235 hr
= IDirect3DDevice9_GetRenderState(device
, render_state_indices
[i
], &value
);
1236 ok(SUCCEEDED(hr
), "GetRenderState returned %#x.\n", hr
);
1237 ok(value
== rsdata
->states
[i
], "Chain stage %u, render state %#x: expected %#x, got %#x.\n",
1238 chain_stage
, render_state_indices
[i
], rsdata
->states
[i
], value
);
1242 static inline DWORD
to_dword(float fl
) {
1243 return *((DWORD
*) &fl
);
1246 static void render_state_default_data_init(const struct render_state_arg
*rsarg
, struct render_state_data
*data
)
1248 DWORD zenable
= rsarg
->device_pparams
->EnableAutoDepthStencil
? D3DZB_TRUE
: D3DZB_FALSE
;
1249 unsigned int idx
= 0;
1251 data
->states
[idx
++] = zenable
; /* ZENABLE */
1252 data
->states
[idx
++] = D3DFILL_SOLID
; /* FILLMODE */
1253 data
->states
[idx
++] = D3DSHADE_GOURAUD
; /* SHADEMODE */
1254 data
->states
[idx
++] = TRUE
; /* ZWRITEENABLE */
1255 data
->states
[idx
++] = FALSE
; /* ALPHATESTENABLE */
1256 data
->states
[idx
++] = TRUE
; /* LASTPIXEL */
1257 data
->states
[idx
++] = D3DBLEND_ONE
; /* SRCBLEND */
1258 data
->states
[idx
++] = D3DBLEND_ZERO
; /* DESTBLEND */
1259 data
->states
[idx
++] = D3DCULL_CCW
; /* CULLMODE */
1260 data
->states
[idx
++] = D3DCMP_LESSEQUAL
; /* ZFUNC */
1261 data
->states
[idx
++] = 0; /* ALPHAREF */
1262 data
->states
[idx
++] = D3DCMP_ALWAYS
; /* ALPHAFUNC */
1263 data
->states
[idx
++] = FALSE
; /* DITHERENABLE */
1264 data
->states
[idx
++] = FALSE
; /* ALPHABLENDENABLE */
1265 data
->states
[idx
++] = FALSE
; /* FOGENABLE */
1266 data
->states
[idx
++] = FALSE
; /* SPECULARENABLE */
1267 data
->states
[idx
++] = 0; /* FOGCOLOR */
1268 data
->states
[idx
++] = D3DFOG_NONE
; /* FOGTABLEMODE */
1269 data
->states
[idx
++] = to_dword(0.0f
); /* FOGSTART */
1270 data
->states
[idx
++] = to_dword(1.0f
); /* FOGEND */
1271 data
->states
[idx
++] = to_dword(1.0f
); /* FOGDENSITY */
1272 data
->states
[idx
++] = FALSE
; /* RANGEFOGENABLE */
1273 data
->states
[idx
++] = FALSE
; /* STENCILENABLE */
1274 data
->states
[idx
++] = D3DSTENCILOP_KEEP
; /* STENCILFAIL */
1275 data
->states
[idx
++] = D3DSTENCILOP_KEEP
; /* STENCILZFAIL */
1276 data
->states
[idx
++] = D3DSTENCILOP_KEEP
; /* STENCILPASS */
1277 data
->states
[idx
++] = D3DCMP_ALWAYS
; /* STENCILFUNC */
1278 data
->states
[idx
++] = 0; /* STENCILREF */
1279 data
->states
[idx
++] = 0xFFFFFFFF; /* STENCILMASK */
1280 data
->states
[idx
++] = 0xFFFFFFFF; /* STENCILWRITEMASK */
1281 data
->states
[idx
++] = 0xFFFFFFFF; /* TEXTUREFACTOR */
1282 data
->states
[idx
++] = 0; /* WRAP 0 */
1283 data
->states
[idx
++] = 0; /* WRAP 1 */
1284 data
->states
[idx
++] = 0; /* WRAP 2 */
1285 data
->states
[idx
++] = 0; /* WRAP 3 */
1286 data
->states
[idx
++] = 0; /* WRAP 4 */
1287 data
->states
[idx
++] = 0; /* WRAP 5 */
1288 data
->states
[idx
++] = 0; /* WRAP 6 */
1289 data
->states
[idx
++] = 0; /* WRAP 7 */
1290 data
->states
[idx
++] = TRUE
; /* CLIPPING */
1291 data
->states
[idx
++] = TRUE
; /* LIGHTING */
1292 data
->states
[idx
++] = 0; /* AMBIENT */
1293 data
->states
[idx
++] = D3DFOG_NONE
; /* FOGVERTEXMODE */
1294 data
->states
[idx
++] = TRUE
; /* COLORVERTEX */
1295 data
->states
[idx
++] = TRUE
; /* LOCALVIEWER */
1296 data
->states
[idx
++] = FALSE
; /* NORMALIZENORMALS */
1297 data
->states
[idx
++] = D3DMCS_COLOR1
; /* DIFFUSEMATERIALSOURCE */
1298 data
->states
[idx
++] = D3DMCS_COLOR2
; /* SPECULARMATERIALSOURCE */
1299 data
->states
[idx
++] = D3DMCS_MATERIAL
; /* AMBIENTMATERIALSOURCE */
1300 data
->states
[idx
++] = D3DMCS_MATERIAL
; /* EMISSIVEMATERIALSOURCE */
1301 data
->states
[idx
++] = D3DVBF_DISABLE
; /* VERTEXBLEND */
1302 data
->states
[idx
++] = 0; /* CLIPPLANEENABLE */
1303 #if 0 /* Driver dependent, increase array size to enable */
1304 data
->states
[idx
++] = to_dword(1.0f
); /* POINTSIZE */
1306 data
->states
[idx
++] = to_dword(1.0f
); /* POINTSIZEMIN */
1307 data
->states
[idx
++] = FALSE
; /* POINTSPRITEENABLE */
1308 data
->states
[idx
++] = FALSE
; /* POINTSCALEENABLE */
1309 data
->states
[idx
++] = to_dword(1.0f
); /* POINTSCALE_A */
1310 data
->states
[idx
++] = to_dword(0.0f
); /* POINTSCALE_B */
1311 data
->states
[idx
++] = to_dword(0.0f
); /* POINTSCALE_C */
1312 data
->states
[idx
++] = TRUE
; /* MULTISAMPLEANTIALIAS */
1313 data
->states
[idx
++] = 0xFFFFFFFF; /* MULTISAMPLEMASK */
1314 data
->states
[idx
++] = D3DPATCHEDGE_DISCRETE
; /* PATCHEDGESTYLE */
1315 if (0) data
->states
[idx
++] = 0xbaadcafe; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1316 data
->states
[idx
++] = to_dword(rsarg
->pointsize_max
); /* POINTSIZE_MAX */
1317 data
->states
[idx
++] = FALSE
; /* INDEXEDVERTEXBLENDENABLE */
1318 data
->states
[idx
++] = 0x0000000F; /* COLORWRITEENABLE */
1319 data
->states
[idx
++] = to_dword(0.0f
); /* TWEENFACTOR */
1320 data
->states
[idx
++] = D3DBLENDOP_ADD
; /* BLENDOP */
1321 data
->states
[idx
++] = D3DDEGREE_CUBIC
; /* POSITIONDEGREE */
1322 data
->states
[idx
++] = D3DDEGREE_LINEAR
; /* NORMALDEGREE */
1323 data
->states
[idx
++] = FALSE
; /* SCISSORTESTENABLE */
1324 data
->states
[idx
++] = to_dword(0.0f
); /* SLOPESCALEDEPTHBIAS */
1325 data
->states
[idx
++] = FALSE
; /* ANTIALIASEDLINEENABLE */
1326 data
->states
[idx
++] = to_dword(1.0f
); /* MINTESSELATIONLEVEL */
1327 data
->states
[idx
++] = to_dword(1.0f
); /* MAXTESSELATIONLEVEL */
1328 data
->states
[idx
++] = to_dword(0.0f
); /* ADAPTIVETESS_X */
1329 data
->states
[idx
++] = to_dword(0.0f
); /* ADAPTIVETESS_Y */
1330 data
->states
[idx
++] = to_dword(1.0f
); /* ADAPTIVETESS_Z */
1331 data
->states
[idx
++] = to_dword(0.0f
); /* ADAPTIVETESS_W */
1332 data
->states
[idx
++] = FALSE
; /* ENABLEADAPTIVETESSELATION */
1333 data
->states
[idx
++] = FALSE
; /* TWOSIDEDSTENCILMODE */
1334 data
->states
[idx
++] = D3DSTENCILOP_KEEP
; /* CCW_STENCILFAIL */
1335 data
->states
[idx
++] = D3DSTENCILOP_KEEP
; /* CCW_STENCILZFAIL */
1336 data
->states
[idx
++] = D3DSTENCILOP_KEEP
; /* CCW_STENCILPASS */
1337 data
->states
[idx
++] = D3DCMP_ALWAYS
; /* CCW_STENCILFUNC */
1338 data
->states
[idx
++] = 0x0000000F; /* COLORWRITEENABLE1 */
1339 data
->states
[idx
++] = 0x0000000F; /* COLORWRITEENABLE2 */
1340 data
->states
[idx
++] = 0x0000000F; /* COLORWRITEENABLE3 */
1341 data
->states
[idx
++] = 0xFFFFFFFF; /* BLENDFACTOR */
1342 data
->states
[idx
++] = 0; /* SRGBWRITEENABLE */
1343 data
->states
[idx
++] = to_dword(0.0f
); /* DEPTHBIAS */
1344 data
->states
[idx
++] = 0; /* WRAP8 */
1345 data
->states
[idx
++] = 0; /* WRAP9 */
1346 data
->states
[idx
++] = 0; /* WRAP10 */
1347 data
->states
[idx
++] = 0; /* WRAP11 */
1348 data
->states
[idx
++] = 0; /* WRAP12 */
1349 data
->states
[idx
++] = 0; /* WRAP13 */
1350 data
->states
[idx
++] = 0; /* WRAP14 */
1351 data
->states
[idx
++] = 0; /* WRAP15 */
1352 data
->states
[idx
++] = FALSE
; /* SEPARATEALPHABLENDENABLE */
1353 data
->states
[idx
++] = D3DBLEND_ONE
; /* SRCBLENDALPHA */
1354 data
->states
[idx
++] = D3DBLEND_ZERO
; /* DESTBLENDALPHA */
1355 data
->states
[idx
++] = TRUE
; /* BLENDOPALPHA */
1358 static void render_state_poison_data_init(struct render_state_data
*data
)
1362 for (i
= 0; i
< sizeof(render_state_indices
) / sizeof(*render_state_indices
); ++i
)
1364 data
->states
[i
] = 0x1337c0de;
1368 static void render_state_test_data_init(struct render_state_data
*data
)
1370 unsigned int idx
= 0;
1371 data
->states
[idx
++] = D3DZB_USEW
; /* ZENABLE */
1372 data
->states
[idx
++] = D3DFILL_WIREFRAME
; /* FILLMODE */
1373 data
->states
[idx
++] = D3DSHADE_PHONG
; /* SHADEMODE */
1374 data
->states
[idx
++] = FALSE
; /* ZWRITEENABLE */
1375 data
->states
[idx
++] = TRUE
; /* ALPHATESTENABLE */
1376 data
->states
[idx
++] = FALSE
; /* LASTPIXEL */
1377 data
->states
[idx
++] = D3DBLEND_SRCALPHASAT
; /* SRCBLEND */
1378 data
->states
[idx
++] = D3DBLEND_INVDESTALPHA
; /* DESTBLEND */
1379 data
->states
[idx
++] = D3DCULL_CW
; /* CULLMODE */
1380 data
->states
[idx
++] = D3DCMP_NOTEQUAL
; /* ZFUNC */
1381 data
->states
[idx
++] = 10; /* ALPHAREF */
1382 data
->states
[idx
++] = D3DCMP_GREATER
; /* ALPHAFUNC */
1383 data
->states
[idx
++] = TRUE
; /* DITHERENABLE */
1384 data
->states
[idx
++] = TRUE
; /* ALPHABLENDENABLE */
1385 data
->states
[idx
++] = TRUE
; /* FOGENABLE */
1386 data
->states
[idx
++] = TRUE
; /* SPECULARENABLE */
1387 data
->states
[idx
++] = 1 << 31; /* FOGCOLOR */
1388 data
->states
[idx
++] = D3DFOG_EXP
; /* FOGTABLEMODE */
1389 data
->states
[idx
++] = to_dword(0.1f
); /* FOGSTART */
1390 data
->states
[idx
++] = to_dword(0.8f
); /* FOGEND */
1391 data
->states
[idx
++] = to_dword(0.5f
); /* FOGDENSITY */
1392 data
->states
[idx
++] = TRUE
; /* RANGEFOGENABLE */
1393 data
->states
[idx
++] = TRUE
; /* STENCILENABLE */
1394 data
->states
[idx
++] = D3DSTENCILOP_INCRSAT
; /* STENCILFAIL */
1395 data
->states
[idx
++] = D3DSTENCILOP_REPLACE
; /* STENCILZFAIL */
1396 data
->states
[idx
++] = D3DSTENCILOP_INVERT
; /* STENCILPASS */
1397 data
->states
[idx
++] = D3DCMP_LESS
; /* STENCILFUNC */
1398 data
->states
[idx
++] = 10; /* STENCILREF */
1399 data
->states
[idx
++] = 0xFF00FF00; /* STENCILMASK */
1400 data
->states
[idx
++] = 0x00FF00FF; /* STENCILWRITEMASK */
1401 data
->states
[idx
++] = 0xF0F0F0F0; /* TEXTUREFACTOR */
1402 data
->states
[idx
++] = D3DWRAPCOORD_0
| D3DWRAPCOORD_2
; /* WRAP 0 */
1403 data
->states
[idx
++] = D3DWRAPCOORD_1
| D3DWRAPCOORD_3
; /* WRAP 1 */
1404 data
->states
[idx
++] = D3DWRAPCOORD_2
| D3DWRAPCOORD_3
; /* WRAP 2 */
1405 data
->states
[idx
++] = D3DWRAPCOORD_3
| D3DWRAPCOORD_0
; /* WRAP 4 */
1406 data
->states
[idx
++] = D3DWRAPCOORD_0
| D3DWRAPCOORD_1
| D3DWRAPCOORD_2
; /* WRAP 5 */
1407 data
->states
[idx
++] = D3DWRAPCOORD_1
| D3DWRAPCOORD_3
| D3DWRAPCOORD_2
; /* WRAP 6 */
1408 data
->states
[idx
++] = D3DWRAPCOORD_2
| D3DWRAPCOORD_1
| D3DWRAPCOORD_0
; /* WRAP 7 */
1409 data
->states
[idx
++] = D3DWRAPCOORD_1
| D3DWRAPCOORD_0
| D3DWRAPCOORD_2
| D3DWRAPCOORD_3
; /* WRAP 8 */
1410 data
->states
[idx
++] = FALSE
; /* CLIPPING */
1411 data
->states
[idx
++] = FALSE
; /* LIGHTING */
1412 data
->states
[idx
++] = 255 << 16; /* AMBIENT */
1413 data
->states
[idx
++] = D3DFOG_EXP2
; /* FOGVERTEXMODE */
1414 data
->states
[idx
++] = FALSE
; /* COLORVERTEX */
1415 data
->states
[idx
++] = FALSE
; /* LOCALVIEWER */
1416 data
->states
[idx
++] = TRUE
; /* NORMALIZENORMALS */
1417 data
->states
[idx
++] = D3DMCS_COLOR2
; /* DIFFUSEMATERIALSOURCE */
1418 data
->states
[idx
++] = D3DMCS_MATERIAL
; /* SPECULARMATERIALSOURCE */
1419 data
->states
[idx
++] = D3DMCS_COLOR1
; /* AMBIENTMATERIALSOURCE */
1420 data
->states
[idx
++] = D3DMCS_COLOR2
; /* EMISSIVEMATERIALSOURCE */
1421 data
->states
[idx
++] = D3DVBF_3WEIGHTS
; /* VERTEXBLEND */
1422 data
->states
[idx
++] = 0xf1f1f1f1; /* CLIPPLANEENABLE */
1423 #if 0 /* Driver dependent, increase array size to enable */
1424 data
->states
[idx
++] = to_dword(32.0f
); /* POINTSIZE */
1426 data
->states
[idx
++] = to_dword(0.7f
); /* POINTSIZEMIN */
1427 data
->states
[idx
++] = TRUE
; /* POINTSPRITEENABLE */
1428 data
->states
[idx
++] = TRUE
; /* POINTSCALEENABLE */
1429 data
->states
[idx
++] = to_dword(0.7f
); /* POINTSCALE_A */
1430 data
->states
[idx
++] = to_dword(0.5f
); /* POINTSCALE_B */
1431 data
->states
[idx
++] = to_dword(0.4f
); /* POINTSCALE_C */
1432 data
->states
[idx
++] = FALSE
; /* MULTISAMPLEANTIALIAS */
1433 data
->states
[idx
++] = 0xABCDDBCA; /* MULTISAMPLEMASK */
1434 data
->states
[idx
++] = D3DPATCHEDGE_CONTINUOUS
; /* PATCHEDGESTYLE */
1435 if (0) data
->states
[idx
++] = D3DDMT_DISABLE
; /* DEBUGMONITORTOKEN, not recorded in the stateblock */
1436 data
->states
[idx
++] = to_dword(77.0f
); /* POINTSIZE_MAX */
1437 data
->states
[idx
++] = TRUE
; /* INDEXEDVERTEXBLENDENABLE */
1438 data
->states
[idx
++] = 0x00000009; /* COLORWRITEENABLE */
1439 data
->states
[idx
++] = to_dword(0.2f
); /* TWEENFACTOR */
1440 data
->states
[idx
++] = D3DBLENDOP_REVSUBTRACT
;/* BLENDOP */
1441 data
->states
[idx
++] = D3DDEGREE_LINEAR
; /* POSITIONDEGREE */
1442 data
->states
[idx
++] = D3DDEGREE_CUBIC
; /* NORMALDEGREE */
1443 data
->states
[idx
++] = TRUE
; /* SCISSORTESTENABLE */
1444 data
->states
[idx
++] = to_dword(0.33f
); /* SLOPESCALEDEPTHBIAS */
1445 data
->states
[idx
++] = TRUE
; /* ANTIALIASEDLINEENABLE */
1446 data
->states
[idx
++] = to_dword(0.8f
); /* MINTESSELATIONLEVEL */
1447 data
->states
[idx
++] = to_dword(0.8f
); /* MAXTESSELATIONLEVEL */
1448 data
->states
[idx
++] = to_dword(0.2f
); /* ADAPTIVETESS_X */
1449 data
->states
[idx
++] = to_dword(0.3f
); /* ADAPTIVETESS_Y */
1450 data
->states
[idx
++] = to_dword(0.6f
); /* ADAPTIVETESS_Z */
1451 data
->states
[idx
++] = to_dword(0.4f
); /* ADAPTIVETESS_W */
1452 data
->states
[idx
++] = TRUE
; /* ENABLEADAPTIVETESSELATION */
1453 data
->states
[idx
++] = TRUE
; /* TWOSIDEDSTENCILMODE */
1454 data
->states
[idx
++] = D3DSTENCILOP_ZERO
; /* CCW_STENCILFAIL */
1455 data
->states
[idx
++] = D3DSTENCILOP_DECR
; /* CCW_STENCILZFAIL */
1456 data
->states
[idx
++] = D3DSTENCILOP_INCR
; /* CCW_STENCILPASS */
1457 data
->states
[idx
++] = D3DCMP_ALWAYS
; /* CCW_STENCILFUNC */
1458 data
->states
[idx
++] = 0x00000007; /* COLORWRITEENABLE1 */
1459 data
->states
[idx
++] = 0x00000008; /* COLORWRITEENABLE2 */
1460 data
->states
[idx
++] = 0x00000004; /* COLORWRITEENABLE3 */
1461 data
->states
[idx
++] = 0xF0F1F2F3; /* BLENDFACTOR */
1462 data
->states
[idx
++] = 1; /* SRGBWRITEENABLE */
1463 data
->states
[idx
++] = to_dword(0.3f
); /* DEPTHBIAS */
1464 data
->states
[idx
++] = D3DWRAPCOORD_0
| D3DWRAPCOORD_2
; /* WRAP 8 */
1465 data
->states
[idx
++] = D3DWRAPCOORD_1
| D3DWRAPCOORD_3
; /* WRAP 9 */
1466 data
->states
[idx
++] = D3DWRAPCOORD_2
| D3DWRAPCOORD_3
; /* WRAP 10 */
1467 data
->states
[idx
++] = D3DWRAPCOORD_3
| D3DWRAPCOORD_0
; /* WRAP 11 */
1468 data
->states
[idx
++] = D3DWRAPCOORD_0
| D3DWRAPCOORD_1
| D3DWRAPCOORD_2
; /* WRAP 12 */
1469 data
->states
[idx
++] = D3DWRAPCOORD_1
| D3DWRAPCOORD_3
| D3DWRAPCOORD_2
; /* WRAP 13 */
1470 data
->states
[idx
++] = D3DWRAPCOORD_2
| D3DWRAPCOORD_1
| D3DWRAPCOORD_0
; /* WRAP 14 */
1471 data
->states
[idx
++] = D3DWRAPCOORD_1
| D3DWRAPCOORD_0
| D3DWRAPCOORD_2
| D3DWRAPCOORD_3
; /* WRAP 15 */
1472 data
->states
[idx
++] = TRUE
; /* SEPARATEALPHABLENDENABLE */
1473 data
->states
[idx
++] = D3DBLEND_ZERO
; /* SRCBLENDALPHA */
1474 data
->states
[idx
++] = D3DBLEND_ONE
; /* DESTBLENDALPHA */
1475 data
->states
[idx
++] = FALSE
; /* BLENDOPALPHA */
1478 static HRESULT
render_state_test_init(IDirect3DDevice9
*device
, struct state_test
*test
)
1480 static const DWORD states_vertex
[] =
1482 D3DRS_ADAPTIVETESS_W
,
1483 D3DRS_ADAPTIVETESS_X
,
1484 D3DRS_ADAPTIVETESS_Y
,
1485 D3DRS_ADAPTIVETESS_Z
,
1487 D3DRS_AMBIENTMATERIALSOURCE
,
1489 D3DRS_CLIPPLANEENABLE
,
1492 D3DRS_DIFFUSEMATERIALSOURCE
,
1493 D3DRS_EMISSIVEMATERIALSOURCE
,
1494 D3DRS_ENABLEADAPTIVETESSELLATION
,
1501 D3DRS_FOGVERTEXMODE
,
1502 D3DRS_INDEXEDVERTEXBLENDENABLE
,
1505 D3DRS_MAXTESSELLATIONLEVEL
,
1506 D3DRS_MINTESSELLATIONLEVEL
,
1507 D3DRS_MULTISAMPLEANTIALIAS
,
1508 D3DRS_MULTISAMPLEMASK
,
1510 D3DRS_NORMALIZENORMALS
,
1511 D3DRS_PATCHEDGESTYLE
,
1515 D3DRS_POINTSCALEENABLE
,
1517 D3DRS_POINTSIZE_MAX
,
1518 D3DRS_POINTSIZE_MIN
,
1519 D3DRS_POINTSPRITEENABLE
,
1520 D3DRS_POSITIONDEGREE
,
1521 D3DRS_RANGEFOGENABLE
,
1523 D3DRS_SPECULARENABLE
,
1524 D3DRS_SPECULARMATERIALSOURCE
,
1529 static const DWORD states_pixel
[] =
1531 D3DRS_ALPHABLENDENABLE
,
1534 D3DRS_ALPHATESTENABLE
,
1535 D3DRS_ANTIALIASEDLINEENABLE
,
1539 D3DRS_CCW_STENCILFAIL
,
1540 D3DRS_CCW_STENCILPASS
,
1541 D3DRS_CCW_STENCILZFAIL
,
1542 D3DRS_COLORWRITEENABLE
,
1543 D3DRS_COLORWRITEENABLE1
,
1544 D3DRS_COLORWRITEENABLE2
,
1545 D3DRS_COLORWRITEENABLE3
,
1548 D3DRS_DESTBLENDALPHA
,
1555 D3DRS_SCISSORTESTENABLE
,
1556 D3DRS_SEPARATEALPHABLENDENABLE
,
1558 D3DRS_SLOPESCALEDEPTHBIAS
,
1560 D3DRS_SRCBLENDALPHA
,
1561 D3DRS_SRGBWRITEENABLE
,
1562 D3DRS_STENCILENABLE
,
1568 D3DRS_STENCILWRITEMASK
,
1570 D3DRS_TEXTUREFACTOR
,
1571 D3DRS_TWOSIDEDSTENCILMODE
,
1593 const struct render_state_arg
*rsarg
= test
->test_arg
;
1596 struct render_state_context
*ctx
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*ctx
));
1597 if (ctx
== NULL
) return E_FAIL
;
1598 test
->test_context
= ctx
;
1600 test
->default_data
= &ctx
->default_data_buffer
;
1601 test
->initial_data
= &ctx
->default_data_buffer
;
1602 test
->test_data_in
= &ctx
->test_data_all_buffer
;
1603 test
->test_data_out_all
= &ctx
->test_data_all_buffer
;
1604 test
->test_data_out_vertex
= &ctx
->test_data_vertex_buffer
;
1605 test
->test_data_out_pixel
= &ctx
->test_data_pixel_buffer
;
1607 render_state_default_data_init(rsarg
, &ctx
->default_data_buffer
);
1608 render_state_test_data_init(&ctx
->test_data_all_buffer
);
1609 render_state_poison_data_init(&ctx
->poison_data_buffer
);
1611 for (i
= 0; i
< sizeof(render_state_indices
) / sizeof(*render_state_indices
); ++i
)
1613 ctx
->test_data_vertex_buffer
.states
[i
] = ctx
->default_data_buffer
.states
[i
];
1614 for (j
= 0; j
< sizeof(states_vertex
) / sizeof(*states_vertex
); ++j
)
1616 if (render_state_indices
[i
] == states_vertex
[j
])
1618 ctx
->test_data_vertex_buffer
.states
[i
] = ctx
->test_data_all_buffer
.states
[i
];
1623 ctx
->test_data_pixel_buffer
.states
[i
] = ctx
->default_data_buffer
.states
[i
];
1624 for (j
= 0; j
< sizeof(states_pixel
) / sizeof(*states_pixel
); ++j
)
1626 if (render_state_indices
[i
] == states_pixel
[j
])
1628 ctx
->test_data_pixel_buffer
.states
[i
] = ctx
->test_data_all_buffer
.states
[i
];
1637 static void render_state_test_cleanup(IDirect3DDevice9
*device
, struct state_test
*test
)
1639 HeapFree(GetProcessHeap(), 0, test
->test_context
);
1642 static void render_states_queue_test(struct state_test
*test
, const struct render_state_arg
*test_arg
)
1644 test
->init
= render_state_test_init
;
1645 test
->cleanup
= render_state_test_cleanup
;
1646 test
->apply_data
= render_state_apply_data
;
1647 test
->check_data
= render_state_check_data
;
1648 test
->test_name
= "set_get_render_states";
1649 test
->test_arg
= test_arg
;
1652 /* resource tests */
1654 struct resource_test_arg
1662 struct resource_test_data
1664 IDirect3DVertexDeclaration9
*decl
;
1665 IDirect3DVertexShader9
*vs
;
1666 IDirect3DPixelShader9
*ps
;
1667 IDirect3DIndexBuffer9
*ib
;
1668 IDirect3DVertexBuffer9
**vb
;
1669 IDirect3DTexture9
**tex
;
1672 struct resource_test_context
1674 struct resource_test_data default_data
;
1675 struct resource_test_data test_data_all
;
1676 struct resource_test_data test_data_vertex
;
1677 struct resource_test_data test_data_pixel
;
1678 struct resource_test_data poison_data
;
1681 static void resource_apply_data(IDirect3DDevice9
*device
, const struct state_test
*test
, const void *data
)
1683 const struct resource_test_arg
*arg
= test
->test_arg
;
1684 const struct resource_test_data
*d
= data
;
1688 hr
= IDirect3DDevice9_SetVertexDeclaration(device
, d
->decl
);
1689 ok(SUCCEEDED(hr
), "SetVertexDeclaration (%p) returned %#x.\n", d
->decl
, hr
);
1691 hr
= IDirect3DDevice9_SetVertexShader(device
, d
->vs
);
1692 ok(SUCCEEDED(hr
), "SetVertexShader (%p) returned %#x.\n", d
->vs
, hr
);
1694 hr
= IDirect3DDevice9_SetPixelShader(device
, d
->ps
);
1695 ok(SUCCEEDED(hr
), "SetPixelShader (%p) returned %#x.\n", d
->ps
, hr
);
1697 hr
= IDirect3DDevice9_SetIndices(device
, d
->ib
);
1698 ok(SUCCEEDED(hr
), "SetIndices (%p) returned %#x.\n", d
->ib
, hr
);
1700 for (i
= 0; i
< arg
->stream_count
; ++i
)
1702 hr
= IDirect3DDevice9_SetStreamSource(device
, i
, d
->vb
[i
], 0, 64);
1703 ok(SUCCEEDED(hr
), "SetStreamSource (%u, %p, 0, 64) returned %#x.\n",
1707 for (i
= 0; i
< arg
->tex_count
; ++i
)
1709 hr
= IDirect3DDevice9_SetTexture(device
, i
, (IDirect3DBaseTexture9
*)d
->tex
[i
]);
1710 ok(SUCCEEDED(hr
), "SetTexture (%u, %p) returned %#x.\n", i
, d
->tex
[i
], hr
);
1714 static void resource_check_data(IDirect3DDevice9
*device
, const struct state_test
*test
,
1715 const void *expected_data
, unsigned int chain_stage
, DWORD quirk
)
1717 const struct resource_test_context
*ctx
= test
->test_context
;
1718 const struct resource_test_data
*poison
= &ctx
->poison_data
;
1719 const struct resource_test_arg
*arg
= test
->test_arg
;
1720 const struct resource_test_data
*d
= expected_data
;
1727 hr
= IDirect3DDevice9_GetVertexDeclaration(device
, (IDirect3DVertexDeclaration9
**)&ptr
);
1728 ok(SUCCEEDED(hr
), "GetVertexDeclaration returned %#x.\n", hr
);
1729 if (quirk
& SB_QUIRK_RECORDED_VDECL_CAPTURE
)
1731 ok(ptr
== ctx
->test_data_all
.decl
, "Chain stage %u, expected vertex declaration %p, received %p.\n",
1732 chain_stage
, ctx
->test_data_all
.decl
, ptr
);
1736 ok(ptr
== d
->decl
, "Chain stage %u, expected vertex declaration %p, received %p.\n",
1737 chain_stage
, d
->decl
, ptr
);
1739 if (SUCCEEDED(hr
) && ptr
)
1741 IDirect3DVertexDeclaration9_Release((IDirect3DVertexDeclaration9
*)ptr
);
1745 hr
= IDirect3DDevice9_GetVertexShader(device
, (IDirect3DVertexShader9
**)&ptr
);
1746 ok(SUCCEEDED(hr
), "GetVertexShader returned %#x.\n", hr
);
1747 ok(ptr
== d
->vs
, "Chain stage %u, expected vertex shader %p, received %p.\n",
1748 chain_stage
, d
->vs
, ptr
);
1749 if (SUCCEEDED(hr
) && ptr
)
1751 IDirect3DVertexShader9_Release((IDirect3DVertexShader9
*)ptr
);
1755 hr
= IDirect3DDevice9_GetPixelShader(device
, (IDirect3DPixelShader9
**)&ptr
);
1756 ok(SUCCEEDED(hr
), "GetPixelShader returned %#x.\n", hr
);
1757 ok(ptr
== d
->ps
, "Chain stage %u, expected pixel shader %p, received %p.\n",
1758 chain_stage
, d
->ps
, ptr
);
1759 if (SUCCEEDED(hr
) && ptr
)
1761 IDirect3DPixelShader9_Release((IDirect3DPixelShader9
*)ptr
);
1765 hr
= IDirect3DDevice9_GetIndices(device
, (IDirect3DIndexBuffer9
**)&ptr
);
1766 ok(SUCCEEDED(hr
), "GetIndices returned %#x.\n", hr
);
1767 ok(ptr
== d
->ib
, "Chain stage %u, expected index buffer %p, received %p.\n",
1768 chain_stage
, d
->ib
, ptr
);
1769 if (SUCCEEDED(hr
) && ptr
)
1771 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9
*)ptr
);
1774 for (i
= 0; i
< arg
->stream_count
; ++i
)
1776 ptr
= poison
->vb
[i
];
1777 hr
= IDirect3DDevice9_GetStreamSource(device
, i
, (IDirect3DVertexBuffer9
**)&ptr
, &v
, &w
);
1778 ok(SUCCEEDED(hr
), "GetStreamSource (%u) returned %#x.\n", i
, hr
);
1779 ok(ptr
== d
->vb
[i
], "Chain stage %u, stream %u, expected vertex buffer %p, received %p.\n",
1780 chain_stage
, i
, d
->vb
[i
], ptr
);
1781 if (SUCCEEDED(hr
) && ptr
)
1783 IDirect3DIndexBuffer9_Release((IDirect3DVertexBuffer9
*)ptr
);
1787 for (i
= 0; i
< arg
->tex_count
; ++i
)
1789 ptr
= poison
->tex
[i
];
1790 hr
= IDirect3DDevice9_GetTexture(device
, i
, (IDirect3DBaseTexture9
**)&ptr
);
1791 ok(SUCCEEDED(hr
), "SetTexture (%u) returned %#x.\n", i
, hr
);
1792 ok(ptr
== d
->tex
[i
], "Chain stage %u, texture stage %u, expected texture %p, received %p.\n",
1793 chain_stage
, i
, d
->tex
[i
], ptr
);
1794 if (SUCCEEDED(hr
) && ptr
)
1796 IDirect3DBaseTexture9_Release((IDirect3DBaseTexture9
*)ptr
);
1801 static void resource_default_data_init(struct resource_test_data
*data
, const struct resource_test_arg
*arg
)
1809 data
->vb
= HeapAlloc(GetProcessHeap(), 0, arg
->stream_count
* sizeof(*data
->vb
));
1810 for (i
= 0; i
< arg
->stream_count
; ++i
)
1814 data
->tex
= HeapAlloc(GetProcessHeap(), 0, arg
->tex_count
* sizeof(*data
->tex
));
1815 for (i
= 0; i
< arg
->tex_count
; ++i
)
1817 data
->tex
[i
] = NULL
;
1821 static void resource_test_data_init(IDirect3DDevice9
*device
,
1822 struct resource_test_data
*data
, const struct resource_test_arg
*arg
)
1824 static const DWORD vs_code
[] =
1826 0xfffe0101, /* vs_1_1 */
1827 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
1828 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
1829 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
1830 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
1831 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
1832 0x0000ffff, /* END */
1834 static const DWORD ps_code
[] =
1836 0xffff0101, /* ps_1_1 */
1837 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
1838 0x00000042, 0xb00f0000, /* tex t0 */
1839 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
1840 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
1841 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
1842 0x0000ffff, /* END */
1844 static const D3DVERTEXELEMENT9 decl
[] =
1846 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1847 {0, 12, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
1854 hr
= IDirect3DDevice9_CreateVertexDeclaration(device
, decl
, &data
->decl
);
1855 ok(SUCCEEDED(hr
), "CreateVertexDeclaration returned %#x.\n", hr
);
1857 if (arg
->vs_version
)
1859 hr
= IDirect3DDevice9_CreateVertexShader(device
, vs_code
, &data
->vs
);
1860 ok(SUCCEEDED(hr
), "CreateVertexShader returned %#x.\n", hr
);
1867 if (arg
->ps_version
)
1869 hr
= IDirect3DDevice9_CreatePixelShader(device
, ps_code
, &data
->ps
);
1870 ok(SUCCEEDED(hr
), "CreatePixelShader returned %#x.\n", hr
);
1877 hr
= IDirect3DDevice9_CreateIndexBuffer(device
, 64, D3DUSAGE_DYNAMIC
,
1878 D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &data
->ib
, NULL
);
1879 ok(SUCCEEDED(hr
), "CreateIndexBuffer returned %#x.\n", hr
);
1881 data
->vb
= HeapAlloc(GetProcessHeap(), 0, arg
->stream_count
* sizeof(*data
->vb
));
1882 for (i
= 0; i
< arg
->stream_count
; ++i
)
1884 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, 64, D3DUSAGE_DYNAMIC
,
1885 0, D3DPOOL_DEFAULT
, &data
->vb
[i
], NULL
);
1886 ok(SUCCEEDED(hr
), "CreateVertexBuffer (%u) returned %#x.\n", i
, hr
);
1888 data
->tex
= HeapAlloc(GetProcessHeap(), 0, arg
->tex_count
* sizeof(*data
->tex
));
1889 for (i
= 0; i
< arg
->tex_count
; ++i
)
1891 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 0, 0,
1892 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &data
->tex
[i
], NULL
);
1893 ok(SUCCEEDED(hr
), "CreateTexture (%u) returned %#x.\n", i
, hr
);
1897 static void resource_poison_data_init(struct resource_test_data
*data
, const struct resource_test_arg
*arg
)
1899 DWORD_PTR poison
= 0xdeadbeef;
1902 data
->decl
= (IDirect3DVertexDeclaration9
*)poison
++;
1903 data
->vs
= (IDirect3DVertexShader9
*)poison
++;
1904 data
->ps
= (IDirect3DPixelShader9
*)poison
++;
1905 data
->ib
= (IDirect3DIndexBuffer9
*)poison
++;
1906 data
->vb
= HeapAlloc(GetProcessHeap(), 0, arg
->stream_count
* sizeof(*data
->vb
));
1907 for (i
= 0; i
< arg
->stream_count
; ++i
)
1909 data
->vb
[i
] = (IDirect3DVertexBuffer9
*)poison
++;
1911 data
->tex
= HeapAlloc(GetProcessHeap(), 0, arg
->tex_count
* sizeof(*data
->tex
));
1912 for (i
= 0; i
< arg
->tex_count
; ++i
)
1914 data
->tex
[i
] = (IDirect3DTexture9
*)poison
++;
1918 static HRESULT
resource_test_init(IDirect3DDevice9
*device
, struct state_test
*test
)
1920 const struct resource_test_arg
*arg
= test
->test_arg
;
1921 struct resource_test_context
*ctx
;
1923 ctx
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*ctx
));
1924 if (!ctx
) return E_OUTOFMEMORY
;
1926 test
->test_context
= ctx
;
1927 test
->test_data_in
= &ctx
->test_data_all
;
1928 test
->test_data_out_all
= &ctx
->test_data_all
;
1929 test
->test_data_out_vertex
= &ctx
->test_data_vertex
;
1930 test
->test_data_out_pixel
= &ctx
->test_data_pixel
;
1931 test
->default_data
= &ctx
->default_data
;
1932 test
->initial_data
= &ctx
->default_data
;
1934 resource_default_data_init(&ctx
->default_data
, arg
);
1935 resource_test_data_init(device
, &ctx
->test_data_all
, arg
);
1936 resource_default_data_init(&ctx
->test_data_vertex
, arg
);
1937 resource_default_data_init(&ctx
->test_data_pixel
, arg
);
1938 resource_poison_data_init(&ctx
->poison_data
, arg
);
1940 ctx
->test_data_vertex
.decl
= ctx
->test_data_all
.decl
;
1941 ctx
->test_data_vertex
.vs
= ctx
->test_data_all
.vs
;
1942 ctx
->test_data_pixel
.ps
= ctx
->test_data_all
.ps
;
1947 static void resource_test_cleanup(IDirect3DDevice9
*device
, struct state_test
*test
)
1949 struct resource_test_context
*ctx
= test
->test_context
;
1950 const struct resource_test_arg
*arg
= test
->test_arg
;
1953 resource_apply_data(device
, test
, &ctx
->default_data
);
1955 IDirect3DVertexDeclaration9_Release(ctx
->test_data_all
.decl
);
1956 if (ctx
->test_data_all
.vs
) IDirect3DVertexShader9_Release(ctx
->test_data_all
.vs
);
1957 if (ctx
->test_data_all
.ps
) IDirect3DPixelShader9_Release(ctx
->test_data_all
.ps
);
1958 IDirect3DIndexBuffer9_Release(ctx
->test_data_all
.ib
);
1959 for (i
= 0; i
< arg
->stream_count
; ++i
)
1961 IDirect3DVertexBuffer9_Release(ctx
->test_data_all
.vb
[i
]);
1964 for (i
= 0; i
< arg
->tex_count
; ++i
)
1966 IDirect3DBaseTexture9_Release(ctx
->test_data_all
.tex
[i
]);
1969 HeapFree(GetProcessHeap(), 0, ctx
->default_data
.vb
);
1970 HeapFree(GetProcessHeap(), 0, ctx
->default_data
.tex
);
1971 HeapFree(GetProcessHeap(), 0, ctx
->test_data_all
.vb
);
1972 HeapFree(GetProcessHeap(), 0, ctx
->test_data_all
.tex
);
1973 HeapFree(GetProcessHeap(), 0, ctx
->test_data_vertex
.vb
);
1974 HeapFree(GetProcessHeap(), 0, ctx
->test_data_vertex
.tex
);
1975 HeapFree(GetProcessHeap(), 0, ctx
->test_data_pixel
.vb
);
1976 HeapFree(GetProcessHeap(), 0, ctx
->test_data_pixel
.tex
);
1977 HeapFree(GetProcessHeap(), 0, ctx
->poison_data
.vb
);
1978 HeapFree(GetProcessHeap(), 0, ctx
->poison_data
.tex
);
1979 HeapFree(GetProcessHeap(), 0, ctx
);
1982 static void resource_test_queue(struct state_test
*test
, const struct resource_test_arg
*test_arg
)
1984 test
->init
= resource_test_init
;
1985 test
->cleanup
= resource_test_cleanup
;
1986 test
->apply_data
= resource_apply_data
;
1987 test
->check_data
= resource_check_data
;
1988 test
->test_name
= "set_get_resources";
1989 test
->test_arg
= test_arg
;
1992 /* =================== Main state tests function =============================== */
1994 static void test_state_management(void)
1996 struct shader_constant_arg pshader_constant_arg
;
1997 struct shader_constant_arg vshader_constant_arg
;
1998 struct resource_test_arg resource_test_arg
;
1999 struct render_state_arg render_state_arg
;
2000 D3DPRESENT_PARAMETERS present_parameters
;
2001 struct light_arg light_arg
;
2002 IDirect3DDevice9
*device
;
2009 /* Test count: 2 for shader constants
2015 struct state_test tests
[6];
2016 unsigned int tcount
= 0;
2018 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
2019 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2020 if (!(d3d
= Direct3DCreate9(D3D_SDK_VERSION
)))
2022 skip("Failed to create a D3D object, skipping tests.\n");
2023 DestroyWindow(window
);
2026 memset(&present_parameters
, 0, sizeof(present_parameters
));
2027 present_parameters
.Windowed
= TRUE
;
2028 present_parameters
.hDeviceWindow
= window
;
2029 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2030 if (FAILED(IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
2031 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
)))
2033 skip("Failed to create a 3D device, skipping test.\n");
2034 IDirect3D9_Release(d3d
);
2035 DestroyWindow(window
);
2039 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
2040 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
2042 texture_stages
= caps
.MaxTextureBlendStages
;
2044 /* Zero test memory */
2045 memset(tests
, 0, sizeof(tests
));
2047 if (caps
.VertexShaderVersion
& 0xffff) {
2048 vshader_constant_arg
.idx
= 0;
2049 vshader_constant_arg
.pshader
= FALSE
;
2050 shader_constants_queue_test(&tests
[tcount
], &vshader_constant_arg
);
2054 if (caps
.PixelShaderVersion
& 0xffff) {
2055 pshader_constant_arg
.idx
= 0;
2056 pshader_constant_arg
.pshader
= TRUE
;
2057 shader_constants_queue_test(&tests
[tcount
], &pshader_constant_arg
);
2062 lights_queue_test(&tests
[tcount
], &light_arg
);
2065 transform_queue_test(&tests
[tcount
]);
2068 render_state_arg
.device_pparams
= &present_parameters
;
2069 render_state_arg
.pointsize_max
= caps
.MaxPointSize
;
2070 render_states_queue_test(&tests
[tcount
], &render_state_arg
);
2073 resource_test_arg
.vs_version
= caps
.VertexShaderVersion
& 0xffff;
2074 resource_test_arg
.ps_version
= caps
.PixelShaderVersion
& 0xffff;
2075 resource_test_arg
.stream_count
= caps
.MaxStreams
;
2076 resource_test_arg
.tex_count
= caps
.MaxTextureBlendStages
;
2077 resource_test_queue(&tests
[tcount
], &resource_test_arg
);
2080 execute_test_chain_all(device
, tests
, tcount
);
2082 refcount
= IDirect3DDevice9_Release(device
);
2083 ok(!refcount
, "Device has %u references left\n", refcount
);
2084 IDirect3D9_Release(d3d
);
2085 DestroyWindow(window
);
2088 START_TEST(stateblock
)
2090 test_state_management();