wer: Add new stubbed wer.dll.
[wine/hramrach.git] / dlls / d3d8 / tests / stateblock.c
blob33cc56d542901bbc15eb7043eaaa83461091e800
1 /*
2 * Copyright 2006 Ivan Gyurdiev
3 * Copyright 2005, 2008 Henri Verbeet
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define COBJMACROS
21 #include <d3d8.h>
22 #include "wine/test.h"
24 static DWORD texture_stages;
26 static HWND create_window(void)
28 WNDCLASS wc = {0};
29 wc.lpfnWndProc = DefWindowProc;
30 wc.lpszClassName = "d3d8_test_wc";
31 RegisterClass(&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;
39 D3DDISPLAYMODE d3ddm;
40 IDirect3D8 *d3d8 = 0;
41 HWND window;
42 HRESULT hr;
44 d3d8_create = (void *)GetProcAddress(d3d8_module, "Direct3DCreate8");
45 if (!d3d8_create) return E_FAIL;
47 d3d8 = d3d8_create(D3D_SDK_VERSION);
48 if (!d3d8)
50 skip("Failed to create D3D8 object.\n");
51 return E_FAIL;
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);
67 return hr;
70 static void test_begin_end_state_block(IDirect3DDevice8 *device)
72 DWORD state_block;
73 HRESULT hr;
75 /* Should succeed */
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;
85 /* Should succeed */
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 ========================== */
104 struct state_test
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,
129 const void *data);
130 void (*check_data)(IDirect3DDevice8 *device, const struct state_test *test,
131 const void *data_expected, unsigned int chain_stage);
133 /* Test arguments */
134 const void *test_arg;
136 /* Test-specific context data */
137 void *test_context;
140 /* See below for explanation of the flags */
141 #define EVENT_OK 0
142 #define EVENT_ERROR -1
144 struct event_data
146 DWORD stateblock;
147 IDirect3DSurface8 *original_render_target;
148 IDirect3DSwapChain8 *new_swap_chain;
151 enum stateblock_data
153 SB_DATA_NONE = 0,
154 SB_DATA_DEFAULT,
155 SB_DATA_INITIAL,
156 SB_DATA_TEST_IN,
157 SB_DATA_TEST_ALL,
158 SB_DATA_TEST_VERTEX,
159 SB_DATA_TEST_PIXEL,
162 struct event
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)
171 switch (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;
191 default:
192 return NULL;
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)
202 unsigned int i, j;
204 /* For each queued event */
205 for (j = 0; j < nevents; ++j)
207 const void *data;
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);
215 break;
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;
251 HRESULT hr;
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;
282 return EVENT_OK;
284 error:
285 if (backbuffer) IDirect3DSurface8_Release(backbuffer);
286 if (swapchain) IDirect3DSwapChain8_Release(swapchain);
287 return EVENT_ERROR;
290 static int revert_render_target(IDirect3DDevice8 *device, struct event_data *event_data)
292 HRESULT hr;
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);
297 if (FAILED(hr))
299 IDirect3DSurface8_Release(event_data->original_render_target);
300 return EVENT_ERROR;
303 IDirect3DSurface8_Release(event_data->original_render_target);
304 IDirect3DSwapChain8_Release(event_data->new_swap_chain);
305 return EVENT_OK;
308 static int create_stateblock_all(IDirect3DDevice8 *device, struct event_data *event_data)
310 HRESULT hr;
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;
315 return EVENT_OK;
318 static int create_stateblock_vertex(IDirect3DDevice8 *device, struct event_data *event_data)
320 HRESULT hr;
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;
325 return EVENT_OK;
328 static int create_stateblock_pixel(IDirect3DDevice8 *device, struct event_data *event_data)
330 HRESULT hr;
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;
335 return EVENT_OK;
338 static int begin_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
340 HRESULT hr;
342 hr = IDirect3DDevice8_BeginStateBlock(device);
343 ok(SUCCEEDED(hr), "BeginStateBlock returned %#x.\n", hr);
344 if (FAILED(hr)) return EVENT_ERROR;
345 return EVENT_OK;
348 static int end_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
350 HRESULT hr;
352 hr = IDirect3DDevice8_EndStateBlock(device, &event_data->stateblock);
353 ok(SUCCEEDED(hr), "EndStateBlock returned %#x.\n", hr);
354 if (FAILED(hr)) return EVENT_ERROR;
355 return EVENT_OK;
358 static int delete_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
360 IDirect3DDevice8_DeleteStateBlock(device, event_data->stateblock);
361 return EVENT_OK;
364 static int apply_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
366 HRESULT hr;
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;
373 return EVENT_OK;
376 static int capture_stateblock(IDirect3DDevice8 *device, struct event_data *event_data)
378 HRESULT hr;
380 hr = IDirect3DDevice8_CaptureStateBlock(device, event_data->stateblock);
381 ok(SUCCEEDED(hr), "Capture returned %#x.\n", hr);
382 if (FAILED(hr)) return EVENT_ERROR;
384 return EVENT_OK;
387 static void execute_test_chain_all(IDirect3DDevice8 *device, struct state_test *test, unsigned int ntests)
389 struct event_data arg;
390 unsigned int i;
391 HRESULT hr;
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
547 unsigned int idx;
548 BOOL pshader;
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;
571 HRESULT hr;
573 if (!scarg->pshader)
575 hr = IDirect3DDevice8_SetVertexShaderConstant(device, index, scdata->float_constant, 1);
576 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
578 else
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;
591 HRESULT hr;
593 value = shader_constant_poison_data;
595 if (!scarg->pshader)
597 hr = IDirect3DDevice8_GetVertexShaderConstant(device, scarg->idx, value.float_constant, 1);
598 ok(SUCCEEDED(hr), "GetVertexShaderConstant returned %#x.\n", hr);
600 else
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;
627 else
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;
635 return D3D_OK;
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 ===================================== */
650 struct light_data
652 D3DLIGHT8 light;
653 BOOL enabled;
654 HRESULT get_light_result;
655 HRESULT get_enabled_result;
658 struct light_arg
660 unsigned int idx;
663 static const struct light_data light_poison_data =
666 0x1337c0de,
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},
670 {3.3f, 4.4f, 5.5f},
671 {6.6f, 7.7f, 8.8f},
672 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
674 TRUE,
675 0x1337c0de,
676 0x1337c0de,
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},
686 {0.0, 0.0, 0.0},
687 {0.0, 0.0, 1.0},
688 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
690 FALSE,
691 D3D_OK,
692 D3D_OK,
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 =
700 0x1337c0de,
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},
704 {3.3f, 4.4f, 5.5f},
705 {6.6f, 7.7f, 8.8f},
706 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f,
708 TRUE,
709 D3DERR_INVALIDCALL,
710 D3DERR_INVALIDCALL,
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},
720 {5.0, 5.0, 5.0},
721 {6.0, 6.0, 6.0},
722 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
724 TRUE,
725 D3D_OK,
726 D3D_OK,
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},
737 {5.0, 5.0, 5.0},
738 {6.0, 6.0, 6.0},
739 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
741 128,
742 D3D_OK,
743 D3D_OK,
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;
751 HRESULT hr;
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;
847 return D3D_OK;
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
864 D3DMATRIX view;
865 D3DMATRIX projection;
866 D3DMATRIX texture0;
867 D3DMATRIX texture7;
868 D3DMATRIX world0;
869 D3DMATRIX world255;
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,
879 }}},
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,
885 }}},
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,
891 }}},
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,
897 }}},
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,
903 }}},
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,
909 }}},
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,
919 }}},
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,
925 }}},
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,
931 }}},
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,
937 }}},
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,
943 }}},
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,
949 }}},
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,
959 }}},
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,
965 }}},
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,
971 }}},
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,
977 }}},
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,
983 }}},
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,
990 }}},
994 static void transform_apply_data(IDirect3DDevice8 *device, const struct state_test *test, const void *data)
996 const struct transform_data *tdata = data;
997 HRESULT hr;
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"
1023 "\t{\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"
1028 "\t} expected\n"
1029 "\t{\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"
1034 "\t} received\n",
1035 chain_stage, name,
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;
1050 D3DMATRIX value;
1051 HRESULT hr;
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;
1094 return D3D_OK;
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[] =
1111 D3DRS_ZENABLE,
1112 D3DRS_FILLMODE,
1113 D3DRS_SHADEMODE,
1114 D3DRS_ZWRITEENABLE,
1115 D3DRS_ALPHATESTENABLE,
1116 D3DRS_LASTPIXEL,
1117 D3DRS_SRCBLEND,
1118 D3DRS_DESTBLEND,
1119 D3DRS_CULLMODE,
1120 D3DRS_ZFUNC,
1121 D3DRS_ALPHAREF,
1122 D3DRS_ALPHAFUNC,
1123 D3DRS_DITHERENABLE,
1124 D3DRS_ALPHABLENDENABLE,
1125 D3DRS_FOGENABLE,
1126 D3DRS_SPECULARENABLE,
1127 D3DRS_FOGCOLOR,
1128 D3DRS_FOGTABLEMODE,
1129 D3DRS_FOGSTART,
1130 D3DRS_FOGEND,
1131 D3DRS_FOGDENSITY,
1132 D3DRS_RANGEFOGENABLE,
1133 D3DRS_STENCILENABLE,
1134 D3DRS_STENCILFAIL,
1135 D3DRS_STENCILZFAIL,
1136 D3DRS_STENCILPASS,
1137 D3DRS_STENCILFUNC,
1138 D3DRS_STENCILREF,
1139 D3DRS_STENCILMASK,
1140 D3DRS_STENCILWRITEMASK,
1141 D3DRS_TEXTUREFACTOR,
1142 D3DRS_WRAP0,
1143 D3DRS_WRAP1,
1144 D3DRS_WRAP2,
1145 D3DRS_WRAP3,
1146 D3DRS_WRAP4,
1147 D3DRS_WRAP5,
1148 D3DRS_WRAP6,
1149 D3DRS_WRAP7,
1150 D3DRS_CLIPPING,
1151 D3DRS_LIGHTING,
1152 D3DRS_AMBIENT,
1153 D3DRS_FOGVERTEXMODE,
1154 D3DRS_COLORVERTEX,
1155 D3DRS_LOCALVIEWER,
1156 D3DRS_NORMALIZENORMALS,
1157 D3DRS_DIFFUSEMATERIALSOURCE,
1158 D3DRS_SPECULARMATERIALSOURCE,
1159 D3DRS_AMBIENTMATERIALSOURCE,
1160 D3DRS_EMISSIVEMATERIALSOURCE,
1161 D3DRS_VERTEXBLEND,
1162 D3DRS_CLIPPLANEENABLE,
1163 #if 0 /* Driver dependent */
1164 D3DRS_POINTSIZE,
1165 #endif
1166 D3DRS_POINTSIZE_MIN,
1167 D3DRS_POINTSPRITEENABLE,
1168 D3DRS_POINTSCALEENABLE,
1169 D3DRS_POINTSCALE_A,
1170 D3DRS_POINTSCALE_B,
1171 D3DRS_POINTSCALE_C,
1172 D3DRS_MULTISAMPLEANTIALIAS,
1173 D3DRS_MULTISAMPLEMASK,
1174 D3DRS_PATCHEDGESTYLE,
1175 #if 0 /* Apparently not recorded in the stateblock */
1176 D3DRS_DEBUGMONITORTOKEN,
1177 #endif
1178 D3DRS_POINTSIZE_MAX,
1179 D3DRS_INDEXEDVERTEXBLENDENABLE,
1180 D3DRS_COLORWRITEENABLE,
1181 D3DRS_TWEENFACTOR,
1182 D3DRS_BLENDOP,
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;
1208 unsigned int i;
1209 HRESULT hr;
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;
1223 unsigned int i;
1224 HRESULT hr;
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;
1240 ret.f = fl;
1241 return ret.d;
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)
1321 unsigned int i;
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[] =
1407 D3DRS_AMBIENT,
1408 D3DRS_AMBIENTMATERIALSOURCE,
1409 D3DRS_CLIPPING,
1410 D3DRS_CLIPPLANEENABLE,
1411 D3DRS_COLORVERTEX,
1412 D3DRS_CULLMODE,
1413 D3DRS_DIFFUSEMATERIALSOURCE,
1414 D3DRS_EMISSIVEMATERIALSOURCE,
1415 D3DRS_FOGCOLOR,
1416 D3DRS_FOGDENSITY,
1417 D3DRS_FOGENABLE,
1418 D3DRS_FOGEND,
1419 D3DRS_FOGSTART,
1420 D3DRS_FOGTABLEMODE,
1421 D3DRS_FOGVERTEXMODE,
1422 D3DRS_INDEXEDVERTEXBLENDENABLE,
1423 D3DRS_LIGHTING,
1424 D3DRS_LOCALVIEWER,
1425 D3DRS_MULTISAMPLEANTIALIAS,
1426 D3DRS_MULTISAMPLEMASK,
1427 D3DRS_NORMALIZENORMALS,
1428 D3DRS_PATCHEDGESTYLE,
1429 D3DRS_POINTSCALE_A,
1430 D3DRS_POINTSCALE_B,
1431 D3DRS_POINTSCALE_C,
1432 D3DRS_POINTSCALEENABLE,
1433 D3DRS_POINTSIZE,
1434 D3DRS_POINTSIZE_MAX,
1435 D3DRS_POINTSIZE_MIN,
1436 D3DRS_POINTSPRITEENABLE,
1437 D3DRS_RANGEFOGENABLE,
1438 D3DRS_SHADEMODE,
1439 D3DRS_SPECULARENABLE,
1440 D3DRS_SPECULARMATERIALSOURCE,
1441 D3DRS_TWEENFACTOR,
1442 D3DRS_VERTEXBLEND,
1445 static const DWORD states_pixel[] =
1447 D3DRS_ALPHABLENDENABLE,
1448 D3DRS_ALPHAFUNC,
1449 D3DRS_ALPHAREF,
1450 D3DRS_ALPHATESTENABLE,
1451 D3DRS_BLENDOP,
1452 D3DRS_COLORWRITEENABLE,
1453 D3DRS_DESTBLEND,
1454 D3DRS_DITHERENABLE,
1455 D3DRS_FILLMODE,
1456 D3DRS_FOGDENSITY,
1457 D3DRS_FOGEND,
1458 D3DRS_FOGSTART,
1459 D3DRS_LASTPIXEL,
1460 D3DRS_SHADEMODE,
1461 D3DRS_SRCBLEND,
1462 D3DRS_STENCILENABLE,
1463 D3DRS_STENCILFAIL,
1464 D3DRS_STENCILFUNC,
1465 D3DRS_STENCILMASK,
1466 D3DRS_STENCILPASS,
1467 D3DRS_STENCILREF,
1468 D3DRS_STENCILWRITEMASK,
1469 D3DRS_STENCILZFAIL,
1470 D3DRS_TEXTUREFACTOR,
1471 D3DRS_WRAP0,
1472 D3DRS_WRAP1,
1473 D3DRS_WRAP2,
1474 D3DRS_WRAP3,
1475 D3DRS_WRAP4,
1476 D3DRS_WRAP5,
1477 D3DRS_WRAP6,
1478 D3DRS_WRAP7,
1479 D3DRS_ZENABLE,
1480 D3DRS_ZFUNC,
1481 D3DRS_ZWRITEENABLE,
1484 const struct render_state_arg *rsarg = test->test_arg;
1485 unsigned int i, j;
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];
1510 break;
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];
1520 break;
1525 return D3D_OK;
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
1547 DWORD vs_version;
1548 DWORD ps_version;
1549 UINT stream_count;
1550 UINT tex_count;
1553 struct resource_test_data
1555 DWORD vs;
1556 DWORD ps;
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;
1575 unsigned int i;
1576 HRESULT hr;
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",
1591 i, d->vb[i], hr);
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;
1608 unsigned int i;
1609 HRESULT hr;
1610 void *ptr;
1611 DWORD v;
1613 v = poison->vs;
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);
1619 v = poison->ps;
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);
1625 ptr = poison->ib;
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)
1664 unsigned int i;
1666 data->vs = 0;
1667 data->ps = 0;
1668 data->ib = NULL;
1669 data->vb = HeapAlloc(GetProcessHeap(), 0, arg->stream_count * sizeof(*data->vb));
1670 for (i = 0; i < arg->stream_count; ++i)
1672 data->vb[i] = NULL;
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[] =
1705 D3DVSD_STREAM(0),
1706 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
1707 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
1708 D3DVSD_END(),
1711 unsigned int i;
1712 HRESULT hr;
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;
1749 unsigned int i;
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;
1791 return D3D_OK;
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;
1798 unsigned int i;
1799 HRESULT hr;
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)
1853 D3DCAPS8 caps;
1854 HRESULT hr;
1856 /* Test count: 2 for shader constants
1857 * 1 for lights
1858 * 1 for transforms
1859 * 1 for render states
1860 * 1 for resources
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);
1894 light_arg.idx = 0;
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;
1918 DWORD stateblock;
1919 D3DCAPS8 caps;
1920 float ret[4];
1921 HRESULT hr;
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;
1928 if (vs_version)
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);
1949 if (ps_version)
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);
1974 if (vs_version)
1976 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 1, vs_const, 1);
1977 ok(SUCCEEDED(hr), "SetVertexShaderConstant returned %#x.\n", hr);
1979 if (ps_version)
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);
1988 if (vs_version)
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]);
2001 if (ps_version)
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);
2019 if (vs_version)
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]);
2032 if (ps_version)
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;
2054 ULONG refcount;
2055 HRESULT hr;
2057 d3d8_module = LoadLibraryA("d3d8.dll");
2058 if (!d3d8_module)
2060 skip("Could not load d3d8.dll\n");
2061 return;
2064 hr = init_d3d8(d3d8_module, &device, &device_pparams);
2065 if (FAILED(hr))
2067 FreeLibrary(d3d8_module);
2068 return;
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);