2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2007, 2009, 2011-2013 Stefan Dösinger(for CodeWeavers)
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 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
27 #include "wine/test.h"
44 static HWND
create_window(void)
48 SetRect(&rect
, 0, 0, 640, 480);
49 AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
50 return CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
51 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
, 0, 0, 0, 0);
54 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
56 unsigned int diff
= x
> y
? x
- y
: y
- x
;
58 return diff
<= max_diff
;
61 static BOOL
color_match(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
63 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
64 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
65 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
66 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
69 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
79 if (abs(x
- y
) > ulps
)
85 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
87 return compare_float(vec
->x
, x
, ulps
)
88 && compare_float(vec
->y
, y
, ulps
)
89 && compare_float(vec
->z
, z
, ulps
)
90 && compare_float(vec
->w
, w
, ulps
);
93 static BOOL
adapter_is_warp(const D3DADAPTER_IDENTIFIER8
*identifier
)
95 return !strcmp(identifier
->Driver
, "d3d10warp.dll");
98 struct surface_readback
100 IDirect3DSurface8
*surface
;
101 D3DLOCKED_RECT locked_rect
;
104 static void get_rt_readback(IDirect3DSurface8
*surface
, struct surface_readback
*rb
)
106 IDirect3DTexture8
*tex
= NULL
;
107 IDirect3DDevice8
*device
;
108 D3DSURFACE_DESC desc
;
111 memset(rb
, 0, sizeof(*rb
));
112 hr
= IDirect3DSurface8_GetDevice(surface
, &device
);
113 ok(SUCCEEDED(hr
), "Failed to get device, hr %#x.\n", hr
);
114 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
115 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
116 hr
= IDirect3DDevice8_CreateTexture(device
, desc
.Width
, desc
.Height
, 1, 0, desc
.Format
, D3DPOOL_SYSTEMMEM
, &tex
);
117 if (FAILED(hr
) || !tex
)
119 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr
);
122 hr
= IDirect3DTexture8_GetSurfaceLevel(tex
, 0, &rb
->surface
);
125 trace("Can't get surface from texture, hr %#x.\n", hr
);
128 hr
= IDirect3DDevice8_CopyRects(device
, surface
, NULL
, 0, rb
->surface
, NULL
);
131 trace("Can't read the render target, hr %#x.\n", hr
);
134 hr
= IDirect3DSurface8_LockRect(rb
->surface
, &rb
->locked_rect
, NULL
, D3DLOCK_READONLY
);
137 trace("Can't lock the offscreen surface, hr %#x.\n", hr
);
140 IDirect3DTexture8_Release(tex
);
141 IDirect3DDevice8_Release(device
);
146 IDirect3DSurface8_Release(rb
->surface
);
149 IDirect3DTexture8_Release(tex
);
150 IDirect3DDevice8_Release(device
);
153 static DWORD
get_readback_color(struct surface_readback
*rb
, unsigned int x
, unsigned int y
)
155 return rb
->locked_rect
.pBits
156 ? ((DWORD
*)rb
->locked_rect
.pBits
)[y
* rb
->locked_rect
.Pitch
/ sizeof(DWORD
) + x
] : 0xdeadbeef;
159 static void release_surface_readback(struct surface_readback
*rb
)
165 if (rb
->locked_rect
.pBits
&& FAILED(hr
= IDirect3DSurface8_UnlockRect(rb
->surface
)))
166 trace("Can't unlock the offscreen surface, hr %#x.\n", hr
);
167 IDirect3DSurface8_Release(rb
->surface
);
170 static DWORD
getPixelColor(IDirect3DDevice8
*device
, UINT x
, UINT y
)
173 IDirect3DSurface8
*rt
;
174 struct surface_readback rb
;
177 hr
= IDirect3DDevice8_GetRenderTarget(device
, &rt
);
180 trace("Can't get the render target, hr %#x.\n", hr
);
184 get_rt_readback(rt
, &rb
);
185 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
186 * really important for these tests
188 ret
= get_readback_color(&rb
, x
, y
) & 0x00ffffff;
189 release_surface_readback(&rb
);
191 IDirect3DSurface8_Release(rt
);
195 static D3DCOLOR
get_surface_color(IDirect3DSurface8
*surface
, UINT x
, UINT y
)
199 D3DSURFACE_DESC desc
;
200 RECT rectToLock
= {x
, y
, x
+1, y
+1};
201 D3DLOCKED_RECT lockedRect
;
203 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
204 ok(SUCCEEDED(hr
), "Failed to get surface description, hr=%#x.\n", hr
);
206 hr
= IDirect3DSurface8_LockRect(surface
, &lockedRect
, &rectToLock
, D3DLOCK_READONLY
);
207 ok(SUCCEEDED(hr
), "Failed to lock surface, hr=%#x.\n", hr
);
211 case D3DFMT_A8R8G8B8
:
212 color
= ((D3DCOLOR
*)lockedRect
.pBits
)[0];
216 trace("Error: unknown surface format: %u.\n", desc
.Format
);
221 hr
= IDirect3DSurface8_UnlockRect(surface
);
222 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr=%#x.\n", hr
);
227 static void check_rect(struct surface_readback
*rb
, RECT r
, const char *message
)
229 LONG x_coords
[2][2] =
231 {r
.left
- 1, r
.left
+ 1},
232 {r
.right
+ 1, r
.right
- 1},
234 LONG y_coords
[2][2] =
236 {r
.top
- 1, r
.top
+ 1},
237 {r
.bottom
+ 1, r
.bottom
- 1}
239 unsigned int i
, j
, x_side
, y_side
;
243 for (i
= 0; i
< 2; ++i
)
245 for (j
= 0; j
< 2; ++j
)
247 for (x_side
= 0; x_side
< 2; ++x_side
)
249 for (y_side
= 0; y_side
< 2; ++y_side
)
251 DWORD expected
= (x_side
== 1 && y_side
== 1) ? 0xffffffff : 0xff000000;
253 x
= x_coords
[i
][x_side
];
254 y
= y_coords
[j
][y_side
];
255 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
257 color
= get_readback_color(rb
, x
, y
);
258 ok(color
== expected
, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n",
259 message
, x
, y
, color
, expected
);
266 static IDirect3DDevice8
*create_device(IDirect3D8
*d3d
, HWND device_window
, HWND focus_window
, BOOL windowed
)
268 D3DPRESENT_PARAMETERS present_parameters
= {0};
269 IDirect3DDevice8
*device
;
271 present_parameters
.Windowed
= windowed
;
272 present_parameters
.hDeviceWindow
= device_window
;
273 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
274 present_parameters
.BackBufferWidth
= 640;
275 present_parameters
.BackBufferHeight
= 480;
276 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
277 present_parameters
.EnableAutoDepthStencil
= TRUE
;
278 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
280 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
281 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
)))
287 static void test_sanity(void)
289 IDirect3DDevice8
*device
;
296 window
= create_window();
297 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
298 ok(!!d3d
, "Failed to create a D3D object.\n");
299 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
301 skip("Failed to create a D3D device, skipping tests.\n");
305 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
306 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
307 color
= getPixelColor(device
, 1, 1);
308 ok(color
== 0x00ff0000, "Got unexpected color 0x%08x.\n", color
);
310 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
311 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
313 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ddee, 1.0f
, 0);
314 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
315 color
= getPixelColor(device
, 639, 479);
316 ok(color
== 0x0000ddee, "Got unexpected color 0x%08x.\n", color
);
318 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
319 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
321 refcount
= IDirect3DDevice8_Release(device
);
322 ok(!refcount
, "Device has %u references left.\n", refcount
);
324 IDirect3D8_Release(d3d
);
325 DestroyWindow(window
);
328 static void lighting_test(void)
330 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
331 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
332 IDirect3DDevice8
*device
;
342 struct vec3 position
;
347 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
348 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
349 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
350 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
354 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
355 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
356 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
357 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
361 struct vec3 position
;
367 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
368 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
369 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
370 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
374 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
375 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
376 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
377 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
381 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
382 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
383 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
384 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
388 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
389 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
390 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
391 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
395 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
396 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
397 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
398 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
400 static const WORD indices
[] = {0, 1, 2, 2, 3, 0};
401 static const D3DMATRIX mat
=
403 1.0f
, 0.0f
, 0.0f
, 0.0f
,
404 0.0f
, 1.0f
, 0.0f
, 0.0f
,
405 0.0f
, 0.0f
, 1.0f
, 0.0f
,
406 0.0f
, 0.0f
, 0.0f
, 1.0f
,
410 1.0f
, 0.0f
, 1.0f
, 0.0f
,
411 0.0f
, 1.0f
, 0.0f
, 0.0f
,
412 1.0f
, 0.0f
, 1.0f
, 0.0f
,
413 0.0f
, 0.0f
, 0.5f
, 1.0f
,
417 0.0f
, 0.0f
, 1.0f
, 0.0f
,
418 0.0f
, 1.0f
, 0.0f
, 0.0f
,
419 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
420 10.f
, 10.0f
, 10.0f
, 1.0f
,
424 1.0f
, 0.0f
, 0.0f
, 0.0f
,
425 0.0f
, 1.0f
, 0.0f
, 0.0f
,
426 0.0f
, 0.0f
, 1.0f
, -1.0f
,
427 10.f
, 10.0f
, 10.0f
, 0.0f
,
431 const D3DMATRIX
*world_matrix
;
439 {&mat
, nquad
, sizeof(nquad
[0]), 0x000000ff, "Lit quad with light"},
440 {&mat_singular
, nquad
, sizeof(nquad
[0]), 0x000000ff, "Lit quad with singular world matrix"},
441 {&mat_transf
, rotatedquad
, sizeof(rotatedquad
[0]), 0x000000ff, "Lit quad with transformation matrix"},
442 {&mat_nonaffine
, translatedquad
, sizeof(translatedquad
[0]), 0x00000000, "Lit quad with non-affine matrix"},
445 window
= create_window();
446 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
447 ok(!!d3d
, "Failed to create a D3D object.\n");
448 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
450 skip("Failed to create a D3D device, skipping tests.\n");
454 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
455 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
457 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &mat
);
458 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
459 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_VIEW
, &mat
);
460 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
461 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &mat
);
462 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
463 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
464 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
465 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
466 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
467 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
468 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
469 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_STENCILENABLE
, FALSE
);
470 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
471 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CULLMODE
, D3DCULL_NONE
);
472 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr
);
474 hr
= IDirect3DDevice8_SetVertexShader(device
, fvf
);
475 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
477 hr
= IDirect3DDevice8_BeginScene(device
);
478 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
480 /* No lights are defined... That means, lit vertices should be entirely black. */
481 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
482 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
483 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
484 2, indices
, D3DFMT_INDEX16
, unlitquad
, sizeof(unlitquad
[0]));
485 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
487 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
488 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
489 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
490 2, indices
, D3DFMT_INDEX16
, litquad
, sizeof(litquad
[0]));
491 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
493 hr
= IDirect3DDevice8_SetVertexShader(device
, nfvf
);
494 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
496 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
497 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
498 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
499 2, indices
, D3DFMT_INDEX16
, unlitnquad
, sizeof(unlitnquad
[0]));
500 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
502 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
503 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
504 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
505 2, indices
, D3DFMT_INDEX16
, litnquad
, sizeof(litnquad
[0]));
506 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
508 hr
= IDirect3DDevice8_EndScene(device
);
509 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
511 color
= getPixelColor(device
, 160, 360); /* Lower left quad - unlit without normals */
512 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color
);
513 color
= getPixelColor(device
, 160, 120); /* Upper left quad - lit without normals */
514 ok(color
== 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color
);
515 color
= getPixelColor(device
, 480, 360); /* Lower right quad - unlit with normals */
516 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color
);
517 color
= getPixelColor(device
, 480, 120); /* Upper right quad - lit with normals */
518 ok(color
== 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color
);
520 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
522 hr
= IDirect3DDevice8_LightEnable(device
, 0, TRUE
);
523 ok(SUCCEEDED(hr
), "Failed to enable light 0, hr %#x.\n", hr
);
525 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
527 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLD
, tests
[i
].world_matrix
);
528 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
530 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
531 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
533 hr
= IDirect3DDevice8_BeginScene(device
);
534 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
536 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
537 2, indices
, D3DFMT_INDEX16
, tests
[i
].quad
, tests
[i
].size
);
538 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
540 hr
= IDirect3DDevice8_EndScene(device
);
541 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
543 color
= getPixelColor(device
, 320, 240);
544 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
547 refcount
= IDirect3DDevice8_Release(device
);
548 ok(!refcount
, "Device has %u references left.\n", refcount
);
550 IDirect3D8_Release(d3d
);
551 DestroyWindow(window
);
554 static void test_specular_lighting(void)
556 static const unsigned int vertices_side
= 5;
557 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
558 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
559 static const D3DMATRIX mat
=
561 1.0f
, 0.0f
, 0.0f
, 0.0f
,
562 0.0f
, 1.0f
, 0.0f
, 0.0f
,
563 0.0f
, 0.0f
, 1.0f
, 0.0f
,
564 0.0f
, 0.0f
, 0.0f
, 1.0f
,
566 static const D3DLIGHT8 directional
=
568 D3DLIGHT_DIRECTIONAL
,
569 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
570 {1.0f
, 1.0f
, 1.0f
, 0.0f
},
571 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
578 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
579 {1.0f
, 1.0f
, 1.0f
, 0.0f
},
580 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
590 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
591 {1.0f
, 1.0f
, 1.0f
, 0.0f
},
592 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
598 M_PI
/ 12.0f
, M_PI
/ 3.0f
600 /* The chosen range value makes the test fail when using a manhattan
601 * distance metric vs the correct euclidean distance. */
605 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
606 {1.0f
, 1.0f
, 1.0f
, 0.0f
},
607 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
617 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
618 {1.0f
, 1.0f
, 1.0f
, 0.0f
},
619 {0.0f
, 0.0f
, 0.0f
, 0.0f
},
626 static const struct expected_color
631 expected_directional
[] =
633 {160, 120, 0x00ffffff},
634 {320, 120, 0x00ffffff},
635 {480, 120, 0x00ffffff},
636 {160, 240, 0x00ffffff},
637 {320, 240, 0x00ffffff},
638 {480, 240, 0x00ffffff},
639 {160, 360, 0x00ffffff},
640 {320, 360, 0x00ffffff},
641 {480, 360, 0x00ffffff},
643 expected_directional_local
[] =
645 {160, 120, 0x003c3c3c},
646 {320, 120, 0x00717171},
647 {480, 120, 0x003c3c3c},
648 {160, 240, 0x00717171},
649 {320, 240, 0x00ffffff},
650 {480, 240, 0x00717171},
651 {160, 360, 0x003c3c3c},
652 {320, 360, 0x00717171},
653 {480, 360, 0x003c3c3c},
657 {160, 120, 0x00282828},
658 {320, 120, 0x005a5a5a},
659 {480, 120, 0x00282828},
660 {160, 240, 0x005a5a5a},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x005a5a5a},
663 {160, 360, 0x00282828},
664 {320, 360, 0x005a5a5a},
665 {480, 360, 0x00282828},
667 expected_point_local
[] =
669 {160, 120, 0x00000000},
670 {320, 120, 0x00070707},
671 {480, 120, 0x00000000},
672 {160, 240, 0x00070707},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x00070707},
675 {160, 360, 0x00000000},
676 {320, 360, 0x00070707},
677 {480, 360, 0x00000000},
681 {160, 120, 0x00000000},
682 {320, 120, 0x00141414},
683 {480, 120, 0x00000000},
684 {160, 240, 0x00141414},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x00141414},
687 {160, 360, 0x00000000},
688 {320, 360, 0x00141414},
689 {480, 360, 0x00000000},
691 expected_spot_local
[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00020202},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00020202},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00020202},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00020202},
701 {480, 360, 0x00000000},
703 expected_point_range
[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x005a5a5a},
707 {480, 120, 0x00000000},
708 {160, 240, 0x005a5a5a},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x005a5a5a},
711 {160, 360, 0x00000000},
712 {320, 360, 0x005a5a5a},
713 {480, 360, 0x00000000},
715 expected_point_side
[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x00000000},
719 {480, 120, 0x00000000},
720 {160, 240, 0x00000000},
721 {320, 240, 0x00000000},
722 {480, 240, 0x00000000},
723 {160, 360, 0x00000000},
724 {320, 360, 0x00000000},
725 {480, 360, 0x00000000},
727 expected_directional_0
[] =
729 {160, 120, 0x00ffffff},
730 {320, 120, 0x00ffffff},
731 {480, 120, 0x00ffffff},
732 {160, 240, 0x00ffffff},
733 {320, 240, 0x00ffffff},
734 {480, 240, 0x00ffffff},
735 {160, 360, 0x00ffffff},
736 {320, 360, 0x00ffffff},
737 {480, 360, 0x00ffffff},
739 expected_directional_local_0
[] =
741 {160, 120, 0x00ffffff},
742 {320, 120, 0x00ffffff},
743 {480, 120, 0x00ffffff},
744 {160, 240, 0x00ffffff},
745 {320, 240, 0x00ffffff},
746 {480, 240, 0x00ffffff},
747 {160, 360, 0x00ffffff},
748 {320, 360, 0x00ffffff},
749 {480, 360, 0x00ffffff},
753 {160, 120, 0x00aaaaaa},
754 {320, 120, 0x00cccccc},
755 {480, 120, 0x00aaaaaa},
756 {160, 240, 0x00cccccc},
757 {320, 240, 0x00ffffff},
758 {480, 240, 0x00cccccc},
759 {160, 360, 0x00aaaaaa},
760 {320, 360, 0x00cccccc},
761 {480, 360, 0x00aaaaaa},
765 {160, 120, 0x00000000},
766 {320, 120, 0x002e2e2e},
767 {480, 120, 0x00000000},
768 {160, 240, 0x002e2e2e},
769 {320, 240, 0x00ffffff},
770 {480, 240, 0x002e2e2e},
771 {160, 360, 0x00000000},
772 {320, 360, 0x002e2e2e},
773 {480, 360, 0x00000000},
775 expected_point_range_0
[] =
777 {160, 120, 0x00000000},
778 {320, 120, 0x00cccccc},
779 {480, 120, 0x00000000},
780 {160, 240, 0x00cccccc},
781 {320, 240, 0x00ffffff},
782 {480, 240, 0x00cccccc},
783 {160, 360, 0x00000000},
784 {320, 360, 0x00cccccc},
785 {480, 360, 0x00000000},
789 const D3DLIGHT8
*light
;
791 float specular_power
;
792 const struct expected_color
*expected
;
793 unsigned int expected_count
;
797 {&directional
, FALSE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
798 {&directional
, TRUE
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
799 {&point
, FALSE
, 30.0f
, expected_point
, ARRAY_SIZE(expected_point
)},
800 {&point
, TRUE
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
801 {&spot
, FALSE
, 30.0f
, expected_spot
, ARRAY_SIZE(expected_spot
)},
802 {&spot
, TRUE
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
803 {&point_range
, FALSE
, 30.0f
, expected_point_range
, ARRAY_SIZE(expected_point_range
)},
804 {&point_side
, TRUE
, 0.0f
, expected_point_side
, ARRAY_SIZE(expected_point_side
)},
805 {&directional
, FALSE
, 0.0f
, expected_directional_0
, ARRAY_SIZE(expected_directional_0
)},
806 {&directional
, TRUE
, 0.0f
, expected_directional_local_0
, ARRAY_SIZE(expected_directional_local_0
)},
807 {&point
, FALSE
, 0.0f
, expected_point_0
, ARRAY_SIZE(expected_point_0
)},
808 {&point
, TRUE
, 0.0f
, expected_point_0
, ARRAY_SIZE(expected_point_0
)},
809 {&spot
, FALSE
, 0.0f
, expected_spot_0
, ARRAY_SIZE(expected_spot_0
)},
810 {&spot
, TRUE
, 0.0f
, expected_spot_0
, ARRAY_SIZE(expected_spot_0
)},
811 {&point_range
, FALSE
, 0.0f
, expected_point_range_0
, ARRAY_SIZE(expected_point_range_0
)},
813 IDirect3DDevice8
*device
;
814 D3DMATERIAL8 material
;
820 unsigned int i
, j
, x
, y
;
823 struct vec3 position
;
828 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
829 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
830 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
832 for (x
= 0; x
< vertices_side
; ++x
)
834 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
835 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
836 quad
[i
].position
.z
= 1.0f
;
837 quad
[i
].normal
.x
= 0.0f
;
838 quad
[i
].normal
.y
= 0.0f
;
839 quad
[i
++].normal
.z
= -1.0f
;
842 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
844 for (x
= 0; x
< (vertices_side
- 1); ++x
)
846 indices
[i
++] = y
* vertices_side
+ x
+ 1;
847 indices
[i
++] = y
* vertices_side
+ x
;
848 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
849 indices
[i
++] = y
* vertices_side
+ x
+ 1;
850 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
851 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
855 window
= create_window();
856 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
857 ok(!!d3d
, "Failed to create a D3D object.\n");
858 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
860 skip("Failed to create a D3D device, skipping tests.\n");
864 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLD
, &mat
);
865 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
866 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_VIEW
, &mat
);
867 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
868 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &mat
);
869 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
870 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
871 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
872 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
873 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
874 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
875 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
877 hr
= IDirect3DDevice8_SetVertexShader(device
, fvf
);
878 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
880 hr
= IDirect3DDevice8_LightEnable(device
, 0, TRUE
);
881 ok(SUCCEEDED(hr
), "Failed to enable light 0, hr %#x.\n", hr
);
882 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SPECULARENABLE
, TRUE
);
883 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
885 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
887 hr
= IDirect3DDevice8_SetLight(device
, 0, tests
[i
].light
);
888 ok(SUCCEEDED(hr
), "Failed to set light parameters, hr %#x.\n", hr
);
890 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LOCALVIEWER
, tests
[i
].local_viewer
);
891 ok(SUCCEEDED(hr
), "Failed to set local viewer state, hr %#x.\n", hr
);
893 memset(&material
, 0, sizeof(material
));
894 material
.Specular
.r
= 1.0f
;
895 material
.Specular
.g
= 1.0f
;
896 material
.Specular
.b
= 1.0f
;
897 material
.Specular
.a
= 1.0f
;
898 material
.Power
= tests
[i
].specular_power
;
899 hr
= IDirect3DDevice8_SetMaterial(device
, &material
);
900 ok(SUCCEEDED(hr
), "Failed to set material, hr %#x.\n", hr
);
902 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
903 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
905 hr
= IDirect3DDevice8_BeginScene(device
);
906 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
908 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
,
909 0, vertices_side
* vertices_side
, indices_count
/ 3, indices
,
910 D3DFMT_INDEX16
, quad
, sizeof(quad
[0]));
911 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
913 hr
= IDirect3DDevice8_EndScene(device
);
914 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
916 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
918 color
= getPixelColor(device
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
919 ok(color_match(color
, tests
[i
].expected
[j
].color
, 1),
920 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
921 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
922 tests
[i
].expected
[j
].y
, color
, i
);
926 refcount
= IDirect3DDevice8_Release(device
);
927 ok(!refcount
, "Device has %u references left.\n", refcount
);
929 IDirect3D8_Release(d3d
);
930 DestroyWindow(window
);
931 HeapFree(GetProcessHeap(), 0, indices
);
932 HeapFree(GetProcessHeap(), 0, quad
);
935 static void clear_test(void)
937 /* Tests the correctness of clearing parameters */
938 D3DRECT rect_negneg
, rect
[2];
939 IDirect3DDevice8
*device
;
946 window
= create_window();
947 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
948 ok(!!d3d
, "Failed to create a D3D object.\n");
949 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
951 skip("Failed to create a D3D device, skipping tests.\n");
955 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
956 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
958 /* Positive x, negative y */
964 /* Positive x, positive y */
969 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
970 * is ignored, the positive is still cleared afterwards
972 hr
= IDirect3DDevice8_Clear(device
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
973 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
975 /* negative x, negative y */
976 rect_negneg
.x1
= 640;
977 rect_negneg
.y1
= 240;
978 rect_negneg
.x2
= 320;
980 hr
= IDirect3DDevice8_Clear(device
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
981 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
983 color
= getPixelColor(device
, 160, 360); /* lower left quad */
984 ok(color
== 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color
);
985 color
= getPixelColor(device
, 160, 120); /* upper left quad */
986 ok(color
== 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color
);
987 color
= getPixelColor(device
, 480, 360); /* lower right quad */
988 ok(color
== 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color
);
989 color
= getPixelColor(device
, 480, 120); /* upper right quad */
990 ok(color
== 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color
);
992 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
994 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
995 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
1001 hr
= IDirect3DDevice8_Clear(device
, 0, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
1002 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
1004 color
= getPixelColor(device
, 320, 240);
1005 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1006 "Clear with count = 0, rect != NULL has color %#08x\n", color
);
1008 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1010 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
1011 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
1012 hr
= IDirect3DDevice8_Clear(device
, 1, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
1013 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
1015 color
= getPixelColor(device
, 320, 240);
1016 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1017 "Clear with count = 1, rect = NULL has color %#08x\n", color
);
1019 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1021 refcount
= IDirect3DDevice8_Release(device
);
1022 ok(!refcount
, "Device has %u references left.\n", refcount
);
1024 IDirect3D8_Release(d3d
);
1025 DestroyWindow(window
);
1028 static void fog_test(void)
1030 float start
= 0.0f
, end
= 1.0f
;
1031 IDirect3DDevice8
*device
;
1039 /* Gets full z based fog with linear fog, no fog with specular color. */
1048 {-1.0f
, -1.0f
, 0.1f
, 0xffff0000, 0xff000000},
1049 {-1.0f
, 0.0f
, 0.1f
, 0xffff0000, 0xff000000},
1050 { 0.0f
, 0.0f
, 0.1f
, 0xffff0000, 0xff000000},
1051 { 0.0f
, -1.0f
, 0.1f
, 0xffff0000, 0xff000000},
1053 /* Ok, I am too lazy to deal with transform matrices. */
1056 {-1.0f
, 0.0f
, 1.0f
, 0xffff0000, 0xff000000},
1057 {-1.0f
, 1.0f
, 1.0f
, 0xffff0000, 0xff000000},
1058 { 0.0f
, 1.0f
, 1.0f
, 0xffff0000, 0xff000000},
1059 { 0.0f
, 0.0f
, 1.0f
, 0xffff0000, 0xff000000},
1063 {-1.0f
, -1.0f
, 0.5f
, 0xffff0000, 0xff000000},
1064 {-1.0f
, 0.0f
, 0.5f
, 0xffff0000, 0xff000000},
1065 { 0.0f
, 0.0f
, 0.5f
, 0xffff0000, 0xff000000},
1066 { 0.0f
, -1.0f
, 0.5f
, 0xffff0000, 0xff000000},
1070 {-1.0f
, 0.0f
, 1.5f
, 0xffff0000, 0xff000000},
1071 {-1.0f
, 1.0f
, 1.5f
, 0xffff0000, 0xff000000},
1072 { 0.0f
, 1.0f
, 1.5f
, 0xffff0000, 0xff000000},
1073 { 0.0f
, 0.0f
, 1.5f
, 0xffff0000, 0xff000000},
1076 /* Untransformed ones. Give them a different diffuse color to make the
1077 * test look nicer. It also makes making sure that they are drawn
1078 * correctly easier. */
1087 {320.0f
, 0.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1088 {640.0f
, 0.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1089 {640.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1090 {320.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1094 {320.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1095 {640.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1096 {640.0f
, 480.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1097 {320.0f
, 480.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
1099 static const D3DMATRIX ident_mat
=
1101 1.0f
, 0.0f
, 0.0f
, 0.0f
,
1102 0.0f
, 1.0f
, 0.0f
, 0.0f
,
1103 0.0f
, 0.0f
, 1.0f
, 0.0f
,
1104 0.0f
, 0.0f
, 0.0f
, 1.0f
,
1106 static const D3DMATRIX world_mat1
=
1108 1.0f
, 0.0f
, 0.0f
, 0.0f
,
1109 0.0f
, 1.0f
, 0.0f
, 0.0f
,
1110 0.0f
, 0.0f
, 1.0f
, 0.0f
,
1111 0.0f
, 0.0f
, -0.5f
, 1.0f
,
1113 static const D3DMATRIX world_mat2
=
1115 1.0f
, 0.0f
, 0.0f
, 0.0f
,
1116 0.0f
, 1.0f
, 0.0f
, 0.0f
,
1117 0.0f
, 0.0f
, 1.0f
, 0.0f
,
1118 0.0f
, 0.0f
, 1.0f
, 1.0f
,
1120 static const D3DMATRIX proj_mat
=
1122 1.0f
, 0.0f
, 0.0f
, 0.0f
,
1123 0.0f
, 1.0f
, 0.0f
, 0.0f
,
1124 0.0f
, 0.0f
, 1.0f
, 0.0f
,
1125 0.0f
, 0.0f
, -1.0f
, 1.0f
,
1127 static const WORD Indices
[] = {0, 1, 2, 2, 3, 0};
1129 window
= create_window();
1130 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1131 ok(!!d3d
, "Failed to create a D3D object.\n");
1132 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1134 skip("Failed to create a D3D device, skipping tests.\n");
1138 memset(&caps
, 0, sizeof(caps
));
1139 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1140 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr
);
1141 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
1142 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %#08x\n", hr
);
1144 /* Setup initial states: No lighting, fog on, fog color */
1145 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
1146 ok(SUCCEEDED(hr
), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr
);
1147 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
1148 ok(hr
== D3D_OK
, "Turning off lighting returned %#08x\n", hr
);
1149 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
1150 ok(hr
== D3D_OK
, "Turning on fog calculations returned %#08x\n", hr
);
1151 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xFF00FF00 /* A nice green */);
1152 ok(hr
== D3D_OK
, "Setting fog color returned %#08x\n", hr
);
1153 /* Some of the tests seem to depend on the projection matrix explicitly
1154 * being set to an identity matrix, even though that's the default.
1155 * (AMD Radeon HD 6310, Windows 7) */
1156 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &ident_mat
);
1157 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
1159 /* First test: Both table fog and vertex fog off */
1160 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
1161 ok(hr
== D3D_OK
, "Turning off table fog returned %#08x\n", hr
);
1162 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
1163 ok(hr
== D3D_OK
, "Turning off vertex fog returned %#08x\n", hr
);
1165 /* Start = 0, end = 1. Should be default, but set them */
1166 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, *((DWORD
*) &start
));
1167 ok(hr
== D3D_OK
, "Setting fog start returned %#08x\n", hr
);
1168 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, *((DWORD
*) &end
));
1169 ok(hr
== D3D_OK
, "Setting fog start returned %#08x\n", hr
);
1171 hr
= IDirect3DDevice8_BeginScene(device
);
1172 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1174 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
1175 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1176 /* Untransformed, vertex fog = NONE, table fog = NONE:
1177 * Read the fog weighting from the specular color. */
1178 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
1179 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, untransformed_1
, sizeof(untransformed_1
[0]));
1180 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1182 /* This makes it use the Z value. */
1183 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_LINEAR
);
1184 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
1185 /* Untransformed, vertex fog != none (or table fog != none):
1186 * Use the Z value as input into the equation. */
1187 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
1188 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, untransformed_2
, sizeof(untransformed_2
[0]));
1189 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1191 /* Transformed vertices. */
1192 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
1193 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1194 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1195 * Use specular color alpha component. */
1196 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
1197 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, transformed_1
, sizeof(transformed_1
[0]));
1198 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1200 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
1201 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
1202 /* Transformed, table fog != none, vertex anything:
1203 * Use Z value as input to the fog equation. */
1204 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
1205 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, transformed_2
, sizeof(transformed_2
[0]));
1206 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1208 hr
= IDirect3DDevice8_EndScene(device
);
1209 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1211 color
= getPixelColor(device
, 160, 360);
1212 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1213 "Untransformed vertex with no table or vertex fog has color %08x\n", color
);
1214 color
= getPixelColor(device
, 160, 120);
1215 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1216 "Untransformed vertex with linear vertex fog has color %08x\n", color
);
1217 color
= getPixelColor(device
, 480, 120);
1218 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1219 "Transformed vertex with linear vertex fog has color %08x\n", color
);
1220 color
= getPixelColor(device
, 480, 360);
1221 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1222 "Transformed vertex with linear table fog has color %08x\n", color
);
1224 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1226 if (caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
)
1228 /* A simple fog + non-identity world matrix test */
1229 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &world_mat1
);
1230 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
1232 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
1233 ok(hr
== D3D_OK
, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr
);
1234 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
1235 ok(hr
== D3D_OK
, "Turning off vertex fog returned %#08x\n", hr
);
1237 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
1238 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %#08x\n", hr
);
1240 hr
= IDirect3DDevice8_BeginScene(device
);
1241 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1242 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
1243 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1244 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
1245 2, Indices
, D3DFMT_INDEX16
, far_quad1
, sizeof(far_quad1
[0]));
1246 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1247 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
1248 2, Indices
, D3DFMT_INDEX16
, far_quad2
, sizeof(far_quad2
[0]));
1249 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1250 hr
= IDirect3DDevice8_EndScene(device
);
1251 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1253 color
= getPixelColor(device
, 160, 360);
1254 ok(color_match(color
, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color
);
1255 color
= getPixelColor(device
, 160, 120);
1256 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1257 "Fogged out quad has color %08x\n", color
);
1259 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1261 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1262 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &world_mat2
);
1263 ok(hr
== D3D_OK
, "SetTransform returned %#08x\n", hr
);
1264 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &proj_mat
);
1265 ok(hr
== D3D_OK
, "SetTransform returned %#08x\n", hr
);
1267 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
1268 ok(hr
== D3D_OK
, "Clear returned %#08x\n", hr
);
1270 hr
= IDirect3DDevice8_BeginScene(device
);
1271 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1272 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
1273 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1274 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
1275 2, Indices
, D3DFMT_INDEX16
, untransformed_1
, sizeof(untransformed_1
[0]));
1276 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1277 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
1278 2, Indices
, D3DFMT_INDEX16
, untransformed_2
, sizeof(untransformed_2
[0]));
1279 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1280 hr
= IDirect3DDevice8_EndScene(device
);
1281 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1283 color
= getPixelColor(device
, 160, 360);
1284 ok(color_match(color
, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color
);
1285 color
= getPixelColor(device
, 160, 120);
1286 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1287 "Fogged out quad has color %08x\n", color
);
1289 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1293 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1296 refcount
= IDirect3DDevice8_Release(device
);
1297 ok(!refcount
, "Device has %u references left.\n", refcount
);
1299 IDirect3D8_Release(d3d
);
1300 DestroyWindow(window
);
1303 /* This tests fog in combination with shaders.
1304 * What's tested: linear fog (vertex and table) with pixel shader
1305 * linear table fog with non foggy vertex shader
1306 * vertex fog with foggy vertex shader, non-linear
1307 * fog with shader, non-linear fog with foggy shader,
1308 * linear table fog with foggy shader */
1309 static void fog_with_shader_test(void)
1311 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1312 DWORD vertex_shader
[3] = {D3DFVF_XYZ
| D3DFVF_DIFFUSE
, 0, 0};
1313 DWORD pixel_shader
[2] = {0, 0};
1314 IDirect3DDevice8
*device
;
1328 /* Basic vertex shader without fog computation ("non foggy") */
1329 static const DWORD vertex_shader_code1
[] =
1331 0xfffe0100, /* vs.1.0 */
1332 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1333 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1336 /* Basic vertex shader with reversed fog computation ("foggy") */
1337 static const DWORD vertex_shader_code2
[] =
1339 0xfffe0100, /* vs.1.0 */
1340 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1341 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1342 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1343 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1346 /* Basic pixel shader */
1347 static const DWORD pixel_shader_code
[] =
1349 0xffff0101, /* ps_1_1 */
1350 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1355 struct vec3 position
;
1360 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
1361 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
1362 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
1363 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
1365 static const DWORD decl
[] =
1368 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
1369 D3DVSD_REG(1, D3DVSDT_D3DCOLOR
), /* diffuse color, v1 */
1372 static const float vs_constant
[4] = {-1.25f
, 0.0f
, -0.9f
, 0.0f
};
1373 /* This reference data was collected on a nVidia GeForce 7600GS
1374 * driver version 84.19 DirectX version 9.0c on Windows XP */
1375 static const struct test_data_t
1381 BOOL uninitialized_reg
;
1382 unsigned int color
[11];
1386 /* Only pixel shader */
1387 {0, 1, D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
,
1388 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1389 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1390 {0, 1, D3DFOG_EXP
, D3DFOG_LINEAR
, FALSE
,
1391 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1392 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1393 {0, 1, D3DFOG_EXP2
, D3DFOG_LINEAR
, FALSE
,
1394 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1395 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1396 {0, 1, D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
,
1397 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1398 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1399 {0, 1, D3DFOG_LINEAR
, D3DFOG_LINEAR
, FALSE
,
1400 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1401 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1404 {1, 0, D3DFOG_NONE
, D3DFOG_NONE
, TRUE
,
1405 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1406 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1407 {1, 0, D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
,
1408 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410 {1, 0, D3DFOG_EXP
, D3DFOG_LINEAR
, FALSE
,
1411 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414 {1, 0, D3DFOG_EXP2
, D3DFOG_LINEAR
, FALSE
,
1415 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1417 {1, 0, D3DFOG_LINEAR
, D3DFOG_LINEAR
, FALSE
,
1418 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1419 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421 /* Vertex shader and pixel shader */
1422 /* The next 4 tests would read the fog coord output, but it isn't available.
1423 * The result is a fully fogged quad, no matter what the Z coord is. */
1424 {1, 1, D3DFOG_NONE
, D3DFOG_NONE
, TRUE
,
1425 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1426 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1427 {1, 1, D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
,
1428 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1429 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1430 {1, 1, D3DFOG_EXP
, D3DFOG_NONE
, TRUE
,
1431 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1432 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1433 {1, 1, D3DFOG_EXP2
, D3DFOG_NONE
, TRUE
,
1434 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1435 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1437 /* These use the Z coordinate with linear table fog */
1438 {1, 1, D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
,
1439 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1440 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1441 {1, 1, D3DFOG_EXP
, D3DFOG_LINEAR
, FALSE
,
1442 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1443 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1444 {1, 1, D3DFOG_EXP2
, D3DFOG_LINEAR
, FALSE
,
1445 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1446 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1447 {1, 1, D3DFOG_LINEAR
, D3DFOG_LINEAR
, FALSE
,
1448 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1449 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1451 /* Non-linear table fog without fog coord */
1452 {1, 1, D3DFOG_NONE
, D3DFOG_EXP
, FALSE
,
1453 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1454 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1455 {1, 1, D3DFOG_NONE
, D3DFOG_EXP2
, FALSE
,
1456 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1457 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1459 /* These tests fail on older Nvidia drivers */
1460 /* Foggy vertex shader */
1461 {2, 0, D3DFOG_NONE
, D3DFOG_NONE
, FALSE
,
1462 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464 {2, 0, D3DFOG_EXP
, D3DFOG_NONE
, FALSE
,
1465 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467 {2, 0, D3DFOG_EXP2
, D3DFOG_NONE
, FALSE
,
1468 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1470 {2, 0, D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
,
1471 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1472 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1474 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1475 * all using the fixed fog-coord linear fog */
1476 {2, 1, D3DFOG_NONE
, D3DFOG_NONE
, FALSE
,
1477 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1478 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1479 {2, 1, D3DFOG_EXP
, D3DFOG_NONE
, FALSE
,
1480 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1481 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1482 {2, 1, D3DFOG_EXP2
, D3DFOG_NONE
, FALSE
,
1483 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1484 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1485 {2, 1, D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
,
1486 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1487 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1489 /* These use table fog. Here the shader-provided fog coordinate is
1490 * ignored and the z coordinate used instead */
1491 {2, 1, D3DFOG_NONE
, D3DFOG_EXP
, FALSE
,
1492 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1493 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1494 {2, 1, D3DFOG_NONE
, D3DFOG_EXP2
, FALSE
,
1495 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1496 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1497 {2, 1, D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
,
1498 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1501 static const D3DMATRIX identity
=
1503 1.0f
, 0.0f
, 0.0f
, 0.0f
,
1504 0.0f
, 1.0f
, 0.0f
, 0.0f
,
1505 0.0f
, 0.0f
, 1.0f
, 0.0f
,
1506 0.0f
, 0.0f
, 0.0f
, 1.0f
,
1509 window
= create_window();
1510 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1511 ok(!!d3d
, "Failed to create a D3D object.\n");
1512 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1514 skip("Failed to create a D3D device, skipping tests.\n");
1518 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1519 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1520 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1) || caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
1522 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1523 IDirect3DDevice8_Release(device
);
1527 /* NOTE: changing these values will not affect the tests with foggy vertex
1528 * shader, as the values are hardcoded in the shader constant. */
1532 /* Some of the tests seem to depend on the projection matrix explicitly
1533 * being set to an identity matrix, even though that's the default.
1534 * (AMD Radeon HD 6310, Windows 7) */
1535 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
1536 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
1538 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vertex_shader_code1
, &vertex_shader
[1], 0);
1539 ok(SUCCEEDED(hr
), "CreateVertexShader failed (%08x)\n", hr
);
1540 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vertex_shader_code2
, &vertex_shader
[2], 0);
1541 ok(SUCCEEDED(hr
), "CreateVertexShader failed (%08x)\n", hr
);
1542 hr
= IDirect3DDevice8_CreatePixelShader(device
, pixel_shader_code
, &pixel_shader
[1]);
1543 ok(SUCCEEDED(hr
), "CreatePixelShader failed (%08x)\n", hr
);
1545 /* Set shader constant value */
1546 hr
= IDirect3DDevice8_SetVertexShader(device
, vertex_shader
[2]);
1547 ok(SUCCEEDED(hr
), "SetVertexShader failed (%08x)\n", hr
);
1548 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, vs_constant
, 1);
1549 ok(hr
== D3D_OK
, "Setting vertex shader constant failed (%08x)\n", hr
);
1551 /* Setup initial states: No lighting, fog on, fog color */
1552 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
1553 ok(hr
== D3D_OK
, "Turning off lighting failed (%08x)\n", hr
);
1554 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
1555 ok(hr
== D3D_OK
, "Turning on fog calculations failed (%08x)\n", hr
);
1556 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xFF00FF00 /* A nice green */);
1557 ok(hr
== D3D_OK
, "Setting fog color failed (%08x)\n", hr
);
1559 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
1560 ok(hr
== D3D_OK
, "Turning off table fog failed (%08x)\n", hr
);
1561 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
1562 ok(hr
== D3D_OK
, "Turning off vertex fog failed (%08x)\n", hr
);
1564 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1565 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, start
.i
);
1566 ok(hr
== D3D_OK
, "Setting fog start failed (%08x)\n", hr
);
1567 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, end
.i
);
1568 ok(hr
== D3D_OK
, "Setting fog end failed (%08x)\n", hr
);
1570 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
1572 hr
= IDirect3DDevice8_SetVertexShader(device
, vertex_shader
[test_data
[i
].vshader
]);
1573 ok(SUCCEEDED(hr
), "SetVertexShader failed (%08x)\n", hr
);
1574 hr
= IDirect3DDevice8_SetPixelShader(device
, pixel_shader
[test_data
[i
].pshader
]);
1575 ok(SUCCEEDED(hr
), "SetPixelShader failed (%08x)\n", hr
);
1576 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, test_data
[i
].vfog
);
1577 ok( hr
== D3D_OK
, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr
);
1578 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, test_data
[i
].tfog
);
1579 ok( hr
== D3D_OK
, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr
);
1581 for(j
= 0; j
< 11; ++j
)
1583 /* Don't use the whole zrange to prevent rounding errors */
1584 quad
[0].position
.z
= 0.001f
+ j
/ 10.02f
;
1585 quad
[1].position
.z
= 0.001f
+ j
/ 10.02f
;
1586 quad
[2].position
.z
= 0.001f
+ j
/ 10.02f
;
1587 quad
[3].position
.z
= 0.001f
+ j
/ 10.02f
;
1589 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff00ff, 1.0f
, 0);
1590 ok(hr
== D3D_OK
, "IDirect3DDevice9_Clear failed (%08x)\n", hr
);
1592 hr
= IDirect3DDevice8_BeginScene(device
);
1593 ok( hr
== D3D_OK
, "BeginScene returned failed (%08x)\n", hr
);
1595 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(quad
[0]));
1596 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed (%08x)\n", hr
);
1598 hr
= IDirect3DDevice8_EndScene(device
);
1599 ok(hr
== D3D_OK
, "EndScene failed (%08x)\n", hr
);
1601 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1602 color
= getPixelColor(device
, 128, 240);
1603 ok(color_match(color
, test_data
[i
].color
[j
], 13) || broken(test_data
[i
].uninitialized_reg
),
1604 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1605 test_data
[i
].vshader
, test_data
[i
].pshader
,
1606 test_data
[i
].vfog
, test_data
[i
].tfog
, j
, color
, test_data
[i
].color
[j
]);
1609 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1611 IDirect3DDevice8_DeleteVertexShader(device
, vertex_shader
[1]);
1612 IDirect3DDevice8_DeleteVertexShader(device
, vertex_shader
[2]);
1613 IDirect3DDevice8_DeleteVertexShader(device
, pixel_shader
[1]);
1614 refcount
= IDirect3DDevice8_Release(device
);
1615 ok(!refcount
, "Device has %u references left.\n", refcount
);
1617 IDirect3D8_Release(d3d
);
1618 DestroyWindow(window
);
1621 static void cnd_test(void)
1623 DWORD shader_11_coissue_2
, shader_12_coissue_2
, shader_13_coissue_2
, shader_14_coissue_2
;
1624 DWORD shader_11_coissue
, shader_12_coissue
, shader_13_coissue
, shader_14_coissue
;
1625 DWORD shader_11
, shader_12
, shader_13
, shader_14
;
1626 IDirect3DDevice8
*device
;
1634 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1635 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1636 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1637 * in 1.x pixel shaders. */
1638 static const DWORD shader_code_11
[] =
1640 0xffff0101, /* ps_1_1 */
1641 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1642 0x00000040, 0xb00f0000, /* texcoord t0 */
1643 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1644 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1645 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1646 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1647 0x0000ffff /* end */
1649 static const DWORD shader_code_12
[] =
1651 0xffff0102, /* ps_1_2 */
1652 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1653 0x00000040, 0xb00f0000, /* texcoord t0 */
1654 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1655 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1656 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1657 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1658 0x0000ffff /* end */
1660 static const DWORD shader_code_13
[] =
1662 0xffff0103, /* ps_1_3 */
1663 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1664 0x00000040, 0xb00f0000, /* texcoord t0 */
1665 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1666 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1667 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1668 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1669 0x0000ffff /* end */
1671 static const DWORD shader_code_14
[] =
1673 0xffff0104, /* ps_1_3 */
1674 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1675 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1676 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1677 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1678 0x0000ffff /* end */
1681 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1682 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1683 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1684 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1685 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1688 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1689 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1690 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1691 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1693 static const DWORD shader_code_11_coissue
[] =
1695 0xffff0101, /* ps_1_1 */
1696 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1697 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1698 0x00000040, 0xb00f0000, /* texcoord t0 */
1699 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1700 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1701 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1702 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1703 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1704 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1705 0x0000ffff /* end */
1707 static const DWORD shader_code_11_coissue_2
[] =
1709 0xffff0101, /* ps_1_1 */
1710 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1711 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1712 0x00000040, 0xb00f0000, /* texcoord t0 */
1713 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1714 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1715 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1716 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1717 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1718 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1719 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1720 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1721 0x0000ffff /* end */
1723 static const DWORD shader_code_12_coissue
[] =
1725 0xffff0102, /* ps_1_2 */
1726 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1727 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1728 0x00000040, 0xb00f0000, /* texcoord t0 */
1729 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1730 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1731 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1732 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1733 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1734 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1735 0x0000ffff /* end */
1737 static const DWORD shader_code_12_coissue_2
[] =
1739 0xffff0102, /* ps_1_2 */
1740 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1741 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1742 0x00000040, 0xb00f0000, /* texcoord t0 */
1743 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1744 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1745 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1746 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1747 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1748 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1749 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1750 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1751 0x0000ffff /* end */
1753 static const DWORD shader_code_13_coissue
[] =
1755 0xffff0103, /* ps_1_3 */
1756 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1757 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1758 0x00000040, 0xb00f0000, /* texcoord t0 */
1759 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1760 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1761 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1762 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1763 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1764 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1765 0x0000ffff /* end */
1767 static const DWORD shader_code_13_coissue_2
[] =
1769 0xffff0103, /* ps_1_3 */
1770 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1771 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1772 0x00000040, 0xb00f0000, /* texcoord t0 */
1773 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1774 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1775 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1776 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1777 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1778 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1779 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1780 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1781 0x0000ffff /* end */
1783 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1784 * texcrd result to cnd, it will compare against 0.5. */
1785 static const DWORD shader_code_14_coissue
[] =
1787 0xffff0104, /* ps_1_4 */
1788 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1789 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1790 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1791 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1792 0x0000ffff /* end */
1794 static const DWORD shader_code_14_coissue_2
[] =
1796 0xffff0104, /* ps_1_4 */
1797 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1798 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1799 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1800 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1801 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1802 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1803 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1804 0x0000ffff /* end */
1806 static const float quad1
[] =
1808 -1.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1809 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1810 0.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1811 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1813 static const float quad2
[] =
1815 0.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1816 0.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1817 1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1818 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1820 static const float quad3
[] =
1822 0.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1823 0.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1824 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1825 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1827 static const float quad4
[] =
1829 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1830 -1.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1831 0.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1832 0.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1834 static const float test_data_c1
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
1835 static const float test_data_c2
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
1836 static const float test_data_c1_coi
[4] = {0.0f
, 1.0f
, 0.0f
, 0.0f
};
1837 static const float test_data_c2_coi
[4] = {1.0f
, 0.0f
, 1.0f
, 1.0f
};
1839 window
= create_window();
1840 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1841 ok(!!d3d
, "Failed to create a D3D object.\n");
1842 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1844 skip("Failed to create a D3D device, skipping tests.\n");
1848 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1849 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1850 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 4))
1852 skip("No ps_1_4 support, skipping tests.\n");
1853 IDirect3DDevice8_Release(device
);
1857 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
1858 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1860 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11
, &shader_11
);
1861 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1862 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12
, &shader_12
);
1863 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1864 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13
, &shader_13
);
1865 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1866 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14
, &shader_14
);
1867 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1868 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11_coissue
, &shader_11_coissue
);
1869 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1870 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12_coissue
, &shader_12_coissue
);
1871 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1872 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13_coissue
, &shader_13_coissue
);
1873 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1874 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14_coissue
, &shader_14_coissue
);
1875 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1876 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11_coissue_2
, &shader_11_coissue_2
);
1877 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1878 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12_coissue_2
, &shader_12_coissue_2
);
1879 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1880 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13_coissue_2
, &shader_13_coissue_2
);
1881 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1882 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14_coissue_2
, &shader_14_coissue_2
);
1883 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1885 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, test_data_c1
, 1);
1886 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1887 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 2, test_data_c2
, 1);
1888 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1889 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
1890 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1892 hr
= IDirect3DDevice8_BeginScene(device
);
1893 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1895 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11
);
1896 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1897 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1898 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1900 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12
);
1901 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1902 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1903 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1905 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13
);
1906 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1907 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1908 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1910 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14
);
1911 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1912 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1913 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1915 hr
= IDirect3DDevice8_EndScene(device
);
1916 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1918 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
1919 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1921 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1922 color
= getPixelColor(device
, 158, 118);
1923 ok(color
== 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color
);
1924 color
= getPixelColor(device
, 162, 118);
1925 ok(color
== 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color
);
1926 color
= getPixelColor(device
, 158, 122);
1927 ok(color
== 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color
);
1928 color
= getPixelColor(device
, 162, 122);
1929 ok(color
== 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color
);
1931 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1932 color
= getPixelColor(device
, 158, 358);
1933 ok(color
== 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color
);
1934 color
= getPixelColor(device
, 162, 358);
1935 ok(color_match(color
, 0x00000000, 1),
1936 "pixel 162, 358 has color %08x, expected 0x00000000\n", color
);
1937 color
= getPixelColor(device
, 158, 362);
1938 ok(color
== 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color
);
1939 color
= getPixelColor(device
, 162, 362);
1940 ok(color_match(color
, 0x00000000, 1),
1941 "pixel 162, 362 has color %08x, expected 0x00000000\n", color
);
1944 color
= getPixelColor(device
, 478, 358);
1945 ok(color
== 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color
);
1946 color
= getPixelColor(device
, 482, 358);
1947 ok(color_match(color
, 0x00000000, 1),
1948 "pixel 482, 358 has color %08x, expected 0x00000000\n", color
);
1949 color
= getPixelColor(device
, 478, 362);
1950 ok(color
== 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color
);
1951 color
= getPixelColor(device
, 482, 362);
1952 ok(color_match(color
, 0x00000000, 1),
1953 "pixel 482, 362 has color %08x, expected 0x00000000\n", color
);
1956 color
= getPixelColor(device
, 478, 118);
1957 ok(color
== 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color
);
1958 color
= getPixelColor(device
, 482, 118);
1959 ok(color_match(color
, 0x00000000, 1),
1960 "pixel 482, 118 has color %08x, expected 0x00000000\n", color
);
1961 color
= getPixelColor(device
, 478, 122);
1962 ok(color
== 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color
);
1963 color
= getPixelColor(device
, 482, 122);
1964 ok(color_match(color
, 0x00000000, 1),
1965 "pixel 482, 122 has color %08x, expected 0x00000000\n", color
);
1967 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1968 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1970 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ffff, 0.0f
, 0);
1971 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1972 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, test_data_c1_coi
, 1);
1973 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1974 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 2, test_data_c2_coi
, 1);
1975 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1977 hr
= IDirect3DDevice8_BeginScene(device
);
1978 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1980 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11_coissue
);
1981 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1982 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1983 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1985 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12_coissue
);
1986 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1987 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1988 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1990 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13_coissue
);
1991 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1992 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1993 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1995 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14_coissue
);
1996 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1997 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1998 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
2000 hr
= IDirect3DDevice8_EndScene(device
);
2001 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
2003 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
2004 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
2006 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
2007 * that we swapped the values in c1 and c2 to make the other tests return some color
2009 color
= getPixelColor(device
, 158, 118);
2010 ok(color
== 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color
);
2011 color
= getPixelColor(device
, 162, 118);
2012 ok(color
== 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color
);
2013 color
= getPixelColor(device
, 158, 122);
2014 ok(color
== 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color
);
2015 color
= getPixelColor(device
, 162, 122);
2016 ok(color
== 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color
);
2018 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
2019 * (The Win7 nvidia driver always selects c2)
2021 color
= getPixelColor(device
, 158, 358);
2022 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2023 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color
);
2024 color
= getPixelColor(device
, 162, 358);
2025 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2026 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color
);
2027 color
= getPixelColor(device
, 158, 362);
2028 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2029 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color
);
2030 color
= getPixelColor(device
, 162, 362);
2031 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2032 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color
);
2035 color
= getPixelColor(device
, 478, 358);
2036 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2037 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color
);
2038 color
= getPixelColor(device
, 482, 358);
2039 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2040 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color
);
2041 color
= getPixelColor(device
, 478, 362);
2042 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2043 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color
);
2044 color
= getPixelColor(device
, 482, 362);
2045 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2046 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color
);
2049 color
= getPixelColor(device
, 478, 118);
2050 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2051 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color
);
2052 color
= getPixelColor(device
, 482, 118);
2053 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2054 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color
);
2055 color
= getPixelColor(device
, 478, 122);
2056 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2057 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color
);
2058 color
= getPixelColor(device
, 482, 122);
2059 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
2060 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color
);
2062 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2063 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
2065 /* Retest with the coissue flag on the alpha instruction instead. This
2066 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
2067 * the same as coissue on .rgb. */
2068 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ffff, 0.0f
, 0);
2069 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
2071 hr
= IDirect3DDevice8_BeginScene(device
);
2072 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
2074 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11_coissue_2
);
2075 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
2076 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
2077 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
2079 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12_coissue_2
);
2080 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
2081 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
2082 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
2084 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13_coissue_2
);
2085 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
2086 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
2087 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
2089 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14_coissue_2
);
2090 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
2091 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
2092 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
2094 hr
= IDirect3DDevice8_EndScene(device
);
2095 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
2098 color
= getPixelColor(device
, 158, 118);
2099 ok(color
== 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color
);
2100 color
= getPixelColor(device
, 162, 118);
2101 ok(color
== 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color
);
2102 color
= getPixelColor(device
, 158, 122);
2103 ok(color
== 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color
);
2104 color
= getPixelColor(device
, 162, 122);
2105 ok(color
== 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color
);
2108 color
= getPixelColor(device
, 238, 358);
2109 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
2110 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color
);
2111 color
= getPixelColor(device
, 242, 358);
2112 ok(color_match(color
, 0x00000000, 1),
2113 "pixel 242, 358 has color %08x, expected 0x00000000\n", color
);
2114 color
= getPixelColor(device
, 238, 362);
2115 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
2116 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color
);
2117 color
= getPixelColor(device
, 242, 362);
2118 ok(color_match(color
, 0x00000000, 1),
2119 "pixel 242, 362 has color %08x, expected 0x00000000\n", color
);
2122 color
= getPixelColor(device
, 558, 358);
2123 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
2124 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color
);
2125 color
= getPixelColor(device
, 562, 358);
2126 ok(color_match(color
, 0x00000000, 1),
2127 "pixel 562, 358 has color %08x, expected 0x00000000\n", color
);
2128 color
= getPixelColor(device
, 558, 362);
2129 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
2130 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color
);
2131 color
= getPixelColor(device
, 562, 362);
2132 ok(color_match(color
, 0x00000000, 1),
2133 "pixel 562, 362 has color %08x, expected 0x00000000\n", color
);
2136 color
= getPixelColor(device
, 558, 118);
2137 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
2138 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color
);
2139 color
= getPixelColor(device
, 562, 118);
2140 ok(color_match(color
, 0x00000000, 1),
2141 "pixel 562, 118 has color %08x, expected 0x00000000\n", color
);
2142 color
= getPixelColor(device
, 558, 122);
2143 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
2144 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color
);
2145 color
= getPixelColor(device
, 562, 122);
2146 ok(color_match(color
, 0x00000000, 1),
2147 "pixel 562, 122 has color %08x, expected 0x00000000\n", color
);
2149 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2150 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
2152 IDirect3DDevice8_DeletePixelShader(device
, shader_14_coissue_2
);
2153 IDirect3DDevice8_DeletePixelShader(device
, shader_13_coissue_2
);
2154 IDirect3DDevice8_DeletePixelShader(device
, shader_12_coissue_2
);
2155 IDirect3DDevice8_DeletePixelShader(device
, shader_11_coissue_2
);
2156 IDirect3DDevice8_DeletePixelShader(device
, shader_14_coissue
);
2157 IDirect3DDevice8_DeletePixelShader(device
, shader_13_coissue
);
2158 IDirect3DDevice8_DeletePixelShader(device
, shader_12_coissue
);
2159 IDirect3DDevice8_DeletePixelShader(device
, shader_11_coissue
);
2160 IDirect3DDevice8_DeletePixelShader(device
, shader_14
);
2161 IDirect3DDevice8_DeletePixelShader(device
, shader_13
);
2162 IDirect3DDevice8_DeletePixelShader(device
, shader_12
);
2163 IDirect3DDevice8_DeletePixelShader(device
, shader_11
);
2164 refcount
= IDirect3DDevice8_Release(device
);
2165 ok(!refcount
, "Device has %u references left.\n", refcount
);
2167 IDirect3D8_Release(d3d
);
2168 DestroyWindow(window
);
2171 static void z_range_test(void)
2173 IDirect3DDevice8
*device
;
2184 struct vec3 position
;
2189 {{-1.0f
, 0.0f
, 1.1f
}, 0xffff0000},
2190 {{-1.0f
, 1.0f
, 1.1f
}, 0xffff0000},
2191 {{ 1.0f
, 0.0f
, -1.1f
}, 0xffff0000},
2192 {{ 1.0f
, 1.0f
, -1.1f
}, 0xffff0000},
2196 {{-1.0f
, 0.0f
, 1.1f
}, 0xff0000ff},
2197 {{-1.0f
, 1.0f
, 1.1f
}, 0xff0000ff},
2198 {{ 1.0f
, 0.0f
, -1.1f
}, 0xff0000ff},
2199 {{ 1.0f
, 1.0f
, -1.1f
}, 0xff0000ff},
2203 struct vec4 position
;
2208 {{640.0f
, 240.0f
, -1.1f
, 1.0f
}, 0xffffff00},
2209 {{640.0f
, 480.0f
, -1.1f
, 1.0f
}, 0xffffff00},
2210 {{ 0.0f
, 240.0f
, 1.1f
, 1.0f
}, 0xffffff00},
2211 {{ 0.0f
, 480.0f
, 1.1f
, 1.0f
}, 0xffffff00},
2215 {{640.0f
, 240.0f
, -1.1f
, 1.0f
}, 0xff00ff00},
2216 {{640.0f
, 480.0f
, -1.1f
, 1.0f
}, 0xff00ff00},
2217 {{ 0.0f
, 240.0f
, 1.1f
, 1.0f
}, 0xff00ff00},
2218 {{ 0.0f
, 480.0f
, 1.1f
, 1.0f
}, 0xff00ff00},
2220 static const DWORD shader_code
[] =
2222 0xfffe0101, /* vs_1_1 */
2223 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2224 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2225 0x0000ffff /* end */
2227 static const float color_const_1
[] = {1.0f
, 0.0f
, 0.0f
, 1.0f
};
2228 static const float color_const_2
[] = {0.0f
, 0.0f
, 1.0f
, 1.0f
};
2229 static const DWORD vertex_declaration
[] =
2232 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
2236 window
= create_window();
2237 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2238 ok(!!d3d
, "Failed to create a D3D object.\n");
2239 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2241 skip("Failed to create a D3D device, skipping tests.\n");
2245 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2246 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
2248 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2249 * then call Present. Then clear the color buffer to make sure it has some defined content
2250 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2251 * by the depth value. */
2252 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.75f
, 0);
2253 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2254 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2255 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
2256 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
2257 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2259 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2260 ok(SUCCEEDED(hr
), "Failed to disabled lighting, hr %#x.\n", hr
);
2261 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
2262 ok(SUCCEEDED(hr
), "Failed to enable clipping, hr %#x.\n", hr
);
2263 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
2264 ok(SUCCEEDED(hr
), "Failed to enable z test, hr %#x.\n", hr
);
2265 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
2266 ok(SUCCEEDED(hr
), "Failed to disable z writes, hr %#x.\n", hr
);
2267 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_GREATER
);
2268 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
2269 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2270 ok(SUCCEEDED(hr
), "Failed set FVF, hr %#x.\n", hr
);
2272 hr
= IDirect3DDevice8_BeginScene(device
);
2273 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2275 /* Test the untransformed vertex path */
2276 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2277 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2278 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESS
);
2279 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
2280 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2281 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2283 /* Test the transformed vertex path */
2284 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
2285 ok(SUCCEEDED(hr
), "Failed set FVF, hr %#x.\n", hr
);
2287 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(quad4
[0]));
2288 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2289 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_GREATER
);
2290 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
2291 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(quad3
[0]));
2292 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2294 hr
= IDirect3DDevice8_EndScene(device
);
2295 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2297 /* Do not test the exact corner pixels, but go pretty close to them */
2299 /* Clipped because z > 1.0 */
2300 color
= getPixelColor(device
, 28, 238);
2301 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2302 color
= getPixelColor(device
, 28, 241);
2303 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
2304 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2306 ok(color_match(color
, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
2308 /* Not clipped, > z buffer clear value(0.75).
2310 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2311 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2312 * equal to a stored depth buffer value of 0.5. */
2313 color
= getPixelColor(device
, 31, 238);
2314 ok(color_match(color
, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2315 color
= getPixelColor(device
, 31, 241);
2316 ok(color_match(color
, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
2317 color
= getPixelColor(device
, 100, 238);
2318 ok(color_match(color
, 0x00ff0000, 0) || broken(color_match(color
, 0x00ffffff, 0)),
2319 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2320 color
= getPixelColor(device
, 100, 241);
2321 ok(color_match(color
, 0x00ffff00, 0) || broken(color_match(color
, 0x00ffffff, 0)),
2322 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
2324 /* Not clipped, < z buffer clear value */
2325 color
= getPixelColor(device
, 104, 238);
2326 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
2327 color
= getPixelColor(device
, 104, 241);
2328 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color
);
2329 color
= getPixelColor(device
, 318, 238);
2330 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
2331 color
= getPixelColor(device
, 318, 241);
2332 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color
);
2334 /* Clipped because z < 0.0 */
2335 color
= getPixelColor(device
, 321, 238);
2336 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2337 color
= getPixelColor(device
, 321, 241);
2338 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
2339 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2341 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2343 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2344 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
2346 /* Test the shader path */
2347 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
2349 skip("Vertex shaders not supported\n");
2350 IDirect3DDevice8_Release(device
);
2353 hr
= IDirect3DDevice8_CreateVertexShader(device
, vertex_declaration
, shader_code
, &shader
, 0);
2354 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
2356 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
2357 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2359 hr
= IDirect3DDevice8_SetVertexShader(device
, shader
);
2360 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2362 hr
= IDirect3DDevice8_BeginScene(device
);
2363 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2365 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, color_const_1
, 1);
2366 ok(SUCCEEDED(hr
), "Failed to set vs constant 0, hr %#x.\n", hr
);
2367 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2368 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2370 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESS
);
2371 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
2372 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, color_const_2
, 1);
2373 ok(SUCCEEDED(hr
), "Failed to set vs constant 0, hr %#x.\n", hr
);
2374 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2375 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2377 hr
= IDirect3DDevice8_EndScene(device
);
2378 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2380 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
2381 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2383 hr
= IDirect3DDevice8_DeleteVertexShader(device
, shader
);
2384 ok(SUCCEEDED(hr
), "Failed to delete vertex shader, hr %#x.\n", hr
);
2387 color
= getPixelColor(device
, 28, 238);
2388 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2390 /* 1.0 < z < 0.75 */
2391 color
= getPixelColor(device
, 31, 238);
2392 ok(color_match(color
, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2393 color
= getPixelColor(device
, 100, 238);
2394 ok(color_match(color
, 0x00ff0000, 0) || broken(color_match(color
, 0x00ffffff, 0)),
2395 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2397 /* 0.75 < z < 0.0 */
2398 color
= getPixelColor(device
, 104, 238);
2399 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
2400 color
= getPixelColor(device
, 318, 238);
2401 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
2404 color
= getPixelColor(device
, 321, 238);
2405 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2407 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2408 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
2410 refcount
= IDirect3DDevice8_Release(device
);
2411 ok(!refcount
, "Device has %u references left.\n", refcount
);
2413 IDirect3D8_Release(d3d
);
2414 DestroyWindow(window
);
2417 static void test_scalar_instructions(void)
2419 IDirect3DDevice8
*device
;
2429 static const struct vec3 quad
[] =
2431 {-1.0f
, -1.0f
, 0.0f
},
2432 {-1.0f
, 1.0f
, 0.0f
},
2433 { 1.0f
, -1.0f
, 0.0f
},
2434 { 1.0f
, 1.0f
, 0.0f
},
2436 static const DWORD decl
[] =
2439 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* dcl_position v0 */
2440 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2443 static const DWORD rcp_test
[] =
2445 0xfffe0101, /* vs_1_1 */
2446 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2447 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2448 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2449 0x00303030, /* enough to make Windows happy. */
2450 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2451 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2452 0x0000ffff /* END */
2454 static const DWORD rsq_test
[] =
2456 0xfffe0101, /* vs_1_1 */
2457 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2458 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2459 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2460 0x00303030, /* enough to make Windows happy. */
2461 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2462 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2463 0x0000ffff /* END */
2465 static const DWORD exp_test
[] =
2467 0xfffe0101, /* vs_1_1 */
2468 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2469 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2470 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2471 0x00303030, /* enough to make Windows happy. */
2472 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2473 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2474 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2475 0x0000ffff, /* END */
2477 static const DWORD expp_test
[] =
2479 0xfffe0101, /* vs_1_1 */
2480 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2481 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2482 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2483 0x00303030, /* enough to make Windows happy. */
2484 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2485 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2486 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2487 0x0000ffff, /* END */
2489 static const DWORD log_test
[] =
2491 0xfffe0101, /* vs_1_1 */
2492 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2493 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2494 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2495 0x00303030, /* enough to make Windows happy. */
2496 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2497 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2498 0x0000ffff, /* END */
2500 static const DWORD logp_test
[] =
2502 0xfffe0101, /* vs_1_1 */
2503 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2504 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2505 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2506 0x00303030, /* enough to make Windows happy. */
2507 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2508 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2509 0x0000ffff, /* END */
2514 const DWORD
*byte_code
;
2516 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2517 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2518 D3DCOLOR broken_color
;
2522 {"rcp_test", rcp_test
, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2523 {"rsq_test", rsq_test
, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2524 {"exp_test", exp_test
, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2525 {"expp_test", expp_test
, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2526 {"log_test", log_test
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2527 {"logp_test", logp_test
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2530 window
= create_window();
2531 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2532 ok(!!d3d
, "Failed to create a D3D object.\n");
2533 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2535 skip("Failed to create a D3D device, skipping tests.\n");
2539 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2540 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
2541 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
2543 skip("No vs_1_1 support, skipping tests.\n");
2544 IDirect3DDevice8_Release(device
);
2548 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
2550 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff336699, 0.0f
, 0);
2551 ok(SUCCEEDED(hr
), "%s: Failed to clear, hr %#x.\n", test_data
[i
].name
, hr
);
2553 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, test_data
[i
].byte_code
, &shader
, 0);
2554 ok(SUCCEEDED(hr
), "%s: Failed to create vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
2555 hr
= IDirect3DDevice8_SetVertexShader(device
, shader
);
2556 ok(SUCCEEDED(hr
), "%s: Failed to set vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
2558 hr
= IDirect3DDevice8_BeginScene(device
);
2559 ok(SUCCEEDED(hr
), "%s: Failed to begin scene, hr %#x.\n", test_data
[i
].name
, hr
);
2560 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], 3 * sizeof(float));
2561 ok(SUCCEEDED(hr
), "%s: Failed to draw primitive, hr %#x.\n", test_data
[i
].name
, hr
);
2562 hr
= IDirect3DDevice8_EndScene(device
);
2563 ok(SUCCEEDED(hr
), "%s: Failed to end scene, hr %#x.\n", test_data
[i
].name
, hr
);
2565 color
= getPixelColor(device
, 320, 240);
2566 ok(color_match(color
, test_data
[i
].color
, 4) || broken(color_match(color
, test_data
[i
].broken_color
, 4)),
2567 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2568 test_data
[i
].name
, color
, test_data
[i
].color
);
2570 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2571 ok(SUCCEEDED(hr
), "%s: Failed to present, hr %#x.\n", test_data
[i
].name
, hr
);
2573 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
2574 ok(SUCCEEDED(hr
), "%s: Failed to set vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
2575 hr
= IDirect3DDevice8_DeleteVertexShader(device
, shader
);
2576 ok(SUCCEEDED(hr
), "%s: Failed to delete vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
2579 refcount
= IDirect3DDevice8_Release(device
);
2580 ok(!refcount
, "Device has %u references left.\n", refcount
);
2582 IDirect3D8_Release(d3d
);
2583 DestroyWindow(window
);
2586 static void offscreen_test(void)
2588 IDirect3DSurface8
*backbuffer
, *offscreen
, *depthstencil
;
2589 IDirect3DTexture8
*offscreenTexture
;
2590 IDirect3DDevice8
*device
;
2597 static const float quad
[][5] =
2599 {-0.5f
, -0.5f
, 0.1f
, 0.0f
, 0.0f
},
2600 {-0.5f
, 0.5f
, 0.1f
, 0.0f
, 1.0f
},
2601 { 0.5f
, -0.5f
, 0.1f
, 1.0f
, 0.0f
},
2602 { 0.5f
, 0.5f
, 0.1f
, 1.0f
, 1.0f
},
2605 window
= create_window();
2606 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2607 ok(!!d3d
, "Failed to create a D3D object.\n");
2608 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2610 skip("Failed to create a D3D device, skipping tests.\n");
2614 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
2615 ok(hr
== D3D_OK
, "Clear failed, hr = %#08x\n", hr
);
2617 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2618 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2619 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
, "Creating the offscreen render target failed, hr = %#08x\n", hr
);
2620 if (!offscreenTexture
)
2622 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2623 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2624 D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2625 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
, "Creating the offscreen render target failed, hr = %#08x\n", hr
);
2626 if (!offscreenTexture
)
2628 skip("Cannot create an offscreen render target.\n");
2629 IDirect3DDevice8_Release(device
);
2634 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
2635 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr
);
2637 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2638 ok(hr
== D3D_OK
, "Can't get back buffer, hr = %#08x\n", hr
);
2640 hr
= IDirect3DTexture8_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
2641 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %#08x\n", hr
);
2643 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2644 ok(hr
== D3D_OK
, "SetVertexShader failed, hr = %#08x\n", hr
);
2646 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
2647 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2648 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2649 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2650 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_NONE
);
2651 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr
);
2652 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_NONE
);
2653 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr
);
2654 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2655 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %08x\n", hr
);
2657 hr
= IDirect3DDevice8_BeginScene(device
);
2658 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2660 hr
= IDirect3DDevice8_SetRenderTarget(device
, offscreen
, depthstencil
);
2661 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2662 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 1.0f
, 0);
2663 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2665 /* Draw without textures - Should result in a white quad. */
2666 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2667 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2669 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
2670 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2671 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)offscreenTexture
);
2672 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2674 /* This time with the texture .*/
2675 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2676 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2678 hr
= IDirect3DDevice8_EndScene(device
);
2679 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2681 /* Center quad - should be white */
2682 color
= getPixelColor(device
, 320, 240);
2683 ok(color
== 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2684 /* Some quad in the cleared part of the texture */
2685 color
= getPixelColor(device
, 170, 240);
2686 ok(color
== 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color
);
2687 /* Part of the originally cleared back buffer */
2688 color
= getPixelColor(device
, 10, 10);
2689 ok(color
== 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2690 color
= getPixelColor(device
, 10, 470);
2691 ok(color
== 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2693 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2695 IDirect3DSurface8_Release(backbuffer
);
2696 IDirect3DTexture8_Release(offscreenTexture
);
2697 IDirect3DSurface8_Release(offscreen
);
2698 IDirect3DSurface8_Release(depthstencil
);
2699 refcount
= IDirect3DDevice8_Release(device
);
2700 ok(!refcount
, "Device has %u references left.\n", refcount
);
2702 IDirect3D8_Release(d3d
);
2703 DestroyWindow(window
);
2706 static void test_blend(void)
2708 IDirect3DSurface8
*backbuffer
, *offscreen
, *depthstencil
;
2709 IDirect3DTexture8
*offscreenTexture
;
2710 IDirect3DDevice8
*device
;
2719 struct vec3 position
;
2724 {{-1.0f
, -1.0f
, 0.1f
}, 0x4000ff00},
2725 {{-1.0f
, 0.0f
, 0.1f
}, 0x4000ff00},
2726 {{ 1.0f
, -1.0f
, 0.1f
}, 0x4000ff00},
2727 {{ 1.0f
, 0.0f
, 0.1f
}, 0x4000ff00},
2731 {{-1.0f
, 0.0f
, 0.1f
}, 0xc00000ff},
2732 {{-1.0f
, 1.0f
, 0.1f
}, 0xc00000ff},
2733 {{ 1.0f
, 0.0f
, 0.1f
}, 0xc00000ff},
2734 {{ 1.0f
, 1.0f
, 0.1f
}, 0xc00000ff},
2736 static const float composite_quad
[][5] =
2738 { 0.0f
, -1.0f
, 0.1f
, 0.0f
, 1.0f
},
2739 { 0.0f
, 1.0f
, 0.1f
, 0.0f
, 0.0f
},
2740 { 1.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
},
2741 { 1.0f
, 1.0f
, 0.1f
, 1.0f
, 0.0f
},
2744 window
= create_window();
2745 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2746 ok(!!d3d
, "Failed to create a D3D object.\n");
2747 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2749 skip("Failed to create a D3D device, skipping tests.\n");
2753 /* Clear the render target with alpha = 0.5 */
2754 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x80ff0000, 1.0f
, 0);
2755 ok(hr
== D3D_OK
, "Clear failed, hr = %08x\n", hr
);
2757 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2758 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2759 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2761 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
2762 ok(SUCCEEDED(hr
), "Failed to get depth/stencil buffer, hr %#x.\n", hr
);
2763 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2764 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
2766 hr
= IDirect3DTexture8_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
2767 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %#08x\n", hr
);
2769 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2770 ok(hr
== D3D_OK
, "SetVertexShader failed, hr = %#08x\n", hr
);
2772 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
2773 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2774 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2775 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2776 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_NONE
);
2777 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr
);
2778 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_NONE
);
2779 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr
);
2780 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2781 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %08x\n", hr
);
2783 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2784 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2785 hr
= IDirect3DDevice8_BeginScene(device
);
2786 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2788 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2789 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2790 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2791 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2792 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2793 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
2794 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2796 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_DESTALPHA
);
2797 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2798 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVDESTALPHA
);
2799 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2800 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2801 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2803 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2804 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2805 * "don't work" on render targets without alpha channel, they give
2806 * essentially ZERO and ONE blend factors. */
2807 hr
= IDirect3DDevice8_SetRenderTarget(device
, offscreen
, 0);
2808 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2809 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x80ff0000, 0.0, 0);
2810 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2812 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2813 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2814 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2815 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2816 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
2817 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2819 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_DESTALPHA
);
2820 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2821 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVDESTALPHA
);
2822 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2823 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2824 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2826 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
2827 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2829 /* Render the offscreen texture onto the frame buffer to be able to
2830 * compare it regularly. Disable alpha blending for the final
2832 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, FALSE
);
2833 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2834 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2835 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2837 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) offscreenTexture
);
2838 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2839 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, composite_quad
, sizeof(float) * 5);
2840 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2842 hr
= IDirect3DDevice8_EndScene(device
);
2843 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2845 color
= getPixelColor(device
, 160, 360);
2846 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2847 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color
);
2849 color
= getPixelColor(device
, 160, 120);
2850 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2851 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color
);
2853 color
= getPixelColor(device
, 480, 360);
2854 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2855 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color
);
2857 color
= getPixelColor(device
, 480, 120);
2858 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2859 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color
);
2861 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2863 IDirect3DSurface8_Release(backbuffer
);
2864 IDirect3DTexture8_Release(offscreenTexture
);
2865 IDirect3DSurface8_Release(offscreen
);
2866 IDirect3DSurface8_Release(depthstencil
);
2867 refcount
= IDirect3DDevice8_Release(device
);
2868 ok(!refcount
, "Device has %u references left.\n", refcount
);
2870 IDirect3D8_Release(d3d
);
2871 DestroyWindow(window
);
2874 static void p8_texture_test(void)
2876 IDirect3DTexture8
*texture
, *texture2
;
2877 IDirect3DDevice8
*device
;
2878 PALETTEENTRY table
[256];
2879 unsigned char *data
;
2889 static const float quad
[] =
2891 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
,
2892 -1.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
,
2893 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
,
2894 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
,
2896 static const float quad2
[] =
2898 -1.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
,
2899 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
,
2900 1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
,
2901 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
,
2904 window
= create_window();
2905 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2906 ok(!!d3d
, "Failed to create a D3D object.\n");
2907 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2909 skip("Failed to create a D3D device, skipping tests.\n");
2913 if (IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
,
2914 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, D3DFMT_P8
) != D3D_OK
)
2916 skip("D3DFMT_P8 textures not supported.\n");
2917 IDirect3DDevice8_Release(device
);
2921 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_P8
, D3DPOOL_MANAGED
, &texture2
);
2922 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2923 memset(&lr
, 0, sizeof(lr
));
2924 hr
= IDirect3DTexture8_LockRect(texture2
, 0, &lr
, NULL
, 0);
2925 ok(hr
== D3D_OK
, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr
);
2928 hr
= IDirect3DTexture8_UnlockRect(texture2
, 0);
2929 ok(hr
== D3D_OK
, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr
);
2931 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_P8
, D3DPOOL_MANAGED
, &texture
);
2932 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2933 memset(&lr
, 0, sizeof(lr
));
2934 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lr
, NULL
, 0);
2935 ok(hr
== D3D_OK
, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr
);
2938 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
2939 ok(hr
== D3D_OK
, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr
);
2941 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000, 1.0f
, 0);
2942 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2944 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2945 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2946 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2947 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2949 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2950 alpha of every entry is set to 1.0, which MS says is required when there's no
2951 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2952 for (i
= 0; i
< 256; i
++) {
2953 table
[i
].peRed
= table
[i
].peGreen
= table
[i
].peBlue
= 0;
2954 table
[i
].peFlags
= 0xff;
2956 table
[1].peRed
= 0xff;
2957 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, table
);
2958 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2961 table
[1].peBlue
= 0xff;
2962 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 1, table
);
2963 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2965 hr
= IDirect3DDevice8_BeginScene(device
);
2966 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2968 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2969 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2970 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2971 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2972 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2973 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2974 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 0);
2975 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2976 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture2
);
2977 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2978 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2979 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2981 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
2982 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2983 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2984 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2986 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 1);
2987 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2988 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 5 * sizeof(float));
2989 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2991 hr
= IDirect3DDevice8_EndScene(device
);
2992 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2994 color
= getPixelColor(device
, 32, 32);
2995 ok(color_match(color
, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color
);
2996 color
= getPixelColor(device
, 32, 320);
2997 ok(color_match(color
, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color
);
2999 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3000 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
3002 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 0.0, 0);
3003 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
3005 hr
= IDirect3DDevice8_BeginScene(device
);
3006 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3007 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture2
);
3008 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
3009 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
3010 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3011 hr
= IDirect3DDevice8_EndScene(device
);
3012 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3014 color
= getPixelColor(device
, 32, 32);
3015 ok(color_match(color
, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color
);
3017 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3018 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
3020 /* Test palettes with alpha */
3021 IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3022 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_ALPHAPALETTE
)) {
3023 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
3025 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 0.0, 0);
3026 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
3028 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
3029 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
3031 for (i
= 0; i
< 256; i
++) {
3032 table
[i
].peRed
= table
[i
].peGreen
= table
[i
].peBlue
= 0;
3033 table
[i
].peFlags
= 0xff;
3035 table
[1].peRed
= 0xff;
3036 table
[1].peFlags
= 0x80;
3037 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, table
);
3038 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
3041 table
[1].peBlue
= 0xff;
3042 table
[1].peFlags
= 0x80;
3043 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 1, table
);
3044 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
3046 hr
= IDirect3DDevice8_BeginScene(device
);
3047 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3049 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
3050 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
3051 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
3052 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
3053 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
3054 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
3056 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 0);
3057 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
3058 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
3059 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3061 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 1);
3062 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
3063 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 5 * sizeof(float));
3064 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3066 hr
= IDirect3DDevice8_EndScene(device
);
3067 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3069 color
= getPixelColor(device
, 32, 32);
3070 ok(color_match(color
, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color
);
3071 color
= getPixelColor(device
, 32, 320);
3072 ok(color_match(color
, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color
);
3074 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3075 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
3078 IDirect3DTexture8_Release(texture
);
3079 IDirect3DTexture8_Release(texture2
);
3080 refcount
= IDirect3DDevice8_Release(device
);
3081 ok(!refcount
, "Device has %u references left.\n", refcount
);
3083 IDirect3D8_Release(d3d
);
3084 DestroyWindow(window
);
3087 static void texop_test(void)
3089 IDirect3DTexture8
*texture
;
3090 D3DLOCKED_RECT locked_rect
;
3091 IDirect3DDevice8
*device
;
3100 static const struct {
3105 {-1.0f
, -1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f
, -1.0f
},
3106 {-1.0f
, 1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f
, 1.0f
},
3107 { 1.0f
, -1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f
, -1.0f
},
3108 { 1.0f
, 1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f
, 1.0f
}
3111 static const struct {
3117 {D3DTOP_SELECTARG1
, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3118 {D3DTOP_SELECTARG2
, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2
, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
3119 {D3DTOP_MODULATE
, "MODULATE", D3DTEXOPCAPS_MODULATE
, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
3120 {D3DTOP_MODULATE2X
, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X
, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
3121 {D3DTOP_MODULATE4X
, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X
, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3122 {D3DTOP_ADD
, "ADD", D3DTEXOPCAPS_ADD
, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3124 {D3DTOP_ADDSIGNED
, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED
, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
3125 {D3DTOP_ADDSIGNED2X
, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3127 {D3DTOP_SUBTRACT
, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT
, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3128 {D3DTOP_ADDSMOOTH
, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH
, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3129 {D3DTOP_BLENDDIFFUSEALPHA
, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA
, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3130 {D3DTOP_BLENDTEXTUREALPHA
, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA
, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
3131 {D3DTOP_BLENDFACTORALPHA
, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA
, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
3132 {D3DTOP_BLENDTEXTUREALPHAPM
, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3133 {D3DTOP_BLENDCURRENTALPHA
, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA
, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3134 {D3DTOP_MODULATEALPHA_ADDCOLOR
, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
3135 {D3DTOP_MODULATECOLOR_ADDALPHA
, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
3136 {D3DTOP_MODULATEINVALPHA_ADDCOLOR
, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3137 {D3DTOP_MODULATEINVCOLOR_ADDALPHA
, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
3138 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
3139 {D3DTOP_DOTPRODUCT3
, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3
, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
3140 {D3DTOP_MULTIPLYADD
, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD
, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
3141 {D3DTOP_LERP
, "LERP", D3DTEXOPCAPS_LERP
, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
3144 window
= create_window();
3145 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3146 ok(!!d3d
, "Failed to create a D3D object.\n");
3147 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3149 skip("Failed to create a D3D device, skipping tests.\n");
3153 memset(&caps
, 0, sizeof(caps
));
3154 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3155 ok(SUCCEEDED(hr
), "GetDeviceCaps failed with 0x%08x\n", hr
);
3157 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_TEX0
);
3158 ok(SUCCEEDED(hr
), "SetVertexShader failed with 0x%08x\n", hr
);
3160 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
3161 ok(SUCCEEDED(hr
), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr
);
3162 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, NULL
, 0);
3163 ok(SUCCEEDED(hr
), "LockRect failed with 0x%08x\n", hr
);
3164 *((DWORD
*)locked_rect
.pBits
) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3165 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
3166 ok(SUCCEEDED(hr
), "LockRect failed with 0x%08x\n", hr
);
3167 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3168 ok(SUCCEEDED(hr
), "SetTexture failed with 0x%08x\n", hr
);
3170 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG0
, D3DTA_DIFFUSE
);
3171 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
3172 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
3173 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
3174 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
3175 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
3177 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
3178 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
3180 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3181 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
3182 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_TEXTUREFACTOR
, 0xdd333333);
3183 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
3184 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
| D3DCOLORWRITEENABLE_ALPHA
);
3185 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
3187 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00000000, 1.0f
, 0);
3188 ok(SUCCEEDED(hr
), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr
);
3190 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
3192 if (!(caps
.TextureOpCaps
& test_data
[i
].caps_flag
))
3194 skip("tex operation %s not supported\n", test_data
[i
].name
);
3198 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, test_data
[i
].op
);
3199 ok(SUCCEEDED(hr
), "SetTextureStageState (%s) failed with 0x%08x\n", test_data
[i
].name
, hr
);
3201 hr
= IDirect3DDevice8_BeginScene(device
);
3202 ok(SUCCEEDED(hr
), "BeginScene failed with 0x%08x\n", hr
);
3204 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3205 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed with 0x%08x\n", hr
);
3207 hr
= IDirect3DDevice8_EndScene(device
);
3208 ok(SUCCEEDED(hr
), "EndScene failed with 0x%08x\n", hr
);
3210 color
= getPixelColor(device
, 320, 240);
3211 ok(color_match(color
, test_data
[i
].result
, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3212 test_data
[i
].name
, color
, test_data
[i
].result
);
3214 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3215 ok(SUCCEEDED(hr
), "Present failed with 0x%08x\n", hr
);
3217 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00000000, 1.0f
, 0);
3218 ok(SUCCEEDED(hr
), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr
);
3221 IDirect3DTexture8_Release(texture
);
3222 refcount
= IDirect3DDevice8_Release(device
);
3223 ok(!refcount
, "Device has %u references left.\n", refcount
);
3225 IDirect3D8_Release(d3d
);
3226 DestroyWindow(window
);
3229 /* This test tests depth clamping / clipping behaviour:
3230 * - With software vertex processing, depth values are clamped to the
3231 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3232 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3233 * same as regular vertices here.
3234 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3235 * Normal vertices are always clipped. Pretransformed vertices are
3236 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3237 * - The viewport's MinZ/MaxZ is irrelevant for this.
3239 static void depth_clamp_test(void)
3241 IDirect3DDevice8
*device
;
3252 struct vec4 position
;
3257 {{ 0.0f
, 0.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
3258 {{640.0f
, 0.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
3259 {{ 0.0f
, 480.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
3260 {{640.0f
, 480.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
3264 {{ 0.0f
, 300.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
3265 {{640.0f
, 300.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
3266 {{ 0.0f
, 360.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
3267 {{640.0f
, 360.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
3271 {{112.0f
, 108.0f
, 5.0f
, 1.0f
}, 0xffffffff},
3272 {{208.0f
, 108.0f
, 5.0f
, 1.0f
}, 0xffffffff},
3273 {{112.0f
, 204.0f
, 5.0f
, 1.0f
}, 0xffffffff},
3274 {{208.0f
, 204.0f
, 5.0f
, 1.0f
}, 0xffffffff},
3278 {{ 42.0f
, 41.0f
, 10.0f
, 1.0f
}, 0xffffffff},
3279 {{112.0f
, 41.0f
, 10.0f
, 1.0f
}, 0xffffffff},
3280 {{ 42.0f
, 108.0f
, 10.0f
, 1.0f
}, 0xffffffff},
3281 {{112.0f
, 108.0f
, 10.0f
, 1.0f
}, 0xffffffff},
3285 struct vec3 position
;
3290 {{-0.5f
, 0.5f
, 10.0f
}, 0xff14f914},
3291 {{ 0.5f
, 0.5f
, 10.0f
}, 0xff14f914},
3292 {{-0.5f
, -0.5f
, 10.0f
}, 0xff14f914},
3293 {{ 0.5f
, -0.5f
, 10.0f
}, 0xff14f914},
3297 {{-1.0f
, 0.5f
, 10.0f
}, 0xfff91414},
3298 {{ 1.0f
, 0.5f
, 10.0f
}, 0xfff91414},
3299 {{-1.0f
, 0.25f
, 10.0f
}, 0xfff91414},
3300 {{ 1.0f
, 0.25f
, 10.0f
}, 0xfff91414},
3303 window
= create_window();
3304 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3305 ok(!!d3d
, "Failed to create a D3D object.\n");
3306 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3308 skip("Failed to create a D3D device, skipping tests.\n");
3312 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3313 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
3322 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
3323 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
3325 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0, 0);
3326 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3328 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
3329 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3330 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3331 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3332 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3333 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3334 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
3335 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3337 hr
= IDirect3DDevice8_BeginScene(device
);
3338 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3340 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
3341 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3343 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(*quad1
));
3344 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3345 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(*quad2
));
3346 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3348 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
3349 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3351 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(*quad3
));
3352 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3353 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(*quad4
));
3354 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3356 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
3357 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3358 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
3359 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3361 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad5
, sizeof(*quad5
));
3362 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3364 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
3365 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3367 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad6
, sizeof(*quad6
));
3368 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3370 hr
= IDirect3DDevice8_EndScene(device
);
3371 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3373 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
3375 color
= getPixelColor(device
, 75, 75);
3376 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
3377 color
= getPixelColor(device
, 150, 150);
3378 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
3379 color
= getPixelColor(device
, 320, 240);
3380 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
3381 color
= getPixelColor(device
, 320, 330);
3382 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
3383 color
= getPixelColor(device
, 320, 330);
3384 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
3388 color
= getPixelColor(device
, 75, 75);
3389 ok(color_match(color
, 0x00ffffff, 1), "color 0x%08x.\n", color
);
3390 color
= getPixelColor(device
, 150, 150);
3391 ok(color_match(color
, 0x00ffffff, 1), "color 0x%08x.\n", color
);
3392 color
= getPixelColor(device
, 320, 240);
3393 ok(color_match(color
, 0x00002b7f, 1), "color 0x%08x.\n", color
);
3394 color
= getPixelColor(device
, 320, 330);
3395 ok(color_match(color
, 0x00f9e814, 1), "color 0x%08x.\n", color
);
3396 color
= getPixelColor(device
, 320, 330);
3397 ok(color_match(color
, 0x00f9e814, 1), "color 0x%08x.\n", color
);
3400 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3401 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3403 refcount
= IDirect3DDevice8_Release(device
);
3404 ok(!refcount
, "Device has %u references left.\n", refcount
);
3406 IDirect3D8_Release(d3d
);
3407 DestroyWindow(window
);
3410 static void depth_buffer_test(void)
3412 IDirect3DSurface8
*backbuffer
, *rt1
, *rt2
, *rt3
;
3413 IDirect3DSurface8
*depth_stencil
;
3414 IDirect3DDevice8
*device
;
3425 struct vec3 position
;
3430 {{-1.0f
, 1.0f
, 0.33f
}, 0xff00ff00},
3431 {{ 1.0f
, 1.0f
, 0.33f
}, 0xff00ff00},
3432 {{-1.0f
, -1.0f
, 0.33f
}, 0xff00ff00},
3433 {{ 1.0f
, -1.0f
, 0.33f
}, 0xff00ff00},
3437 {{-1.0f
, 1.0f
, 0.50f
}, 0xffff00ff},
3438 {{ 1.0f
, 1.0f
, 0.50f
}, 0xffff00ff},
3439 {{-1.0f
, -1.0f
, 0.50f
}, 0xffff00ff},
3440 {{ 1.0f
, -1.0f
, 0.50f
}, 0xffff00ff},
3444 {{-1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
3445 {{ 1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
3446 {{-1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3447 {{ 1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3449 static const DWORD expected_colors
[4][4] =
3451 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3452 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3453 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3454 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3457 window
= create_window();
3458 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3459 ok(!!d3d
, "Failed to create a D3D object.\n");
3460 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3462 skip("Failed to create a D3D device, skipping tests.\n");
3473 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
3474 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
3476 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3477 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3478 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3479 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3480 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3481 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3482 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
3483 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3484 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
3485 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3487 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
3488 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
3489 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
3490 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3491 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 320, 240, D3DFMT_A8R8G8B8
,
3492 D3DMULTISAMPLE_NONE
, FALSE
, &rt1
);
3493 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3494 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 480, 360, D3DFMT_A8R8G8B8
,
3495 D3DMULTISAMPLE_NONE
, FALSE
, &rt2
);
3496 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3497 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3498 D3DMULTISAMPLE_NONE
, FALSE
, &rt3
);
3499 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3501 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt3
, depth_stencil
);
3502 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3503 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 0.0f
, 0);
3504 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3506 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3507 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3508 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
3509 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3511 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt1
, depth_stencil
);
3512 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3513 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.0f
, 0);
3514 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3516 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt2
, depth_stencil
);
3517 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3518 hr
= IDirect3DDevice8_BeginScene(device
);
3519 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3520 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(*quad2
));
3521 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3522 hr
= IDirect3DDevice8_EndScene(device
);
3523 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3525 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3526 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3528 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
3529 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3531 hr
= IDirect3DDevice8_BeginScene(device
);
3532 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3533 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(*quad1
));
3534 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3535 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(*quad3
));
3536 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3537 hr
= IDirect3DDevice8_EndScene(device
);
3538 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3540 for (i
= 0; i
< 4; ++i
)
3542 for (j
= 0; j
< 4; ++j
)
3544 unsigned int x
= 80 * ((2 * j
) + 1);
3545 unsigned int y
= 60 * ((2 * i
) + 1);
3546 color
= getPixelColor(device
, x
, y
);
3547 ok(color_match(color
, expected_colors
[i
][j
], 0),
3548 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
3552 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3553 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3555 IDirect3DSurface8_Release(depth_stencil
);
3556 IDirect3DSurface8_Release(backbuffer
);
3557 IDirect3DSurface8_Release(rt3
);
3558 IDirect3DSurface8_Release(rt2
);
3559 IDirect3DSurface8_Release(rt1
);
3560 refcount
= IDirect3DDevice8_Release(device
);
3561 ok(!refcount
, "Device has %u references left.\n", refcount
);
3563 IDirect3D8_Release(d3d
);
3564 DestroyWindow(window
);
3567 /* Test that partial depth copies work the way they're supposed to. The clear
3568 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3569 * the following draw should only copy back the part that was modified. */
3570 static void depth_buffer2_test(void)
3572 IDirect3DSurface8
*backbuffer
, *rt1
, *rt2
;
3573 IDirect3DSurface8
*depth_stencil
;
3574 IDirect3DDevice8
*device
;
3585 struct vec3 position
;
3590 {{-1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
3591 {{ 1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
3592 {{-1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3593 {{ 1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3596 window
= create_window();
3597 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3598 ok(!!d3d
, "Failed to create a D3D object.\n");
3599 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3601 skip("Failed to create a D3D device, skipping tests.\n");
3612 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
3613 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
3615 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3616 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3617 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3618 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3619 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3620 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3621 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
3622 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3623 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
3624 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3626 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3627 D3DMULTISAMPLE_NONE
, FALSE
, &rt1
);
3628 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3629 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 480, 360, D3DFMT_A8R8G8B8
,
3630 D3DMULTISAMPLE_NONE
, FALSE
, &rt2
);
3631 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3632 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
3633 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
3634 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
3635 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3637 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt1
, depth_stencil
);
3638 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3639 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
3640 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3642 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3643 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3644 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 0.5f
, 0);
3645 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3647 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt2
, depth_stencil
);
3648 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3649 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.0f
, 0);
3650 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3652 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3653 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3655 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
3656 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3658 hr
= IDirect3DDevice8_BeginScene(device
);
3659 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3660 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3661 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3662 hr
= IDirect3DDevice8_EndScene(device
);
3663 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3665 for (i
= 0; i
< 4; ++i
)
3667 for (j
= 0; j
< 4; ++j
)
3669 unsigned int x
= 80 * ((2 * j
) + 1);
3670 unsigned int y
= 60 * ((2 * i
) + 1);
3671 color
= getPixelColor(device
, x
, y
);
3672 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3673 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x
, y
, color
);
3677 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3678 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3680 IDirect3DSurface8_Release(depth_stencil
);
3681 IDirect3DSurface8_Release(backbuffer
);
3682 IDirect3DSurface8_Release(rt2
);
3683 IDirect3DSurface8_Release(rt1
);
3684 refcount
= IDirect3DDevice8_Release(device
);
3685 ok(!refcount
, "Device has %u references left.\n", refcount
);
3687 IDirect3D8_Release(d3d
);
3688 DestroyWindow(window
);
3691 static void intz_test(void)
3693 IDirect3DSurface8
*original_rt
, *rt
;
3694 struct surface_readback rb
;
3695 IDirect3DTexture8
*texture
;
3696 IDirect3DDevice8
*device
;
3697 IDirect3DSurface8
*ds
;
3706 static const DWORD ps_code
[] =
3708 0xffff0101, /* ps_1_1 */
3709 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3710 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3711 0x00000042, 0xb00f0000, /* tex t0 */
3712 0x00000042, 0xb00f0001, /* tex t1 */
3713 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3714 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3715 0x0000ffff, /* end */
3721 float s1
, t1
, p1
, q1
;
3725 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3726 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3727 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3728 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3732 { -1.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3733 { 1.0f
, 0.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3734 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3735 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3739 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3740 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3741 { -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3742 { 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3751 { 80, 100, 0x20204020},
3752 {240, 100, 0x6060bf60},
3753 {400, 100, 0x9f9f409f},
3754 {560, 100, 0xdfdfbfdf},
3755 { 80, 450, 0x20204020},
3756 {240, 450, 0x6060bf60},
3757 {400, 450, 0x9f9f409f},
3758 {560, 450, 0xdfdfbfdf},
3761 window
= create_window();
3762 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3763 ok(!!d3d
, "Failed to create a D3D object.\n");
3764 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3766 skip("Failed to create a D3D device, skipping tests.\n");
3770 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3771 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3772 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
3774 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3775 IDirect3DDevice8_Release(device
);
3778 if (caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
)
3780 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3781 IDirect3DDevice8_Release(device
);
3785 if (FAILED(hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3786 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, MAKEFOURCC('I','N','T','Z'))))
3788 skip("No INTZ support, skipping INTZ test.\n");
3789 IDirect3DDevice8_Release(device
);
3793 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3794 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3796 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3797 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3798 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3799 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3800 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
3801 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3802 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3803 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3805 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3806 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3807 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3808 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3809 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3810 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3811 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3812 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3813 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3814 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3815 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3817 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3818 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3819 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3820 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3821 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3822 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3823 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3824 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3826 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3827 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3828 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3829 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3830 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3831 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3832 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3833 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3834 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3835 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3836 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3837 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3838 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3840 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3841 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3843 /* Render offscreen, using the INTZ texture as depth buffer */
3844 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3845 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3846 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3847 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3849 /* Setup the depth/stencil surface. */
3850 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3851 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3853 hr
= IDirect3DDevice8_BeginScene(device
);
3854 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3855 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3856 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3857 hr
= IDirect3DDevice8_EndScene(device
);
3858 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3860 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3861 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3862 IDirect3DSurface8_Release(ds
);
3863 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3864 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3865 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3866 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3867 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3868 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3870 /* Read the depth values back. */
3871 hr
= IDirect3DDevice8_BeginScene(device
);
3872 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3873 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3874 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3875 hr
= IDirect3DDevice8_EndScene(device
);
3876 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3878 get_rt_readback(original_rt
, &rb
);
3879 for (i
= 0; i
< ARRAY_SIZE(expected_colors
); ++i
)
3881 D3DCOLOR color
= get_readback_color(&rb
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3882 ok(color_match(color
, expected_colors
[i
].color
, 1),
3883 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3884 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3886 release_surface_readback(&rb
);
3888 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3889 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3891 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3892 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3893 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3894 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3895 IDirect3DTexture8_Release(texture
);
3897 /* Render onscreen while using the INTZ texture as depth buffer */
3898 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3899 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3900 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3901 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3902 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3903 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3904 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3905 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3906 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3908 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3909 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3911 hr
= IDirect3DDevice8_BeginScene(device
);
3912 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3913 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3914 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3915 hr
= IDirect3DDevice8_EndScene(device
);
3916 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3918 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3919 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3920 IDirect3DSurface8_Release(ds
);
3921 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3922 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3923 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3924 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3925 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3926 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3928 /* Read the depth values back. */
3929 hr
= IDirect3DDevice8_BeginScene(device
);
3930 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3931 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3932 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3933 hr
= IDirect3DDevice8_EndScene(device
);
3934 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3936 get_rt_readback(original_rt
, &rb
);
3937 for (i
= 0; i
< ARRAY_SIZE(expected_colors
); ++i
)
3939 D3DCOLOR color
= get_readback_color(&rb
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3940 ok(color_match(color
, expected_colors
[i
].color
, 1),
3941 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3942 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3944 release_surface_readback(&rb
);
3946 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3947 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3949 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3950 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3951 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3952 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3953 IDirect3DTexture8_Release(texture
);
3955 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3956 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3957 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3958 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3959 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3960 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3961 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3962 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3963 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3964 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3966 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3967 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3969 hr
= IDirect3DDevice8_BeginScene(device
);
3970 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3971 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, half_quad_1
, sizeof(*half_quad_1
));
3972 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3973 hr
= IDirect3DDevice8_EndScene(device
);
3974 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3976 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3977 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3979 hr
= IDirect3DDevice8_BeginScene(device
);
3980 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3981 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, half_quad_2
, sizeof(*half_quad_2
));
3982 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3983 hr
= IDirect3DDevice8_EndScene(device
);
3984 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3986 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3987 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3988 IDirect3DSurface8_Release(ds
);
3989 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3990 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3991 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3992 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3993 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3994 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3996 /* Read the depth values back. */
3997 hr
= IDirect3DDevice8_BeginScene(device
);
3998 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3999 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4000 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4001 hr
= IDirect3DDevice8_EndScene(device
);
4002 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4004 get_rt_readback(original_rt
, &rb
);
4005 for (i
= 0; i
< ARRAY_SIZE(expected_colors
); ++i
)
4007 D3DCOLOR color
= get_readback_color(&rb
, expected_colors
[i
].x
, expected_colors
[i
].y
);
4008 ok(color_match(color
, expected_colors
[i
].color
, 1),
4009 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4010 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
4012 release_surface_readback(&rb
);
4014 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4015 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
4017 IDirect3DTexture8_Release(texture
);
4018 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4019 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
4020 IDirect3DSurface8_Release(original_rt
);
4021 IDirect3DSurface8_Release(rt
);
4022 refcount
= IDirect3DDevice8_Release(device
);
4023 ok(!refcount
, "Device has %u references left.\n", refcount
);
4025 IDirect3D8_Release(d3d
);
4026 DestroyWindow(window
);
4029 static void shadow_test(void)
4031 IDirect3DSurface8
*original_rt
, *rt
;
4032 struct surface_readback rb
;
4033 IDirect3DDevice8
*device
;
4042 static const DWORD ps_code
[] =
4044 0xffff0101, /* ps_1_1 */
4045 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
4046 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4047 0x00000042, 0xb00f0000, /* tex t0 */
4048 0x00000042, 0xb00f0001, /* tex t1 */
4049 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
4050 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
4051 0x0000ffff, /* end */
4060 {D3DFMT_D16_LOCKABLE
, "D3DFMT_D16_LOCKABLE"},
4061 {D3DFMT_D32
, "D3DFMT_D32"},
4062 {D3DFMT_D15S1
, "D3DFMT_D15S1"},
4063 {D3DFMT_D24S8
, "D3DFMT_D24S8"},
4064 {D3DFMT_D24X8
, "D3DFMT_D24X8"},
4065 {D3DFMT_D24X4S4
, "D3DFMT_D24X4S4"},
4066 {D3DFMT_D16
, "D3DFMT_D16"},
4072 float s1
, t1
, p1
, q1
;
4076 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
},
4077 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.0f
},
4078 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
},
4079 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
},
4088 {400, 60, 0x00000000},
4089 {560, 180, 0xffff00ff},
4090 {560, 300, 0xffff00ff},
4091 {400, 420, 0xffffffff},
4092 {240, 420, 0xffffffff},
4093 { 80, 300, 0x00000000},
4094 { 80, 180, 0x00000000},
4095 {240, 60, 0x00000000},
4098 window
= create_window();
4099 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4100 ok(!!d3d
, "Failed to create a D3D object.\n");
4101 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4103 skip("Failed to create a D3D device, skipping tests.\n");
4107 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4108 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
4109 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
4111 skip("No pixel shader 1.1 support, skipping shadow test.\n");
4112 IDirect3DDevice8_Release(device
);
4116 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
4117 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
4119 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 1024, 1024, D3DFMT_A8R8G8B8
,
4120 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
4121 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
4122 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
4123 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
4125 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
4126 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4127 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
4128 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
4129 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4130 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
4131 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4132 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
4133 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4134 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
4135 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4137 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
4138 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4139 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
4140 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4141 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4142 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4143 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
4144 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4146 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
4147 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4148 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
4149 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4150 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4151 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4152 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
4153 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4154 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
4155 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4156 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
4157 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
4158 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4160 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
4162 D3DFORMAT format
= formats
[i
].format
;
4163 IDirect3DTexture8
*texture
;
4164 IDirect3DSurface8
*ds
;
4167 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4168 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, format
)))
4171 hr
= IDirect3DDevice8_CreateTexture(device
, 1024, 1024, 1,
4172 D3DUSAGE_DEPTHSTENCIL
, format
, D3DPOOL_DEFAULT
, &texture
);
4173 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
4175 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
4176 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
4178 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
4179 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
4181 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
4182 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4184 /* Setup the depth/stencil surface. */
4185 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
4186 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
4188 hr
= IDirect3DDevice8_BeginScene(device
);
4189 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4190 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4191 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4192 hr
= IDirect3DDevice8_EndScene(device
);
4193 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4195 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
4196 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
4197 IDirect3DSurface8_Release(ds
);
4199 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4200 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4201 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
4202 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4204 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4205 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4207 /* Do the actual shadow mapping. */
4208 hr
= IDirect3DDevice8_BeginScene(device
);
4209 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4210 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4211 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4212 hr
= IDirect3DDevice8_EndScene(device
);
4213 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4215 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
4216 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4217 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
4218 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4219 IDirect3DTexture8_Release(texture
);
4221 get_rt_readback(original_rt
, &rb
);
4222 for (j
= 0; j
< ARRAY_SIZE(expected_colors
); ++j
)
4224 D3DCOLOR color
= get_readback_color(&rb
, expected_colors
[j
].x
, expected_colors
[j
].y
);
4225 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
4226 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
4227 * Accept alpha mismatches as broken but make sure to check the color channels. */
4228 ok(color_match(color
, expected_colors
[j
].color
, 0)
4229 || broken(color_match(color
& 0x00ffffff, expected_colors
[j
].color
& 0x00ffffff, 0)),
4230 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4231 expected_colors
[j
].color
, expected_colors
[j
].x
, expected_colors
[j
].y
,
4232 formats
[i
].name
, color
);
4234 release_surface_readback(&rb
);
4236 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4237 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
4240 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4241 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
4242 IDirect3DSurface8_Release(original_rt
);
4243 IDirect3DSurface8_Release(rt
);
4244 refcount
= IDirect3DDevice8_Release(device
);
4245 ok(!refcount
, "Device has %u references left.\n", refcount
);
4247 IDirect3D8_Release(d3d
);
4248 DestroyWindow(window
);
4251 static void multisample_copy_rects_test(void)
4253 IDirect3DSurface8
*ds
, *ds_plain
, *rt
, *readback
;
4254 RECT src_rect
= {64, 64, 128, 128};
4255 POINT dst_point
= {96, 96};
4256 D3DLOCKED_RECT locked_rect
;
4257 IDirect3DDevice8
*device
;
4264 window
= create_window();
4265 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4266 ok(!!d3d
, "Failed to create a D3D object.\n");
4267 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4269 skip("Failed to create a D3D device, skipping tests.\n");
4273 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
4274 D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
4276 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4277 IDirect3DDevice8_Release(device
);
4281 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 256, 256, D3DFMT_A8R8G8B8
,
4282 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
4283 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
4284 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 256, 256, D3DFMT_D24S8
,
4285 D3DMULTISAMPLE_2_SAMPLES
, &ds
);
4286 ok(SUCCEEDED(hr
), "Failed to create depth stencil surface, hr %#x.\n", hr
);
4287 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 256, 256, D3DFMT_D24S8
,
4288 D3DMULTISAMPLE_NONE
, &ds_plain
);
4289 ok(SUCCEEDED(hr
), "Failed to create depth stencil surface, hr %#x.\n", hr
);
4290 hr
= IDirect3DDevice8_CreateImageSurface(device
, 256, 256, D3DFMT_A8R8G8B8
, &readback
);
4291 ok(SUCCEEDED(hr
), "Failed to create readback surface, hr %#x.\n", hr
);
4293 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
4294 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
4296 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
4297 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4299 hr
= IDirect3DDevice8_CopyRects(device
, rt
, NULL
, 0, readback
, NULL
);
4300 ok(SUCCEEDED(hr
), "Failed to read render target back, hr %#x.\n", hr
);
4302 hr
= IDirect3DDevice8_CopyRects(device
, ds
, NULL
, 0, ds_plain
, NULL
);
4303 ok(hr
== D3DERR_INVALIDCALL
, "Depth buffer copy, hr %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
4305 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
4306 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4308 hr
= IDirect3DDevice8_CopyRects(device
, rt
, &src_rect
, 1, readback
, &dst_point
);
4309 ok(SUCCEEDED(hr
), "Failed to read render target back, hr %#x.\n", hr
);
4311 hr
= IDirect3DSurface8_LockRect(readback
, &locked_rect
, NULL
, D3DLOCK_READONLY
);
4312 ok(SUCCEEDED(hr
), "Failed to lock readback surface, hr %#x.\n", hr
);
4314 color
= *(DWORD
*)((BYTE
*)locked_rect
.pBits
+ 31 * locked_rect
.Pitch
+ 31 * 4);
4315 ok(color
== 0xff00ff00, "Got unexpected color 0x%08x.\n", color
);
4317 color
= *(DWORD
*)((BYTE
*)locked_rect
.pBits
+ 127 * locked_rect
.Pitch
+ 127 * 4);
4318 ok(color
== 0xffff0000, "Got unexpected color 0x%08x.\n", color
);
4320 hr
= IDirect3DSurface8_UnlockRect(readback
);
4321 ok(SUCCEEDED(hr
), "Failed to unlock readback surface, hr %#x.\n", hr
);
4323 IDirect3DSurface8_Release(readback
);
4324 IDirect3DSurface8_Release(ds_plain
);
4325 IDirect3DSurface8_Release(ds
);
4326 IDirect3DSurface8_Release(rt
);
4327 refcount
= IDirect3DDevice8_Release(device
);
4328 ok(!refcount
, "Device has %u references left.\n", refcount
);
4330 IDirect3D8_Release(d3d
);
4331 DestroyWindow(window
);
4334 static void resz_test(void)
4336 IDirect3DSurface8
*rt
, *original_rt
, *ds
, *original_ds
, *intz_ds
;
4337 IDirect3DTexture8
*texture
;
4338 IDirect3DDevice8
*device
;
4347 static const DWORD ps_code
[] =
4349 0xffff0101, /* ps_1_1 */
4350 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4351 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4352 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4353 0x00000042, 0xb00f0000, /* tex t0 */
4354 0x00000042, 0xb00f0001, /* tex t1 */
4355 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4356 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4357 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4358 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4359 0x0000ffff, /* end */
4365 float s1
, t1
, p1
, q1
;
4369 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
4370 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
4371 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
4372 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
4381 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4382 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4383 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4384 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4385 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4386 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4387 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4388 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4391 window
= create_window();
4392 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4393 ok(!!d3d
, "Failed to create a D3D object.\n");
4394 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4396 skip("Failed to create a D3D device, skipping tests.\n");
4400 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
4401 D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
4403 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4404 IDirect3DDevice8_Release(device
);
4407 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
4408 D3DDEVTYPE_HAL
, D3DFMT_D24S8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
4410 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4411 IDirect3DDevice8_Release(device
);
4414 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4415 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, MAKEFOURCC('I','N','T','Z'))))
4417 skip("No INTZ support, skipping RESZ test.\n");
4418 IDirect3DDevice8_Release(device
);
4421 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4422 D3DFMT_X8R8G8B8
, D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, MAKEFOURCC('R','E','S','Z'))))
4424 skip("No RESZ support, skipping RESZ test.\n");
4425 IDirect3DDevice8_Release(device
);
4429 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4430 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
4431 if (caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
)
4433 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4434 IDirect3DDevice8_Release(device
);
4438 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
4439 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4440 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &original_ds
);
4441 ok(SUCCEEDED(hr
), "Failed to get depth/stencil, hr %#x.\n", hr
);
4443 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
4444 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
4445 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
4446 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
,
4447 D3DMULTISAMPLE_2_SAMPLES
, &ds
);
4449 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
4450 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
4451 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
4452 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &intz_ds
);
4453 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
4455 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, intz_ds
);
4456 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
4457 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
4458 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4460 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
4461 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
4462 IDirect3DSurface8_Release(intz_ds
);
4463 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
4464 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
4466 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
4467 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4468 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
4469 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
4470 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4471 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
4472 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4473 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
4474 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4475 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
4476 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4478 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
4479 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4480 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
4481 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4482 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4483 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4484 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
4485 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4487 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
4488 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4489 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
4490 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4491 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4492 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4493 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
4494 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4495 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
4496 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4497 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
4498 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
4499 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
4501 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4502 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
4503 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4505 hr
= IDirect3DDevice8_BeginScene(device
);
4506 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4507 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4508 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4510 /* The destination depth texture has to be bound to sampler 0 */
4511 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4512 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4514 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4515 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
4516 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4517 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
4518 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4519 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0);
4520 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4521 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4522 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4523 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
4524 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4525 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
4526 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4527 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0xf);
4528 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4530 /* The actual multisampled depth buffer resolve happens here */
4531 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
4532 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
4533 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_POINTSIZE
, &value
);
4534 ok(SUCCEEDED(hr
) && value
== 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr
, value
);
4536 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
4537 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
4538 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
4539 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4540 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4541 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4543 /* Read the depth values back. */
4544 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4545 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4546 hr
= IDirect3DDevice8_EndScene(device
);
4547 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4549 for (i
= 0; i
< ARRAY_SIZE(expected_colors
); ++i
)
4551 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
4552 ok(color_match(color
, expected_colors
[i
].color
, 1),
4553 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4554 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
4557 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4558 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
4560 /* Test edge cases - try with no texture at all */
4561 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
4562 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4563 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
4564 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4565 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
4566 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
4568 hr
= IDirect3DDevice8_BeginScene(device
);
4569 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4570 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4571 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4572 hr
= IDirect3DDevice8_EndScene(device
);
4573 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4575 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
4576 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
4578 /* With a non-multisampled depth buffer */
4579 IDirect3DSurface8_Release(ds
);
4580 IDirect3DSurface8_Release(rt
);
4581 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
,
4582 D3DMULTISAMPLE_NONE
, &ds
);
4584 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
4585 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
4586 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
4587 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4589 hr
= IDirect3DDevice8_BeginScene(device
);
4590 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4591 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4592 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4593 hr
= IDirect3DDevice8_EndScene(device
);
4594 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4596 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4597 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4599 hr
= IDirect3DDevice8_BeginScene(device
);
4600 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4601 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
4602 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4603 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
4604 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4605 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0);
4606 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4607 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4608 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4609 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
4610 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4611 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
4612 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4613 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0xf);
4614 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4615 hr
= IDirect3DDevice8_EndScene(device
);
4616 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4618 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
4619 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
4621 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
4622 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4623 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4624 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4626 /* Read the depth values back. */
4627 hr
= IDirect3DDevice8_BeginScene(device
);
4628 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4629 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4630 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4631 hr
= IDirect3DDevice8_EndScene(device
);
4632 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4634 for (i
= 0; i
< ARRAY_SIZE(expected_colors
); ++i
)
4636 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
4637 ok(color_match(color
, expected_colors
[i
].color
, 1),
4638 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4639 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
4642 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4643 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
4645 IDirect3DSurface8_Release(ds
);
4646 IDirect3DTexture8_Release(texture
);
4647 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4648 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
4649 IDirect3DSurface8_Release(original_ds
);
4650 IDirect3DSurface8_Release(original_rt
);
4652 refcount
= IDirect3DDevice8_Release(device
);
4653 ok(!refcount
, "Device has %u references left.\n", refcount
);
4655 IDirect3D8_Release(d3d
);
4656 DestroyWindow(window
);
4659 static void zenable_test(void)
4661 IDirect3DDevice8
*device
;
4671 IDirect3DSurface8
*ds
, *rt
;
4675 struct vec4 position
;
4680 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
4681 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
4682 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
4683 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
4686 window
= create_window();
4687 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4688 ok(!!d3d
, "Failed to create a D3D object.\n");
4689 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4691 skip("Failed to create a D3D device, skipping tests.\n");
4695 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &ds
);
4696 ok(SUCCEEDED(hr
), "Failed to get depth stencil surface, hr %#x.\n", hr
);
4697 hr
= IDirect3DDevice8_GetRenderTarget(device
, &rt
);
4698 ok(SUCCEEDED(hr
), "Failed to get render target surface, hr %#x.\n", hr
);
4700 for (test
= 0; test
< 2; ++test
)
4702 /* The Windows 8 testbot (WARP) appears to clip with
4703 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4704 static const D3DCOLOR expected_broken
[] =
4706 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4707 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4708 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4709 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4714 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, NULL
);
4715 ok(SUCCEEDED(hr
), "Failed to set depth stencil surface, hr %#x.\n", hr
);
4719 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_FALSE
);
4720 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
4721 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
4722 ok(SUCCEEDED(hr
), "Failed to set depth stencil surface, hr %#x.\n", hr
);
4723 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0x00000000, 0.0f
, 0);
4724 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4726 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
4727 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4729 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
4730 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4731 hr
= IDirect3DDevice8_BeginScene(device
);
4732 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4733 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, tquad
, sizeof(*tquad
));
4734 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4735 hr
= IDirect3DDevice8_EndScene(device
);
4736 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4738 for (i
= 0; i
< 4; ++i
)
4740 for (j
= 0; j
< 4; ++j
)
4742 x
= 80 * ((2 * j
) + 1);
4743 y
= 60 * ((2 * i
) + 1);
4744 color
= getPixelColor(device
, x
, y
);
4745 ok(color_match(color
, 0x0000ff00, 1)
4746 || broken(color_match(color
, expected_broken
[i
* 4 + j
], 1) && !test
),
4747 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
4751 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4752 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4755 IDirect3DSurface8_Release(ds
);
4756 IDirect3DSurface8_Release(rt
);
4758 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4759 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4761 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1)
4762 && caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1))
4764 static const DWORD vs_code
[] =
4766 0xfffe0101, /* vs_1_1 */
4767 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4768 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4771 static const DWORD ps_code
[] =
4773 0xffff0101, /* ps_1_1 */
4774 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4775 0x0000ffff /* end */
4777 static const struct vec3 quad
[] =
4779 {-1.0f
, -1.0f
, -0.5f
},
4780 {-1.0f
, 1.0f
, -0.5f
},
4781 { 1.0f
, -1.0f
, 1.5f
},
4782 { 1.0f
, 1.0f
, 1.5f
},
4784 static const D3DCOLOR expected
[] =
4786 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4787 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4788 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4789 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4791 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4792 * vertices either. */
4793 static const D3DCOLOR expected_broken
[] =
4795 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4796 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4797 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4798 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4800 static const DWORD decl
[] =
4803 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
4808 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_code
, &vs
, 0);
4809 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
4810 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
4811 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4812 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
4813 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
4814 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4815 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4817 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
4818 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4819 hr
= IDirect3DDevice8_BeginScene(device
);
4820 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4821 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4822 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4823 hr
= IDirect3DDevice8_EndScene(device
);
4824 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4826 for (i
= 0; i
< 4; ++i
)
4828 for (j
= 0; j
< 4; ++j
)
4830 x
= 80 * ((2 * j
) + 1);
4831 y
= 60 * ((2 * i
) + 1);
4832 color
= getPixelColor(device
, x
, y
);
4833 ok(color_match(color
, expected
[i
* 4 + j
], 1)
4834 || broken(color_match(color
, expected_broken
[i
* 4 + j
], 1)),
4835 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected
[i
* 4 + j
], x
, y
, color
);
4839 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4840 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4842 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4843 ok(SUCCEEDED(hr
), "Failed to delete pixel shader, hr %#x.\n", hr
);
4844 hr
= IDirect3DDevice8_DeleteVertexShader(device
, vs
);
4845 ok(SUCCEEDED(hr
), "Failed to delete vertex shader, hr %#x.\n", hr
);
4848 refcount
= IDirect3DDevice8_Release(device
);
4849 ok(!refcount
, "Device has %u references left.\n", refcount
);
4851 IDirect3D8_Release(d3d
);
4852 DestroyWindow(window
);
4855 static void fog_special_test(void)
4857 IDirect3DDevice8
*device
;
4874 struct vec3 position
;
4879 {{ -1.0f
, -1.0f
, 0.0f
}, 0xff00ff00},
4880 {{ -1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
4881 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
4882 {{ 1.0f
, 1.0f
, 1.0f
}, 0xff00ff00}
4886 DWORD vertexmode
, tablemode
;
4888 D3DCOLOR color_left
, color_right
;
4892 {D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, FALSE
, 0x00ff0000, 0x00ff0000},
4893 {D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, TRUE
, 0x00ff0000, 0x00ff0000},
4894 {D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000},
4895 {D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000},
4897 {D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, FALSE
, 0x0000ff00, 0x00ff0000},
4898 {D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, TRUE
, 0x0000ff00, 0x00ff0000},
4899 {D3DFOG_NONE
, D3DFOG_LINEAR
, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000},
4900 {D3DFOG_NONE
, D3DFOG_LINEAR
, TRUE
, TRUE
, 0x0000ff00, 0x00ff0000},
4902 static const DWORD pixel_shader_code
[] =
4904 0xffff0101, /* ps.1.1 */
4905 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4908 static const DWORD vertex_decl
[] =
4911 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
4912 D3DVSD_REG(1, D3DVSDT_D3DCOLOR
), /* diffuse color, v1 */
4915 static const DWORD vertex_shader_code
[] =
4917 0xfffe0101, /* vs.1.1 */
4918 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4919 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4922 static const D3DMATRIX identity
=
4924 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4925 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4926 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4927 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4930 window
= create_window();
4931 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4932 ok(!!d3d
, "Failed to create a D3D object.\n");
4933 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4935 skip("Failed to create a D3D device, skipping tests.\n");
4939 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4940 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4941 if (caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1))
4943 hr
= IDirect3DDevice8_CreateVertexShader(device
, vertex_decl
, vertex_shader_code
, &vs
, 0);
4944 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
4948 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4951 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1))
4953 hr
= IDirect3DDevice8_CreatePixelShader(device
, pixel_shader_code
, &ps
);
4954 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4958 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4962 /* The table fog tests seem to depend on the projection matrix explicitly
4963 * being set to an identity matrix, even though that's the default.
4964 * (AMD Radeon HD 6310, Windows 7) */
4965 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
4966 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
4968 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
4969 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4970 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
4971 ok(SUCCEEDED(hr
), "Failed to enable fog, hr %#x.\n", hr
);
4972 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xffff0000);
4973 ok(SUCCEEDED(hr
), "Failed to set fog color, hr %#x.\n", hr
);
4976 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, conv
.d
);
4977 ok(SUCCEEDED(hr
), "Failed to set fog start, hr %#x.\n", hr
);
4978 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, conv
.d
);
4979 ok(SUCCEEDED(hr
), "Failed to set fog end, hr %#x.\n", hr
);
4981 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4983 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
4984 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4988 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
4989 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
4993 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
4994 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
5003 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
5004 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
5008 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
5009 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
5016 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, tests
[i
].vertexmode
);
5017 ok(SUCCEEDED(hr
), "Failed to set fogvertexmode, hr %#x.\n", hr
);
5018 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, tests
[i
].tablemode
);
5019 ok(SUCCEEDED(hr
), "Failed to set fogtablemode, hr %#x.\n", hr
);
5021 hr
= IDirect3DDevice8_BeginScene(device
);
5022 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5023 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
5024 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5025 hr
= IDirect3DDevice8_EndScene(device
);
5026 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5028 color
= getPixelColor(device
, 310, 240);
5029 ok(color_match(color
, tests
[i
].color_left
, 1),
5030 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_left
, color
, i
);
5031 color
= getPixelColor(device
, 330, 240);
5032 ok(color_match(color
, tests
[i
].color_right
, 1),
5033 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_right
, color
, i
);
5035 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5036 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
5040 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
5042 IDirect3DDevice8_DeletePixelShader(device
, ps
);
5043 refcount
= IDirect3DDevice8_Release(device
);
5044 ok(!refcount
, "Device has %u references left.\n", refcount
);
5046 IDirect3D8_Release(d3d
);
5047 DestroyWindow(window
);
5050 static void volume_dxtn_test(void)
5052 IDirect3DVolumeTexture8
*texture
;
5053 struct surface_readback rb
;
5054 IDirect3DDevice8
*device
;
5055 IDirect3DSurface8
*rt
;
5064 static const BYTE dxt1_data
[] =
5066 0x00, 0xf8, 0x00, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0,
5067 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5068 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5069 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5071 static const BYTE dxt3_data
[] =
5073 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5074 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5075 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5076 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5078 static const BYTE dxt5_data
[] =
5080 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colours of the
5081 * blocks are red, green, blue and white. */
5082 0xff, 0xff, 0x80, 0x0d, 0xd8, 0x80, 0x0d, 0xd8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5083 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5084 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5085 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5087 static const DWORD dxt1_expected_colours
[] =
5089 0xffff0000, 0x00000000, 0xff00ff00, 0xff00ff00,
5090 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff,
5092 static const DWORD dxt3_expected_colours
[] =
5094 0xffff0000, 0xeeff0000, 0xff00ff00, 0xdd00ff00,
5095 0xff0000ff, 0xcc0000ff, 0xffffffff, 0xbbffffff,
5097 static const DWORD dxt5_expected_colours
[] =
5099 0xffff0000, 0x00ff0000, 0xff00ff00, 0xff00ff00,
5100 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff
5109 const DWORD
*expected_colours
;
5113 {"DXT1", D3DFMT_DXT1
, dxt1_data
, sizeof(dxt1_data
), dxt1_expected_colours
},
5114 {"DXT3", D3DFMT_DXT3
, dxt3_data
, sizeof(dxt3_data
), dxt3_expected_colours
},
5115 {"DXT5", D3DFMT_DXT5
, dxt5_data
, sizeof(dxt5_data
), dxt5_expected_colours
},
5120 struct vec3 position
;
5125 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.25f
}},
5126 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.25f
}},
5127 {{ 0.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.25f
}},
5128 {{ 0.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.25f
}},
5130 {{ 0.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.75f
}},
5131 {{ 0.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.75f
}},
5132 {{ 1.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.75f
}},
5133 {{ 1.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.75f
}},
5136 window
= create_window();
5137 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
5138 ok(!!d3d
, "Failed to create a D3D object.\n");
5140 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5142 skip("Failed to create a D3D device, skipping tests.\n");
5146 hr
= IDirect3DDevice8_GetRenderTarget(device
, &rt
);
5147 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5149 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5151 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
5152 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, tests
[i
].format
)))
5154 skip("%s volume textures are not supported, skipping test.\n", tests
[i
].name
);
5157 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 8, 4, 2, 1, 0,
5158 tests
[i
].format
, D3DPOOL_MANAGED
, &texture
);
5159 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
5161 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &box
, NULL
, 0);
5162 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
5163 memcpy(box
.pBits
, tests
[i
].data
, tests
[i
].data_size
);
5164 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
5165 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
5167 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0));
5168 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
5169 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
5170 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5171 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
5172 ok(SUCCEEDED(hr
), "Failed to set colour op, hr %#x.\n", hr
);
5173 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
5174 ok(SUCCEEDED(hr
), "Failed to set colour arg, hr %#x.\n", hr
);
5175 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
5176 ok(SUCCEEDED(hr
), "Failed to set colour op, hr %#x.\n", hr
);
5177 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
5178 ok(SUCCEEDED(hr
), "Failed to set mag filter, hr %#x.\n", hr
);
5180 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
5181 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
5182 hr
= IDirect3DDevice8_BeginScene(device
);
5183 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5184 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
5185 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5186 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
5187 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5188 hr
= IDirect3DDevice8_EndScene(device
);
5189 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5191 get_rt_readback(rt
, &rb
);
5192 for (j
= 0; j
< ARRAY_SIZE(dxt1_expected_colours
); ++j
)
5194 colour
= get_readback_color(&rb
, 40 + 80 * j
, 240);
5195 ok(color_match(colour
, tests
[i
].expected_colours
[j
], 1),
5196 "Expected colour 0x%08x, got 0x%08x, case %u.\n", tests
[i
].expected_colours
[j
], colour
, j
);
5198 release_surface_readback(&rb
);
5200 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5201 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5202 IDirect3DVolumeTexture8_Release(texture
);
5205 IDirect3DSurface8_Release(rt
);
5206 refcount
= IDirect3DDevice8_Release(device
);
5207 ok(!refcount
, "Device has %u references left.\n", refcount
);
5209 IDirect3D8_Release(d3d
);
5210 DestroyWindow(window
);
5213 static void volume_v16u16_test(void)
5215 IDirect3DVolumeTexture8
*texture
;
5216 IDirect3DDevice8
*device
;
5230 struct vec3 position
;
5235 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.25f
}},
5236 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.25f
}},
5237 {{ 0.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.25f
}},
5238 {{ 0.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.25f
}},
5240 {{ 0.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.75f
}},
5241 {{ 0.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.75f
}},
5242 {{ 1.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.75f
}},
5243 {{ 1.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.75f
}},
5245 static const DWORD shader_code
[] =
5247 0xffff0101, /* ps_1_1 */
5248 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5249 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5250 0x00000042, 0xb00f0000, /* tex t0 */
5251 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5252 0x0000ffff /* end */
5255 window
= create_window();
5256 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
5257 ok(!!d3d
, "Failed to create a D3D object.\n");
5258 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5260 skip("Failed to create a D3D device, skipping tests.\n");
5264 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
5265 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, D3DFMT_V16U16
)))
5267 skip("Volume V16U16 textures are not supported, skipping test.\n");
5268 IDirect3DDevice8_Release(device
);
5271 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
5272 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5273 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
5275 skip("No pixel shader 1.1 support, skipping test.\n");
5276 IDirect3DDevice8_Release(device
);
5280 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0));
5281 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
5282 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code
, &shader
);
5283 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
5284 hr
= IDirect3DDevice8_SetPixelShader(device
, shader
);
5285 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
5286 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
5287 ok(SUCCEEDED(hr
), "Failed to set filter, hr %#x.\n", hr
);
5289 for (i
= 0; i
< 2; i
++)
5294 pool
= D3DPOOL_SYSTEMMEM
;
5296 pool
= D3DPOOL_MANAGED
;
5298 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 2, 2, 1, 0, D3DFMT_V16U16
,
5300 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
5302 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &box
, NULL
, 0);
5303 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
5305 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 0 * box
.RowPitch
+ 0 * box
.SlicePitch
);
5308 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 1 * box
.RowPitch
+ 0 * box
.SlicePitch
);
5311 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 0 * box
.RowPitch
+ 1 * box
.SlicePitch
);
5314 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 1 * box
.RowPitch
+ 1 * box
.SlicePitch
);
5318 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
5319 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
5323 IDirect3DVolumeTexture8
*texture2
;
5325 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 2, 2, 1, 0, D3DFMT_V16U16
,
5326 D3DPOOL_DEFAULT
, &texture2
);
5327 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
5329 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)texture
,
5330 (IDirect3DBaseTexture8
*)texture2
);
5331 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5333 IDirect3DVolumeTexture8_Release(texture
);
5337 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) texture
);
5338 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5340 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
5341 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
5342 hr
= IDirect3DDevice8_BeginScene(device
);
5343 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5344 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
5345 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5346 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
5347 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5348 hr
= IDirect3DDevice8_EndScene(device
);
5349 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5351 color
= getPixelColor(device
, 120, 160);
5352 ok (color_match(color
, 0x000080ff, 2),
5353 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color
);
5354 color
= getPixelColor(device
, 120, 400);
5355 ok (color_match(color
, 0x00ffffff, 2),
5356 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color
);
5357 color
= getPixelColor(device
, 360, 160);
5358 ok (color_match(color
, 0x007f7fff, 2),
5359 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color
);
5360 color
= getPixelColor(device
, 360, 400);
5361 ok (color_match(color
, 0x0040c0ff, 2),
5362 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color
);
5364 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5365 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5367 IDirect3DVolumeTexture8_Release(texture
);
5370 hr
= IDirect3DDevice8_DeletePixelShader(device
, shader
);
5371 ok(SUCCEEDED(hr
), "Failed delete pixel shader, hr %#x.\n", hr
);
5372 refcount
= IDirect3DDevice8_Release(device
);
5373 ok(!refcount
, "Device has %u references left.\n", refcount
);
5375 IDirect3D8_Release(d3d
);
5376 DestroyWindow(window
);
5379 static void fill_surface(IDirect3DSurface8
*surface
, DWORD color
, DWORD flags
)
5381 D3DSURFACE_DESC desc
;
5387 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
5388 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5389 hr
= IDirect3DSurface8_LockRect(surface
, &l
, NULL
, flags
);
5390 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5394 for (y
= 0; y
< desc
.Height
; y
++)
5396 mem
= (DWORD
*)((BYTE
*)l
.pBits
+ y
* l
.Pitch
);
5397 for (x
= 0; x
< l
.Pitch
/ sizeof(DWORD
); x
++)
5402 hr
= IDirect3DSurface8_UnlockRect(surface
);
5403 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5406 static void add_dirty_rect_test_draw(IDirect3DDevice8
*device
)
5411 struct vec3 position
;
5412 struct vec2 texcoord
;
5416 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
5417 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
5418 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
5419 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
5422 hr
= IDirect3DDevice8_BeginScene(device
);
5423 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5424 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
, sizeof(*quad
));
5425 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5426 hr
= IDirect3DDevice8_EndScene(device
);
5427 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5430 static void add_dirty_rect_test(void)
5432 IDirect3DTexture8
*tex_dst1
, *tex_dst2
, *tex_src_red
, *tex_src_green
,
5433 *tex_managed
, *tex_dynamic
;
5434 IDirect3DSurface8
*surface_dst2
, *surface_src_green
, *surface_src_red
,
5435 *surface_managed0
, *surface_managed1
, *surface_dynamic
;
5436 D3DLOCKED_RECT locked_rect
;
5437 IDirect3DDevice8
*device
;
5446 static const RECT part_rect
= {96, 96, 160, 160};
5447 static const RECT oob_rect
[] =
5453 {300, 200, 310, 210},
5457 window
= create_window();
5458 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
5459 ok(!!d3d
, "Failed to create a D3D object.\n");
5460 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5462 skip("Failed to create a D3D device, skipping tests.\n");
5466 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
5467 D3DPOOL_DEFAULT
, &tex_dst1
);
5468 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5469 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
5470 D3DPOOL_DEFAULT
, &tex_dst2
);
5471 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5472 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
5473 D3DPOOL_SYSTEMMEM
, &tex_src_red
);
5474 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5475 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
5476 D3DPOOL_SYSTEMMEM
, &tex_src_green
);
5477 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5478 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 2, 0, D3DFMT_X8R8G8B8
,
5479 D3DPOOL_MANAGED
, &tex_managed
);
5480 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5481 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, D3DUSAGE_DYNAMIC
,
5482 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &tex_dynamic
);
5483 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5485 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_dst2
, 0, &surface_dst2
);
5486 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5487 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_src_green
, 0, &surface_src_green
);
5488 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5489 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_src_red
, 0, &surface_src_red
);
5490 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5491 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_managed
, 0, &surface_managed0
);
5492 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5493 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_managed
, 1, &surface_managed1
);
5494 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5495 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_dynamic
, 0, &surface_dynamic
);
5496 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5498 fill_surface(surface_src_red
, 0x00ff0000, 0);
5499 fill_surface(surface_src_green
, 0x0000ff00, 0);
5501 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
5502 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
5503 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
5504 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
5505 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
5506 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
5507 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
5508 ok(SUCCEEDED(hr
), "Failed to set mip filter, hr %#x.\n", hr
);
5510 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5511 (IDirect3DBaseTexture8
*)tex_dst1
);
5512 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5514 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5515 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_red
,
5516 (IDirect3DBaseTexture8
*)tex_dst2
);
5517 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5518 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5519 (IDirect3DBaseTexture8
*)tex_dst2
);
5520 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5522 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst1
);
5523 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5524 add_dirty_rect_test_draw(device
);
5525 color
= getPixelColor(device
, 320, 240);
5526 ok(color_match(color
, 0x0000ff00, 1),
5527 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5528 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5529 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5531 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst2
);
5532 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5533 add_dirty_rect_test_draw(device
);
5534 color
= getPixelColor(device
, 320, 240);
5535 ok(color_match(color
, 0x00ff0000, 1),
5536 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5537 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5538 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5540 /* AddDirtyRect on the destination is ignored. */
5541 hr
= IDirect3DTexture8_AddDirtyRect(tex_dst2
, &part_rect
);
5542 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5543 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5544 (IDirect3DBaseTexture8
*)tex_dst2
);
5545 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5546 add_dirty_rect_test_draw(device
);
5547 color
= getPixelColor(device
, 320, 240);
5548 ok(color_match(color
, 0x00ff0000, 1),
5549 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5550 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5551 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5553 hr
= IDirect3DTexture8_AddDirtyRect(tex_dst2
, NULL
);
5554 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5555 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5556 (IDirect3DBaseTexture8
*)tex_dst2
);
5557 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5558 add_dirty_rect_test_draw(device
);
5559 color
= getPixelColor(device
, 320, 240);
5560 ok(color_match(color
, 0x00ff0000, 1),
5561 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5562 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5563 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5565 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5566 * tracking is supported. */
5567 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, &part_rect
);
5568 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5569 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5570 (IDirect3DBaseTexture8
*)tex_dst2
);
5571 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5572 add_dirty_rect_test_draw(device
);
5573 color
= getPixelColor(device
, 320, 240);
5574 ok(color_match(color
, 0x0000ff00, 1),
5575 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5576 color
= getPixelColor(device
, 1, 1);
5577 ok(color_match(color
, 0x00ff0000, 1),
5578 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5579 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5580 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5582 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, NULL
);
5583 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5584 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5585 (IDirect3DBaseTexture8
*)tex_dst2
);
5586 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5587 add_dirty_rect_test_draw(device
);
5588 color
= getPixelColor(device
, 1, 1);
5589 ok(color_match(color
, 0x0000ff00, 1),
5590 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5592 /* Locks with NO_DIRTY_UPDATE are ignored. */
5593 fill_surface(surface_src_green
, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE
);
5594 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5595 (IDirect3DBaseTexture8
*)tex_dst2
);
5596 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5597 add_dirty_rect_test_draw(device
);
5598 color
= getPixelColor(device
, 320, 240);
5599 ok(color_match(color
, 0x0000ff00, 1),
5600 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5601 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5602 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5604 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5605 fill_surface(surface_src_green
, 0x000000ff, D3DLOCK_READONLY
);
5606 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5607 (IDirect3DBaseTexture8
*)tex_dst2
);
5608 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5609 add_dirty_rect_test_draw(device
);
5610 color
= getPixelColor(device
, 320, 240);
5611 ok(color_match(color
, 0x0000ff00, 1),
5612 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5613 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5614 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5616 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, NULL
);
5617 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5618 (IDirect3DBaseTexture8
*)tex_dst2
);
5619 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5620 add_dirty_rect_test_draw(device
);
5621 color
= getPixelColor(device
, 320, 240);
5622 ok(color_match(color
, 0x000000ff, 1),
5623 "Expected color 0x000000ff, got 0x%08x.\n", color
);
5624 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5625 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5627 /* Maps without either of these flags record a dirty rectangle. */
5628 fill_surface(surface_src_green
, 0x00ffffff, 0);
5629 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5630 (IDirect3DBaseTexture8
*)tex_dst2
);
5631 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5632 add_dirty_rect_test_draw(device
);
5633 color
= getPixelColor(device
, 320, 240);
5634 ok(color_match(color
, 0x00ffffff, 1),
5635 "Expected color 0x00ffffff, got 0x%08x.\n", color
);
5636 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5637 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5639 /* Partial LockRect works just like a partial AddDirtyRect call. */
5640 hr
= IDirect3DTexture8_LockRect(tex_src_green
, 0, &locked_rect
, &part_rect
, 0);
5641 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5642 texel
= locked_rect
.pBits
;
5643 for (i
= 0; i
< 64; i
++)
5644 texel
[i
] = 0x00ff00ff;
5645 for (i
= 1; i
< 64; i
++)
5646 memcpy((BYTE
*)locked_rect
.pBits
+ i
* locked_rect
.Pitch
, locked_rect
.pBits
, locked_rect
.Pitch
);
5647 hr
= IDirect3DTexture8_UnlockRect(tex_src_green
, 0);
5648 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5649 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5650 (IDirect3DBaseTexture8
*)tex_dst2
);
5651 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5652 add_dirty_rect_test_draw(device
);
5653 color
= getPixelColor(device
, 320, 240);
5654 ok(color_match(color
, 0x00ff00ff, 1),
5655 "Expected color 0x00ff00ff, got 0x%08x.\n", color
);
5656 color
= getPixelColor(device
, 1, 1);
5657 ok(color_match(color
, 0x00ffffff, 1),
5658 "Expected color 0x00ffffff, got 0x%08x.\n", color
);
5659 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5660 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5662 fill_surface(surface_src_red
, 0x00ff0000, 0);
5663 fill_surface(surface_src_green
, 0x0000ff00, 0);
5665 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
5666 (IDirect3DBaseTexture8
*)tex_dst1
);
5667 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
5668 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst1
);
5669 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5670 add_dirty_rect_test_draw(device
);
5671 color
= getPixelColor(device
, 320, 240);
5672 ok(color_match(color
, 0x0000ff00, 1),
5673 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5674 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5675 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5677 /* UpdateSurface ignores the missing dirty marker. */
5678 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_red
,
5679 (IDirect3DBaseTexture8
*)tex_dst2
);
5680 hr
= IDirect3DDevice8_CopyRects(device
, surface_src_green
, NULL
, 0, surface_dst2
, NULL
);
5681 ok(SUCCEEDED(hr
), "Failed to update surface, hr %#x.\n", hr
);
5682 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst2
);
5683 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5684 add_dirty_rect_test_draw(device
);
5685 color
= getPixelColor(device
, 320, 240);
5686 ok(color_match(color
, 0x0000ff00, 1),
5687 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5688 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5689 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5691 /* Tests with managed textures. */
5692 fill_surface(surface_managed0
, 0x00ff0000, 0);
5693 fill_surface(surface_managed1
, 0x00ff0000, 0);
5694 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_managed
);
5695 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5696 add_dirty_rect_test_draw(device
);
5697 color
= getPixelColor(device
, 320, 240);
5698 ok(color_match(color
, 0x00ff0000, 1),
5699 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5700 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5701 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5702 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAXMIPLEVEL
, 1);
5703 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
5704 add_dirty_rect_test_draw(device
);
5705 color
= getPixelColor(device
, 320, 240);
5706 ok(color_match(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
5707 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5708 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5710 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5711 fill_surface(surface_managed0
, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE
);
5712 fill_surface(surface_managed1
, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE
);
5713 add_dirty_rect_test_draw(device
);
5714 color
= getPixelColor(device
, 320, 240);
5715 ok(color_match(color
, 0x00ff0000, 1),
5716 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5717 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5718 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5719 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAXMIPLEVEL
, 0);
5720 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
5721 add_dirty_rect_test_draw(device
);
5722 color
= getPixelColor(device
, 320, 240);
5723 ok(color_match(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
5724 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5725 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5727 /* AddDirtyRect uploads the new contents.
5728 * Side note, not tested in the test: Partial surface updates work, and two separate
5729 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5731 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5732 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5733 add_dirty_rect_test_draw(device
);
5734 color
= getPixelColor(device
, 320, 240);
5735 ok(color_match(color
, 0x0000ff00, 1),
5736 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5737 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5738 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5739 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAXMIPLEVEL
, 1);
5740 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
5741 add_dirty_rect_test_draw(device
);
5742 color
= getPixelColor(device
, 320, 240);
5743 ok(color_match(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
5744 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5745 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5747 /* So does ResourceManagerDiscardBytes. */
5748 fill_surface(surface_managed0
, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE
);
5749 fill_surface(surface_managed1
, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE
);
5750 hr
= IDirect3DDevice8_ResourceManagerDiscardBytes(device
, 0);
5751 ok(SUCCEEDED(hr
), "Failed to evict managed resources, hr %#x.\n", hr
);
5752 add_dirty_rect_test_draw(device
);
5753 color
= getPixelColor(device
, 320, 240);
5754 ok(color_match(color
, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color
);
5755 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5756 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5757 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAXMIPLEVEL
, 0);
5758 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
5759 add_dirty_rect_test_draw(device
);
5760 color
= getPixelColor(device
, 320, 240);
5761 ok(color_match(color
, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color
);
5762 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5763 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5765 /* Tests with dynamic textures */
5766 fill_surface(surface_dynamic
, 0x0000ffff, 0);
5767 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dynamic
);
5768 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5769 add_dirty_rect_test_draw(device
);
5770 color
= getPixelColor(device
, 320, 240);
5771 ok(color_match(color
, 0x0000ffff, 1),
5772 "Expected color 0x0000ffff, got 0x%08x.\n", color
);
5773 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5774 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5776 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
5777 fill_surface(surface_dynamic
, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE
);
5778 add_dirty_rect_test_draw(device
);
5779 color
= getPixelColor(device
, 320, 240);
5780 ok(color_match(color
, 0x00ffff00, 1),
5781 "Expected color 0x00ffff00, got 0x%08x.\n", color
);
5782 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5783 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5785 /* AddDirtyRect on a locked texture is allowed. */
5786 hr
= IDirect3DTexture8_LockRect(tex_src_red
, 0, &locked_rect
, NULL
, 0);
5787 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5788 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_red
, NULL
);
5789 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5790 hr
= IDirect3DTexture8_UnlockRect(tex_src_red
, 0);
5791 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5793 /* Redundant AddDirtyRect calls are ok. */
5794 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5795 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5796 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5797 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5799 /* Test out-of-bounds regions. */
5800 for (i
= 0; i
< ARRAY_SIZE(oob_rect
); ++i
)
5802 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_red
, &oob_rect
[i
]);
5803 ok(hr
== D3DERR_INVALIDCALL
, "[%u] Got unexpected hr %#x.\n", i
, hr
);
5804 hr
= IDirect3DTexture8_LockRect(tex_src_red
, 0, &locked_rect
, &oob_rect
[i
], 0);
5805 ok(SUCCEEDED(hr
), "[%u] Got unexpected hr %#x.\n", i
, hr
);
5806 hr
= IDirect3DTexture8_UnlockRect(tex_src_red
, 0);
5807 ok(SUCCEEDED(hr
), "[%u] Got unexpected hr %#x.\n", i
, hr
);
5810 IDirect3DSurface8_Release(surface_dst2
);
5811 IDirect3DSurface8_Release(surface_managed1
);
5812 IDirect3DSurface8_Release(surface_managed0
);
5813 IDirect3DSurface8_Release(surface_src_red
);
5814 IDirect3DSurface8_Release(surface_src_green
);
5815 IDirect3DSurface8_Release(surface_dynamic
);
5816 IDirect3DTexture8_Release(tex_src_red
);
5817 IDirect3DTexture8_Release(tex_src_green
);
5818 IDirect3DTexture8_Release(tex_dst1
);
5819 IDirect3DTexture8_Release(tex_dst2
);
5820 IDirect3DTexture8_Release(tex_managed
);
5821 IDirect3DTexture8_Release(tex_dynamic
);
5822 refcount
= IDirect3DDevice8_Release(device
);
5823 ok(!refcount
, "Device has %u references left.\n", refcount
);
5825 IDirect3D8_Release(d3d
);
5826 DestroyWindow(window
);
5829 static void test_3dc_formats(void)
5831 static const char ati1n_data
[] =
5833 /* A 4x4 texture with the color component at 50%. */
5834 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5836 static const char ati2n_data
[] =
5838 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5839 * 0% second component. Second block is the opposite. */
5840 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5845 struct vec3 position
;
5846 struct vec2 texcoord
;
5850 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
5851 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
5852 {{ 0.0f
, -1.0f
, 1.0f
}, {1.0f
, 0.0f
}},
5853 {{ 0.0f
, 1.0f
, 1.0f
}, {1.0f
, 1.0f
}},
5855 {{ 0.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
5856 {{ 0.0f
, 1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
5857 {{ 1.0f
, -1.0f
, 1.0f
}, {1.0f
, 0.0f
}},
5858 {{ 1.0f
, 1.0f
, 1.0f
}, {1.0f
, 1.0f
}},
5860 static const DWORD ati1n_fourcc
= MAKEFOURCC('A','T','I','1');
5861 static const DWORD ati2n_fourcc
= MAKEFOURCC('A','T','I','2');
5864 struct vec2 position
;
5867 D3DCOLOR nvidia_old
;
5868 D3DCOLOR nvidia_new
;
5872 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5873 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5874 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5875 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5878 IDirect3DDevice8
*device
;
5879 IDirect3DTexture8
*ati1n_texture
, *ati2n_texture
;
5881 D3DLOCKED_RECT rect
;
5888 window
= create_window();
5889 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
5890 ok(!!d3d
, "Failed to create a D3D object.\n");
5891 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
5892 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, ati1n_fourcc
)))
5894 skip("ATI1N textures are not supported, skipping test.\n");
5897 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
5898 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, ati2n_fourcc
)))
5900 skip("ATI2N textures are not supported, skipping test.\n");
5903 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5905 skip("Failed to create a D3D device, skipping tests.\n");
5908 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
5909 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
5910 if (!(caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_TSSARGTEMP
))
5912 skip("D3DTA_TEMP not supported, skipping tests.\n");
5913 IDirect3DDevice8_Release(device
);
5917 hr
= IDirect3DDevice8_CreateTexture(device
, 4, 4, 1, 0, ati1n_fourcc
,
5918 D3DPOOL_MANAGED
, &ati1n_texture
);
5919 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5921 hr
= IDirect3DTexture8_LockRect(ati1n_texture
, 0, &rect
, NULL
, 0);
5922 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5923 memcpy(rect
.pBits
, ati1n_data
, sizeof(ati1n_data
));
5924 hr
= IDirect3DTexture8_UnlockRect(ati1n_texture
, 0);
5925 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5927 hr
= IDirect3DDevice8_CreateTexture(device
, 8, 4, 1, 0, ati2n_fourcc
,
5928 D3DPOOL_MANAGED
, &ati2n_texture
);
5929 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5931 hr
= IDirect3DTexture8_LockRect(ati2n_texture
, 0, &rect
, NULL
, 0);
5932 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5933 memcpy(rect
.pBits
, ati2n_data
, sizeof(ati2n_data
));
5934 hr
= IDirect3DTexture8_UnlockRect(ati2n_texture
, 0);
5935 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5937 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE2(0));
5938 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
5939 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDTEXTUREALPHA
);
5940 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
5941 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
5942 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
5943 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TEMP
);
5944 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
5945 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
5946 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
5947 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
);
5948 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
5949 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
5950 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
5951 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
5952 ok(SUCCEEDED(hr
), "Failed to set mag filter, hr %#x.\n", hr
);
5954 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
5955 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
5956 hr
= IDirect3DDevice8_BeginScene(device
);
5957 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5958 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)ati1n_texture
);
5959 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5960 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
5961 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5962 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)ati2n_texture
);
5963 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
5964 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
5965 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5966 hr
= IDirect3DDevice8_EndScene(device
);
5967 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5969 for (i
= 0; i
< 4; ++i
)
5971 color
= getPixelColor(device
, expected_colors
[i
].position
.x
, expected_colors
[i
].position
.y
);
5972 ok (color_match(color
, expected_colors
[i
].amd_r500
, 1)
5973 || color_match(color
, expected_colors
[i
].amd_r600
, 1)
5974 || color_match(color
, expected_colors
[i
].nvidia_old
, 1)
5975 || color_match(color
, expected_colors
[i
].nvidia_new
, 1),
5976 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
5979 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5980 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5981 IDirect3DTexture8_Release(ati2n_texture
);
5982 IDirect3DTexture8_Release(ati1n_texture
);
5983 refcount
= IDirect3DDevice8_Release(device
);
5984 ok(!refcount
, "Device has %u references left.\n", refcount
);
5987 IDirect3D8_Release(d3d
);
5988 DestroyWindow(window
);
5991 static void test_fog_interpolation(void)
5994 IDirect3DDevice8
*device
;
6001 struct vec3 position
;
6007 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff000000},
6008 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff000000},
6009 {{ 1.0f
, -1.0f
, 1.0f
}, 0xffff0000, 0x00000000},
6010 {{ 1.0f
, 1.0f
, 1.0f
}, 0xffff0000, 0x00000000},
6020 D3DFOGMODE vfog
, tfog
;
6022 D3DCOLOR middle_color
;
6027 {D3DFOG_NONE
, D3DFOG_NONE
, D3DSHADE_FLAT
, 0x00007f80, FALSE
},
6028 {D3DFOG_NONE
, D3DFOG_NONE
, D3DSHADE_GOURAUD
, 0x00007f80, FALSE
},
6029 {D3DFOG_EXP
, D3DFOG_NONE
, D3DSHADE_FLAT
, 0x00007f80, TRUE
},
6030 {D3DFOG_EXP
, D3DFOG_NONE
, D3DSHADE_GOURAUD
, 0x00007f80, TRUE
},
6031 {D3DFOG_NONE
, D3DFOG_EXP
, D3DSHADE_FLAT
, 0x0000ea15, FALSE
},
6032 {D3DFOG_NONE
, D3DFOG_EXP
, D3DSHADE_GOURAUD
, 0x0000ea15, FALSE
},
6033 {D3DFOG_EXP
, D3DFOG_EXP
, D3DSHADE_FLAT
, 0x0000ea15, FALSE
},
6034 {D3DFOG_EXP
, D3DFOG_EXP
, D3DSHADE_GOURAUD
, 0x0000ea15, FALSE
},
6036 static const D3DMATRIX ident_mat
=
6038 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6039 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6040 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6041 0.0f
, 0.0f
, 0.0f
, 1.0f
6045 window
= create_window();
6046 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6047 ok(!!d3d
, "Failed to create a D3D object.\n");
6049 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
6051 skip("Failed to create a D3D device, skipping tests.\n");
6052 IDirect3D8_Release(d3d
);
6053 DestroyWindow(window
);
6057 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6058 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6059 if (!(caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
6060 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
6062 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
6063 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
6064 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
6065 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6066 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
6067 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6068 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
6069 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6070 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0x0000ff00);
6071 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6073 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGDENSITY
, conv
.d
);
6074 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6076 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
6077 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
6078 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
6079 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
6080 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_TEXTUREFACTOR
, 0x000000ff);
6081 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6083 /* Some of the tests seem to depend on the projection matrix explicitly
6084 * being set to an identity matrix, even though that's the default.
6085 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
6086 * the drivers seem to use a static z = 1.0 input for the fog equation.
6087 * The input value is independent of the actual z and w component of
6088 * the vertex position. */
6089 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &ident_mat
);
6090 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
6092 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6094 if(!(caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
) && tests
[i
].tfog
)
6097 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00808080, 0.0f
, 0);
6098 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
6100 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SHADEMODE
, tests
[i
].shade
);
6101 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6102 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, tests
[i
].vfog
);
6103 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6104 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, tests
[i
].tfog
);
6105 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6106 hr
= IDirect3DDevice8_BeginScene(device
);
6107 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6108 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
6109 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6110 hr
= IDirect3DDevice8_EndScene(device
);
6111 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6113 color
= getPixelColor(device
, 0, 240);
6114 ok(color_match(color
, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color
, i
);
6115 color
= getPixelColor(device
, 320, 240);
6116 todo_wine_if (tests
[i
].todo
)
6117 ok(color_match(color
, tests
[i
].middle_color
, 2),
6118 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
6119 color
= getPixelColor(device
, 639, 240);
6120 ok(color_match(color
, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color
, i
);
6121 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
6122 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
6125 refcount
= IDirect3DDevice8_Release(device
);
6126 ok(!refcount
, "Device has %u references left.\n", refcount
);
6127 IDirect3D8_Release(d3d
);
6128 DestroyWindow(window
);
6131 static void test_negative_fixedfunction_fog(void)
6134 IDirect3DDevice8
*device
;
6141 struct vec3 position
;
6146 {{-1.0f
, -1.0f
, -0.5f
}, 0xffff0000},
6147 {{-1.0f
, 1.0f
, -0.5f
}, 0xffff0000},
6148 {{ 1.0f
, -1.0f
, -0.5f
}, 0xffff0000},
6149 {{ 1.0f
, 1.0f
, -0.5f
}, 0xffff0000},
6153 struct vec4 position
;
6158 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xffff0000},
6159 {{640.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xffff0000},
6160 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xffff0000},
6161 {{640.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xffff0000},
6164 static const D3DMATRIX zero
=
6166 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6167 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6168 0.0f
, 0.0f
, 0.0f
, 0.0f
,
6169 0.0f
, 0.0f
, 0.0f
, 1.0f
6171 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
6172 * have an effect on RHW draws. */
6173 static const D3DMATRIX identity
=
6175 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6176 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6177 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6178 0.0f
, 0.0f
, 0.0f
, 1.0f
6185 const D3DMATRIX
*matrix
;
6191 D3DFOGMODE vfog
, tfog
;
6192 DWORD color
, color_broken
, color_broken2
;
6196 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
6198 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
6199 {D3DFVF_XYZRHW
, tquad
, sizeof(*tquad
), &identity
, { 0.0f
}, {1.0f
},
6200 D3DFOG_NONE
, D3DFOG_LINEAR
, 0x00ff0000, 0x00808000, 0x00808000},
6201 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
6202 * parameters to 0.0 and 1.0 in the table fog case. */
6203 {D3DFVF_XYZRHW
, tquad
, sizeof(*tquad
), &identity
, {-1.0f
}, {0.0f
},
6204 D3DFOG_NONE
, D3DFOG_LINEAR
, 0x00808000, 0x00ff0000, 0x0000ff00},
6205 /* test_fog_interpolation shows that vertex fog evaluates the fog
6206 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
6207 * that the abs happens before the fog equation is evaluated.
6209 * Vertex fog abs() behavior is the same on all GPUs. */
6210 {D3DFVF_XYZ
, quad
, sizeof(*quad
), &zero
, { 0.0f
}, {1.0f
},
6211 D3DFOG_LINEAR
, D3DFOG_NONE
, 0x00808000, 0x00808000, 0x00808000},
6212 {D3DFVF_XYZ
, quad
, sizeof(*quad
), &zero
, {-1.0f
}, {0.0f
},
6213 D3DFOG_LINEAR
, D3DFOG_NONE
, 0x0000ff00, 0x0000ff00, 0x0000ff00},
6214 {D3DFVF_XYZ
, quad
, sizeof(*quad
), &zero
, { 0.0f
}, {1.0f
},
6215 D3DFOG_EXP
, D3DFOG_NONE
, 0x009b6400, 0x009b6400, 0x009b6400},
6219 window
= create_window();
6220 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6221 ok(!!d3d
, "Failed to create a D3D object.\n");
6223 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
6225 skip("Failed to create a D3D device, skipping tests.\n");
6226 IDirect3D8_Release(d3d
);
6227 DestroyWindow(window
);
6231 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6232 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6233 if (!(caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
6234 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
6236 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
6237 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6238 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_FALSE
);
6239 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6240 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
6241 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6242 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0x0000ff00);
6243 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6244 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
6245 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
6247 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6249 if (!(caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
) && tests
[i
].tfog
)
6252 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
6253 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
6255 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, tests
[i
].matrix
);
6256 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
6257 hr
= IDirect3DDevice8_SetVertexShader(device
, tests
[i
].pos_type
| D3DFVF_DIFFUSE
);
6258 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
6259 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, tests
[i
].start
.d
);
6260 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6261 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, tests
[i
].end
.d
);
6262 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6263 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, tests
[i
].vfog
);
6264 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6265 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, tests
[i
].tfog
);
6266 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6268 hr
= IDirect3DDevice8_BeginScene(device
);
6269 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6270 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, tests
[i
].quad
, tests
[i
].stride
);
6271 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6272 hr
= IDirect3DDevice8_EndScene(device
);
6273 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6275 color
= getPixelColor(device
, 320, 240);
6276 ok(color_match(color
, tests
[i
].color
, 2) || broken(color_match(color
, tests
[i
].color_broken
, 2))
6277 || broken(color_match(color
, tests
[i
].color_broken2
, 2)),
6278 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
6279 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
6280 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
6283 refcount
= IDirect3DDevice8_Release(device
);
6284 ok(!refcount
, "Device has %u references left.\n", refcount
);
6285 IDirect3D8_Release(d3d
);
6286 DestroyWindow(window
);
6289 static void test_table_fog_zw(void)
6292 IDirect3DDevice8
*device
;
6300 struct vec4 position
;
6305 {{ 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0xffff0000},
6306 {{640.0f
, 0.0f
, 0.0f
, 0.0f
}, 0xffff0000},
6307 {{ 0.0f
, 480.0f
, 0.0f
, 0.0f
}, 0xffff0000},
6308 {{640.0f
, 480.0f
, 0.0f
, 0.0f
}, 0xffff0000},
6310 static const D3DMATRIX identity
=
6312 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6313 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6314 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6315 0.0f
, 0.0f
, 0.0f
, 1.0f
6320 D3DZBUFFERTYPE z_test
;
6325 {0.7f
, 0.0f
, D3DZB_TRUE
, 0x004cb200},
6326 {0.7f
, 0.0f
, D3DZB_FALSE
, 0x004cb200},
6327 {0.7f
, 0.3f
, D3DZB_TRUE
, 0x004cb200},
6328 {0.7f
, 0.3f
, D3DZB_FALSE
, 0x004cb200},
6329 {0.7f
, 3.0f
, D3DZB_TRUE
, 0x004cb200},
6330 {0.7f
, 3.0f
, D3DZB_FALSE
, 0x004cb200},
6331 {0.3f
, 0.0f
, D3DZB_TRUE
, 0x00b24c00},
6332 {0.3f
, 0.0f
, D3DZB_FALSE
, 0x00b24c00},
6336 window
= create_window();
6337 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6338 ok(!!d3d
, "Failed to create a D3D object.\n");
6340 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
6342 skip("Failed to create a D3D device, skipping tests.\n");
6343 IDirect3D8_Release(d3d
);
6344 DestroyWindow(window
);
6348 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6349 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6350 if (!(caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
6352 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6356 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
6357 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6358 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
6359 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6360 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0x0000ff00);
6361 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6362 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
6363 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
6364 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6365 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
6366 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
6367 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
6368 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6369 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
6370 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
6372 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6374 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x000000ff, 1.0f
, 0);
6375 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
6377 quad
[0].position
.z
= tests
[i
].z
;
6378 quad
[1].position
.z
= tests
[i
].z
;
6379 quad
[2].position
.z
= tests
[i
].z
;
6380 quad
[3].position
.z
= tests
[i
].z
;
6381 quad
[0].position
.w
= tests
[i
].w
;
6382 quad
[1].position
.w
= tests
[i
].w
;
6383 quad
[2].position
.w
= tests
[i
].w
;
6384 quad
[3].position
.w
= tests
[i
].w
;
6385 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, tests
[i
].z_test
);
6386 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6388 hr
= IDirect3DDevice8_BeginScene(device
);
6389 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6390 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
6391 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6392 hr
= IDirect3DDevice8_EndScene(device
);
6393 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6395 color
= getPixelColor(device
, 320, 240);
6396 ok(color_match(color
, tests
[i
].color
, 2),
6397 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color
, tests
[i
].color
, i
);
6398 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
6399 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
6403 refcount
= IDirect3DDevice8_Release(device
);
6404 ok(!refcount
, "Device has %u references left.\n", refcount
);
6405 IDirect3D8_Release(d3d
);
6406 DestroyWindow(window
);
6409 static void test_signed_formats(void)
6411 IDirect3DDevice8
*device
;
6414 unsigned int i
, j
, x
, y
;
6415 IDirect3DTexture8
*texture
, *texture_sysmem
;
6416 D3DLOCKED_RECT locked_rect
;
6417 DWORD shader
, shader_alpha
;
6423 /* See comments in the d3d9 version of this test for an
6424 * explanation of these values. */
6425 static const USHORT content_v8u8
[4][4] =
6427 {0x0000, 0x7f7f, 0x8880, 0x0000},
6428 {0x0080, 0x8000, 0x7f00, 0x007f},
6429 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6430 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6432 static const DWORD content_v16u16
[4][4] =
6434 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6435 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6436 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6437 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6439 static const DWORD content_q8w8v8u8
[4][4] =
6441 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6442 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6443 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6444 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6446 static const DWORD content_x8l8v8u8
[4][4] =
6448 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6449 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6450 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6451 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6453 static const USHORT content_l6v5u5
[4][4] =
6455 {0x0000, 0xfdef, 0x0230, 0xfc00},
6456 {0x0010, 0x0200, 0x01e0, 0x000f},
6457 {0x4067, 0x53b9, 0x0421, 0xffff},
6458 {0x8108, 0x0318, 0xc28c, 0x909c},
6464 const void *content
;
6467 unsigned int slop
, slop_broken
, alpha_broken
;
6471 {D3DFMT_V8U8
, "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, FALSE
, 1, 0, FALSE
},
6472 {D3DFMT_V16U16
, "D3DFMT_V16U16", content_v16u16
, sizeof(DWORD
), FALSE
, FALSE
, 1, 0, FALSE
},
6473 {D3DFMT_Q8W8V8U8
, "D3DFMT_Q8W8V8U8", content_q8w8v8u8
, sizeof(DWORD
), TRUE
, TRUE
, 1, 0, TRUE
},
6474 {D3DFMT_X8L8V8U8
, "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, FALSE
, 1, 0, FALSE
},
6475 {D3DFMT_L6V5U5
, "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, FALSE
, 4, 7, FALSE
},
6484 {D3DPOOL_SYSTEMMEM
, 4},
6485 {D3DPOOL_SYSTEMMEM
, 1},
6486 {D3DPOOL_MANAGED
, 4},
6487 {D3DPOOL_MANAGED
, 1},
6489 static const DWORD shader_code
[] =
6491 0xffff0101, /* ps_1_1 */
6492 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6493 0x00000042, 0xb00f0000, /* tex t0 */
6494 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6495 0x0000ffff /* end */
6497 static const DWORD shader_code_alpha
[] =
6499 /* The idea of this shader is to replicate the alpha value in .rg, and set
6500 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6501 0xffff0101, /* ps_1_1 */
6502 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6503 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6504 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6505 0x00000042, 0xb00f0000, /* tex t0 */
6506 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6507 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6508 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6509 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6510 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6511 0x0000ffff /* end */
6515 struct vec3 position
;
6520 /* Flip the y coordinate to make the input and
6521 * output arrays easier to compare. */
6522 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 1.0f
}},
6523 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 0.0f
}},
6524 {{ 1.0f
, -1.0f
, 0.0f
}, { 1.0f
, 1.0f
}},
6525 {{ 1.0f
, 1.0f
, 0.0f
}, { 1.0f
, 0.0f
}},
6527 static const D3DCOLOR expected_alpha
[4][4] =
6529 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6530 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6531 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6532 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6534 static const BOOL alpha_broken
[4][4] =
6536 {FALSE
, FALSE
, FALSE
, FALSE
},
6537 {FALSE
, FALSE
, FALSE
, FALSE
},
6538 {FALSE
, FALSE
, FALSE
, TRUE
},
6539 {FALSE
, FALSE
, FALSE
, FALSE
},
6541 static const D3DCOLOR expected_colors
[4][4] =
6543 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6544 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6545 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6546 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6548 D3DCOLOR expected_color
;
6550 window
= create_window();
6551 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6552 ok(!!d3d
, "Failed to create a D3D object.\n");
6554 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
6556 skip("Failed to create a D3D device, skipping tests.\n");
6557 IDirect3D8_Release(d3d
);
6558 DestroyWindow(window
);
6562 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6563 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6565 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
6567 skip("Pixel shaders not supported, skipping converted format test.\n");
6571 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_FALSE
);
6572 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6573 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
6574 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
6575 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code
, &shader
);
6576 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
6577 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_alpha
, &shader_alpha
);
6578 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
6580 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
6582 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
6583 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, formats
[i
].format
);
6586 skip("Format %s not supported, skipping.\n", formats
[i
].name
);
6590 for (j
= 0; j
< ARRAY_SIZE(tests
); j
++)
6592 texture_sysmem
= NULL
;
6593 hr
= IDirect3DDevice8_CreateTexture(device
, tests
[j
].width
, 4, 1, 0,
6594 formats
[i
].format
, tests
[j
].pool
, &texture
);
6595 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
6597 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, NULL
, 0);
6598 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
6599 for (y
= 0; y
< 4; y
++)
6601 memcpy((char *)locked_rect
.pBits
+ y
* locked_rect
.Pitch
,
6602 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
6603 tests
[j
].width
* formats
[i
].pixel_size
);
6605 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
6606 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
6608 if (tests
[j
].pool
== D3DPOOL_SYSTEMMEM
)
6610 texture_sysmem
= texture
;
6611 hr
= IDirect3DDevice8_CreateTexture(device
, tests
[j
].width
, 4, 1, 0,
6612 formats
[i
].format
, D3DPOOL_DEFAULT
, &texture
);
6613 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
6615 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)texture_sysmem
,
6616 (IDirect3DBaseTexture8
*)texture
);
6617 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
6618 IDirect3DTexture8_Release(texture_sysmem
);
6621 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
6622 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
6623 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_alpha
);
6624 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
6626 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00330033, 0.0f
, 0);
6627 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
6628 hr
= IDirect3DDevice8_BeginScene(device
);
6629 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6630 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(*quad
));
6631 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6632 hr
= IDirect3DDevice8_EndScene(device
);
6633 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6635 for (y
= 0; y
< 4; y
++)
6637 for (x
= 0; x
< tests
[j
].width
; x
++)
6639 BOOL r200_broken
= formats
[i
].alpha_broken
&& alpha_broken
[y
][x
];
6640 if (formats
[i
].alpha
)
6641 expected_color
= expected_alpha
[y
][x
];
6643 expected_color
= 0x00ffff00;
6645 color
= getPixelColor(device
, 80 + 160 * x
, 60 + 120 * y
);
6646 ok(color_match(color
, expected_color
, 1) || broken(r200_broken
),
6647 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6648 expected_color
, color
, formats
[i
].name
, j
, x
, y
);
6651 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
6652 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
6654 hr
= IDirect3DDevice8_SetPixelShader(device
, shader
);
6655 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
6657 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00330033, 0.0f
, 0);
6658 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
6659 hr
= IDirect3DDevice8_BeginScene(device
);
6660 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6661 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(*quad
));
6662 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6663 hr
= IDirect3DDevice8_EndScene(device
);
6664 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6666 for (y
= 0; y
< 4; y
++)
6668 for (x
= 0; x
< tests
[j
].width
; x
++)
6670 expected_color
= expected_colors
[y
][x
];
6671 if (!formats
[i
].blue
)
6672 expected_color
|= 0x000000ff;
6674 color
= getPixelColor(device
, 80 + 160 * x
, 60 + 120 * y
);
6675 ok(color_match(color
, expected_color
, formats
[i
].slop
)
6676 || broken(color_match(color
, expected_color
, formats
[i
].slop_broken
)),
6677 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6678 expected_color
, color
, formats
[i
].name
, j
, x
, y
);
6681 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
6682 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
6684 IDirect3DTexture8_Release(texture
);
6688 IDirect3DDevice8_DeletePixelShader(device
, shader
);
6689 IDirect3DDevice8_DeletePixelShader(device
, shader_alpha
);
6692 refcount
= IDirect3DDevice8_Release(device
);
6693 ok(!refcount
, "Device has %u references left.\n", refcount
);
6694 IDirect3D8_Release(d3d
);
6695 DestroyWindow(window
);
6698 static void test_updatetexture(void)
6700 IDirect3DDevice8
*device
;
6704 IDirect3DBaseTexture8
*src
, *dst
;
6705 unsigned int t
, i
, f
, l
, x
, y
, z
;
6706 D3DLOCKED_RECT locked_rect
;
6707 D3DLOCKED_BOX locked_box
;
6711 BOOL ati2n_supported
, do_visual_test
;
6715 struct vec2 texcoord
;
6719 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
6720 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
6721 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
6722 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
6727 struct vec3 texcoord
;
6731 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, -0.5f
, 0.5f
}},
6732 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.5f
, 0.5f
}},
6733 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, -0.5f
, -0.5f
}},
6734 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.5f
, -0.5f
}},
6738 UINT src_width
, src_height
;
6739 UINT dst_width
, dst_height
;
6740 UINT src_levels
, dst_levels
;
6741 D3DFORMAT src_format
, dst_format
;
6746 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 0 */
6747 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 1 */
6748 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 2 */
6749 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 3 */
6750 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 4 */
6751 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 5 */
6752 /* The WARP renderer doesn't handle these cases correctly. */
6753 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, TRUE
}, /* 6 */
6754 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, TRUE
}, /* 7 */
6755 /* Not clear what happens here on Windows, it doesn't make much sense
6756 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6757 * one or something like that). */
6758 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6759 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 8 */
6760 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 9 */
6761 /* This one causes weird behavior on Windows (it probably writes out
6762 * of the texture memory). */
6763 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6764 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 10 */
6765 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 11 */
6766 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_X8R8G8B8
, FALSE
}, /* 12 */
6767 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
}, /* 13 */
6768 /* The data is converted correctly on AMD, on Nvidia nothing happens
6769 * (it draws a black quad). */
6770 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_R5G6B5
, TRUE
}, /* 14 */
6771 /* This one doesn't seem to give the expected results on AMD. */
6772 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6773 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE
}, /* 15 */
6774 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE
}, /* 16 */
6775 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE
}, /* 17 */
6779 D3DRESOURCETYPE type
;
6782 unsigned int vertex_size
;
6788 {D3DRTYPE_TEXTURE
, D3DFVF_XYZ
| D3DFVF_TEX1
,
6789 quad
, sizeof(*quad
), D3DPTEXTURECAPS_MIPMAP
, "2D mipmapped"},
6791 {D3DRTYPE_CUBETEXTURE
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0),
6792 quad_cube_tex
, sizeof(*quad_cube_tex
), D3DPTEXTURECAPS_CUBEMAP
, "Cube"},
6794 {D3DRTYPE_VOLUMETEXTURE
, D3DFVF_XYZ
| D3DFVF_TEX1
,
6795 quad
, sizeof(*quad
), D3DPTEXTURECAPS_VOLUMEMAP
, "Volume"}
6798 window
= create_window();
6799 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6800 ok(!!d3d
, "Failed to create a D3D object.\n");
6801 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
6803 skip("Failed to create a D3D device, skipping tests.\n");
6804 IDirect3D8_Release(d3d
);
6805 DestroyWindow(window
);
6809 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6810 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6812 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_LINEAR
);
6813 ok(SUCCEEDED(hr
), "Failed to set texture filtering state, hr %#x.\n", hr
);
6814 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ADDRESSU
, D3DTADDRESS_CLAMP
);
6815 ok(SUCCEEDED(hr
), "Failed to set texture filtering state, hr %#x.\n", hr
);
6816 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ADDRESSV
, D3DTADDRESS_CLAMP
);
6817 ok(SUCCEEDED(hr
), "Failed to set texture filtering state, hr %#x.\n", hr
);
6818 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ADDRESSW
, D3DTADDRESS_CLAMP
);
6819 ok(SUCCEEDED(hr
), "Failed to set texture filtering state, hr %#x.\n", hr
);
6820 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
6821 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
6822 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
6823 ok(hr
== D3D_OK
, "Failed to set texture stage state, hr %#x.\n", hr
);
6824 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
6825 ok(hr
== D3D_OK
, "Failed to set texture stage state, hr %#x.\n", hr
);
6827 for (t
= 0; t
< ARRAY_SIZE(texture_types
); ++t
)
6829 if (!(caps
.TextureCaps
& texture_types
[t
].cap
))
6831 skip("%s textures not supported, skipping some tests.\n", texture_types
[t
].name
);
6835 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
6836 D3DFMT_X8R8G8B8
, 0, texture_types
[t
].type
, MAKEFOURCC('A','T','I','2'))))
6838 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types
[t
].name
);
6839 ati2n_supported
= FALSE
;
6843 ati2n_supported
= TRUE
;
6846 hr
= IDirect3DDevice8_SetVertexShader(device
, texture_types
[t
].fvf
);
6847 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
6849 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6851 if (tests
[i
].src_format
== MAKEFOURCC('A','T','I','2') && !ati2n_supported
)
6854 switch (texture_types
[t
].type
)
6856 case D3DRTYPE_TEXTURE
:
6857 hr
= IDirect3DDevice8_CreateTexture(device
,
6858 tests
[i
].src_width
, tests
[i
].src_height
,
6859 tests
[i
].src_levels
, 0, tests
[i
].src_format
, D3DPOOL_SYSTEMMEM
,
6860 (IDirect3DTexture8
**)&src
);
6861 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6862 hr
= IDirect3DDevice8_CreateTexture(device
,
6863 tests
[i
].dst_width
, tests
[i
].dst_height
,
6864 tests
[i
].dst_levels
, 0, tests
[i
].dst_format
, D3DPOOL_DEFAULT
,
6865 (IDirect3DTexture8
**)&dst
);
6866 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6868 case D3DRTYPE_CUBETEXTURE
:
6869 hr
= IDirect3DDevice8_CreateCubeTexture(device
,
6871 tests
[i
].src_levels
, 0, tests
[i
].src_format
, D3DPOOL_SYSTEMMEM
,
6872 (IDirect3DCubeTexture8
**)&src
);
6873 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6874 hr
= IDirect3DDevice8_CreateCubeTexture(device
,
6876 tests
[i
].dst_levels
, 0, tests
[i
].dst_format
, D3DPOOL_DEFAULT
,
6877 (IDirect3DCubeTexture8
**)&dst
);
6878 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6880 case D3DRTYPE_VOLUMETEXTURE
:
6881 hr
= IDirect3DDevice8_CreateVolumeTexture(device
,
6882 tests
[i
].src_width
, tests
[i
].src_height
, tests
[i
].src_width
,
6883 tests
[i
].src_levels
, 0, tests
[i
].src_format
, D3DPOOL_SYSTEMMEM
,
6884 (IDirect3DVolumeTexture8
**)&src
);
6885 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6886 hr
= IDirect3DDevice8_CreateVolumeTexture(device
,
6887 tests
[i
].dst_width
, tests
[i
].dst_height
, tests
[i
].dst_width
,
6888 tests
[i
].dst_levels
, 0, tests
[i
].dst_format
, D3DPOOL_DEFAULT
,
6889 (IDirect3DVolumeTexture8
**)&dst
);
6890 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6893 trace("Unexpected resource type.\n");
6896 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6897 * give a different (and unlikely to be useful) result. */
6898 do_visual_test
= (tests
[i
].src_format
== D3DFMT_A8R8G8B8
|| tests
[i
].src_format
== D3DFMT_X8R8G8B8
)
6899 && tests
[i
].src_levels
!= 0
6900 && tests
[i
].src_width
>= tests
[i
].dst_width
&& tests
[i
].src_height
>= tests
[i
].dst_height
6901 && !(tests
[i
].src_width
> tests
[i
].src_height
&& tests
[i
].dst_width
< tests
[i
].dst_height
);
6906 unsigned int width
, height
, depth
, row_pitch
= 0, slice_pitch
= 0;
6908 for (f
= 0; f
< (texture_types
[t
].type
== D3DRTYPE_CUBETEXTURE
? 6 : 1); ++f
)
6910 width
= tests
[i
].src_width
;
6911 height
= texture_types
[t
].type
!= D3DRTYPE_CUBETEXTURE
? tests
[i
].src_height
: tests
[i
].src_width
;
6912 depth
= texture_types
[t
].type
== D3DRTYPE_VOLUMETEXTURE
? width
: 1;
6914 for (l
= 0; l
< tests
[i
].src_levels
; ++l
)
6916 switch (texture_types
[t
].type
)
6918 case D3DRTYPE_TEXTURE
:
6919 hr
= IDirect3DTexture8_LockRect((IDirect3DTexture8
*)src
,
6920 l
, &locked_rect
, NULL
, 0);
6921 ptr
= locked_rect
.pBits
;
6922 row_pitch
= locked_rect
.Pitch
/ sizeof(*ptr
);
6924 case D3DRTYPE_CUBETEXTURE
:
6925 hr
= IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8
*)src
,
6926 f
, l
, &locked_rect
, NULL
, 0);
6927 ptr
= locked_rect
.pBits
;
6928 row_pitch
= locked_rect
.Pitch
/ sizeof(*ptr
);
6930 case D3DRTYPE_VOLUMETEXTURE
:
6931 hr
= IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8
*)src
,
6932 l
, &locked_box
, NULL
, 0);
6933 ptr
= locked_box
.pBits
;
6934 row_pitch
= locked_box
.RowPitch
/ sizeof(*ptr
);
6935 slice_pitch
= locked_box
.SlicePitch
/ sizeof(*ptr
);
6938 trace("Unexpected resource type.\n");
6940 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
6942 for (z
= 0; z
< depth
; ++z
)
6944 for (y
= 0; y
< height
; ++y
)
6946 for (x
= 0; x
< width
; ++x
)
6948 ptr
[z
* slice_pitch
+ y
* row_pitch
+ x
] = 0xff000000
6949 | (DWORD
)(x
/ (width
- 1.0f
) * 255.0f
) << 16
6950 | (DWORD
)(y
/ (height
- 1.0f
) * 255.0f
) << 8;
6955 switch (texture_types
[t
].type
)
6957 case D3DRTYPE_TEXTURE
:
6958 hr
= IDirect3DTexture8_UnlockRect((IDirect3DTexture8
*)src
, l
);
6960 case D3DRTYPE_CUBETEXTURE
:
6961 hr
= IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8
*)src
, f
, l
);
6963 case D3DRTYPE_VOLUMETEXTURE
:
6964 hr
= IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8
*)src
, l
);
6967 trace("Unexpected resource type.\n");
6969 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
6984 hr
= IDirect3DDevice8_UpdateTexture(device
, src
, dst
);
6987 todo_wine
ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6988 IDirect3DBaseTexture8_Release(src
);
6989 IDirect3DBaseTexture8_Release(dst
);
6992 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x, case %u, %u.\n", hr
, t
, i
);
6996 hr
= IDirect3DDevice8_SetTexture(device
, 0, dst
);
6997 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
6999 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 1.0f
, 0);
7000 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7002 hr
= IDirect3DDevice8_BeginScene(device
);
7003 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7004 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2,
7005 texture_types
[t
].quad
, texture_types
[t
].vertex_size
);
7006 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7007 hr
= IDirect3DDevice8_EndScene(device
);
7008 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7010 color
= getPixelColor(device
, 320, 240);
7011 ok (color_match(color
, 0x007f7f00, 3) || broken(tests
[i
].broken
)
7012 || broken(color
== 0x00adbeef), /* WARP device often just breaks down. */
7013 "Got unexpected color 0x%08x, case %u, %u.\n", color
, t
, i
);
7016 IDirect3DBaseTexture8_Release(src
);
7017 IDirect3DBaseTexture8_Release(dst
);
7021 refcount
= IDirect3DDevice8_Release(device
);
7022 ok(!refcount
, "Device has %u references left.\n", refcount
);
7023 IDirect3D8_Release(d3d
);
7024 DestroyWindow(window
);
7027 static BOOL
point_match(IDirect3DDevice8
*device
, UINT x
, UINT y
, UINT r
)
7031 color
= D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
7032 if (!color_match(getPixelColor(device
, x
+ r
, y
), color
, 1))
7034 if (!color_match(getPixelColor(device
, x
- r
, y
), color
, 1))
7036 if (!color_match(getPixelColor(device
, x
, y
+ r
), color
, 1))
7038 if (!color_match(getPixelColor(device
, x
, y
- r
), color
, 1))
7042 color
= D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
7043 if (!color_match(getPixelColor(device
, x
+ r
, y
), color
, 1))
7045 if (!color_match(getPixelColor(device
, x
- r
, y
), color
, 1))
7047 if (!color_match(getPixelColor(device
, x
, y
+ r
), color
, 1))
7049 if (!color_match(getPixelColor(device
, x
, y
- r
), color
, 1))
7055 static void test_pointsize(void)
7057 static const float a
= 0.5f
, b
= 0.5f
, c
= 0.5f
;
7058 float ptsize
, ptsizemax_orig
, ptsizemin_orig
;
7059 IDirect3DSurface8
*rt
, *backbuffer
, *depthstencil
;
7060 IDirect3DTexture8
*tex1
, *tex2
;
7061 IDirect3DDevice8
*device
;
7072 static const DWORD tex1_data
[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
7073 static const DWORD tex2_data
[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
7074 static const float vertices
[] =
7077 128.0f
, 64.0f
, 0.1f
,
7078 192.0f
, 64.0f
, 0.1f
,
7079 256.0f
, 64.0f
, 0.1f
,
7080 320.0f
, 64.0f
, 0.1f
,
7081 384.0f
, 64.0f
, 0.1f
,
7082 448.0f
, 64.0f
, 0.1f
,
7083 512.0f
, 64.0f
, 0.1f
,
7090 vertex_pointsize
= {64.0f
, 64.0f
, 0.1f
, 48.0f
},
7091 vertex_pointsize_scaled
= {64.0f
, 64.0f
, 0.1f
, 24.0f
},
7092 vertex_pointsize_zero
= {64.0f
, 64.0f
, 0.1f
, 0.0f
};
7093 static const DWORD decl
[] =
7096 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7102 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
7103 D3DVSD_REG(1, D3DVSDT_FLOAT1
), /* point size, v1 */
7106 static const DWORD vshader_code
[] =
7108 0xfffe0101, /* vs_1_1 */
7109 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7110 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7111 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7112 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7115 static const DWORD vshader_psize_code
[] =
7117 0xfffe0101, /* vs_1_1 */
7118 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7119 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7120 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7121 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7122 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
7125 static const DWORD pshader_code
[] =
7127 0xffff0101, /* ps_1_1 */
7128 0x00000042, 0xb00f0000, /* tex t0 */
7129 0x00000042, 0xb00f0001, /* tex t1 */
7130 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
7133 static const struct test_shader
7139 vs1
= {D3DVS_VERSION(1, 1), vshader_code
},
7140 vs1_psize
= {D3DVS_VERSION(1, 1), vshader_psize_code
},
7142 ps1
= {D3DPS_VERSION(1, 1), pshader_code
};
7146 const struct test_shader
*vs
;
7147 const struct test_shader
*ps
;
7149 unsigned int nonscaled_size
, scaled_size
;
7153 {NULL
, &novs
, &nops
, D3DFVF_XYZ
, 32, 62},
7154 {decl
, &vs1
, &ps1
, D3DFVF_XYZ
, 32, 32},
7155 {NULL
, &novs
, &ps1
, D3DFVF_XYZ
, 32, 62},
7156 {decl
, &vs1
, &nops
, D3DFVF_XYZ
, 32, 32},
7157 {NULL
, &novs
, &nops
, D3DFVF_XYZ
| D3DFVF_PSIZE
, 48, 48},
7158 {decl_psize
, &vs1_psize
, &ps1
, D3DFVF_XYZ
| D3DFVF_PSIZE
, 48, 24},
7166 const void *vertex_data
;
7167 unsigned int vertex_size
;
7171 {FALSE
, FALSE
, FALSE
, D3DFVF_XYZ
, vertices
, sizeof(float) * 3},
7172 {FALSE
, TRUE
, FALSE
, D3DFVF_XYZ
, vertices
, sizeof(float) * 3},
7173 {FALSE
, FALSE
, TRUE
, D3DFVF_XYZ
, vertices
, sizeof(float) * 3},
7174 {TRUE
, FALSE
, FALSE
, D3DFVF_XYZ
, vertices
, sizeof(float) * 3},
7175 {FALSE
, FALSE
, FALSE
, D3DFVF_XYZ
| D3DFVF_PSIZE
, &vertex_pointsize
, sizeof(vertex_pointsize
)},
7176 {FALSE
, TRUE
, FALSE
, D3DFVF_XYZ
| D3DFVF_PSIZE
, &vertex_pointsize_scaled
, sizeof(vertex_pointsize_scaled
)},
7177 {FALSE
, FALSE
, TRUE
, D3DFVF_XYZ
| D3DFVF_PSIZE
, &vertex_pointsize
, sizeof(vertex_pointsize
)},
7178 {TRUE
, FALSE
, FALSE
, D3DFVF_XYZ
| D3DFVF_PSIZE
, &vertex_pointsize_zero
, sizeof(vertex_pointsize_zero
)},
7180 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
7181 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
7184 2.0f
/ 640.0f
, 0.0f
, 0.0f
, 0.0f
,
7185 0.0f
, -2.0f
/ 480.0f
, 0.0f
, 0.0f
,
7186 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7187 -1.0f
, 1.0f
, 0.0f
, 1.0f
,
7190 window
= create_window();
7191 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
7192 ok(!!d3d
, "Failed to create a D3D object.\n");
7193 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
7195 skip("Failed to create a D3D device, skipping tests.\n");
7199 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
7200 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7201 if (caps
.MaxPointSize
< 32.0f
)
7203 skip("MaxPointSize %f < 32.0, skipping.\n", caps
.MaxPointSize
);
7204 IDirect3DDevice8_Release(device
);
7208 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
7209 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
7210 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
7211 ok(SUCCEEDED(hr
), "Failed to set FVF, hr=%#x.\n", hr
);
7212 hr
= IDirect3DDevice8_BeginScene(device
);
7213 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7214 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, vertices
, sizeof(float) * 5);
7215 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7216 hr
= IDirect3DDevice8_EndScene(device
);
7217 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7219 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
7220 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7221 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
7222 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7223 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &matrix
);
7224 ok(SUCCEEDED(hr
), "Failed to set projection matrix, hr %#x.\n", hr
);
7225 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
7226 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
7228 hr
= IDirect3DDevice8_BeginScene(device
);
7229 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7232 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7233 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7234 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[0], sizeof(float) * 3);
7235 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7238 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7239 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7240 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[3], sizeof(float) * 3);
7241 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7244 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7245 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7246 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[6], sizeof(float) * 3);
7247 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7249 if (caps
.MaxPointSize
>= 63.0f
)
7252 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7253 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7254 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[9], sizeof(float) * 3);
7255 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7258 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7259 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7260 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[15], sizeof(float) * 3);
7261 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7265 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7266 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7267 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[12], sizeof(float) * 3);
7268 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7270 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_POINTSIZE_MAX
, (DWORD
*)&ptsizemax_orig
);
7271 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
7272 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_POINTSIZE_MIN
, (DWORD
*)&ptsizemin_orig
);
7273 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
7275 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
7277 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7278 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7280 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE_MAX
, *(DWORD
*)&ptsize
);
7281 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7282 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[18], sizeof(float) * 3);
7283 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7285 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE_MAX
, *(DWORD
*)&ptsizemax_orig
);
7286 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7288 /* pointsize < pointsize_min < pointsize_max?
7289 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7291 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7292 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7294 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE_MIN
, *(DWORD
*)&ptsize
);
7295 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7296 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[21], sizeof(float) * 3);
7297 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7299 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE_MIN
, *(DWORD
*)&ptsizemin_orig
);
7300 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
7302 hr
= IDirect3DDevice8_EndScene(device
);
7303 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7305 ok(point_match(device
, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7306 ok(point_match(device
, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7307 ok(point_match(device
, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7309 if (caps
.MaxPointSize
>= 63.0f
)
7311 ok(point_match(device
, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7312 ok(point_match(device
, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7315 ok(point_match(device
, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7316 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7317 ok(point_match(device
, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7318 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7319 ok(point_match(device
, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7321 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
7323 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7324 * generates texture coordinates for the point(result: Yes, it does)
7326 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7327 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7328 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7330 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
7331 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7333 hr
= IDirect3DDevice8_CreateTexture(device
, 2, 2, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &tex1
);
7334 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
7335 hr
= IDirect3DDevice8_CreateTexture(device
, 2, 2, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &tex2
);
7336 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
7337 memset(&lr
, 0, sizeof(lr
));
7338 hr
= IDirect3DTexture8_LockRect(tex1
, 0, &lr
, NULL
, 0);
7339 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
7340 memcpy(lr
.pBits
, tex1_data
, sizeof(tex1_data
));
7341 hr
= IDirect3DTexture8_UnlockRect(tex1
, 0);
7342 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
7343 memset(&lr
, 0, sizeof(lr
));
7344 hr
= IDirect3DTexture8_LockRect(tex2
, 0, &lr
, NULL
, 0);
7345 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
7346 memcpy(lr
.pBits
, tex2_data
, sizeof(tex2_data
));
7347 hr
= IDirect3DTexture8_UnlockRect(tex2
, 0);
7348 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
7349 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex1
);
7350 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
7351 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)tex2
);
7352 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
7353 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
7354 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
7355 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
7356 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
7357 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
7358 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
7359 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
7360 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
7361 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
7362 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
7364 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSPRITEENABLE
, TRUE
);
7365 ok(SUCCEEDED(hr
), "Failed to enable point sprites, hr %#x.\n", hr
);
7367 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7368 ok(SUCCEEDED(hr
), "Failed to set point size, hr %#x.\n", hr
);
7370 hr
= IDirect3DDevice8_BeginScene(device
);
7371 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7372 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, &vertices
[0], sizeof(float) * 3);
7373 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7374 hr
= IDirect3DDevice8_EndScene(device
);
7375 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7377 color
= getPixelColor(device
, 64 - 4, 64 - 4);
7378 ok(color
== 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color
);
7379 color
= getPixelColor(device
, 64 - 4, 64 + 4);
7380 ok(color
== 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color
);
7381 color
= getPixelColor(device
, 64 + 4, 64 + 4);
7382 ok(color
== 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color
);
7383 color
= getPixelColor(device
, 64 + 4, 64 - 4);
7384 ok(color
== 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color
);
7385 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
7387 U(matrix
).m
[0][0] = 1.0f
/ 64.0f
;
7388 U(matrix
).m
[1][1] = -1.0f
/ 64.0f
;
7389 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &matrix
);
7390 ok(SUCCEEDED(hr
), "Failed to set projection matrix, hr %#x.\n", hr
);
7392 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
7393 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
7394 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
7395 ok(SUCCEEDED(hr
), "Failed to get depth / stencil buffer, hr %#x.\n", hr
);
7397 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 128, 128, D3DFMT_A8R8G8B8
,
7398 D3DMULTISAMPLE_NONE
, TRUE
, &rt
);
7399 ok(SUCCEEDED(hr
), "Failed to create a render target, hr %#x.\n", hr
);
7401 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSCALE_A
, *(DWORD
*)&a
);
7402 ok(SUCCEEDED(hr
), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr
);
7403 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSCALE_B
, *(DWORD
*)&b
);
7404 ok(SUCCEEDED(hr
), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr
);
7405 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSCALE_C
, *(DWORD
*)&c
);
7406 ok(SUCCEEDED(hr
), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr
);
7407 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, &S(U(matrix
))._11
, 4);
7408 ok(SUCCEEDED(hr
), "Failed to set vertex shader constants, hr %#x.\n", hr
);
7410 if (caps
.MaxPointSize
< 63.0f
)
7412 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps
.MaxPointSize
);
7416 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, depthstencil
);
7417 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
7419 for (i
= 0; i
< ARRAY_SIZE(test_setups
); ++i
)
7421 if (caps
.VertexShaderVersion
< test_setups
[i
].vs
->version
7422 || caps
.PixelShaderVersion
< test_setups
[i
].ps
->version
)
7424 skip("Vertex / pixel shader version not supported, skipping test.\n");
7427 if (test_setups
[i
].vs
->code
)
7429 hr
= IDirect3DDevice8_CreateVertexShader(device
, test_setups
[i
].decl
, test_setups
[i
].vs
->code
, &vs
, 0);
7430 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x (case %u).\n", hr
, i
);
7436 if (test_setups
[i
].ps
->code
)
7438 hr
= IDirect3DDevice8_CreatePixelShader(device
, test_setups
[i
].ps
->code
, &ps
);
7439 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x (case %u).\n", hr
, i
);
7446 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
? vs
: test_setups
[i
].accepted_fvf
);
7447 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
7448 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
7449 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
7451 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
7453 unsigned int size
= tests
[j
].override_min
? 63 : tests
[j
].zero_size
? 0 : tests
[j
].scale
7454 ? test_setups
[i
].scaled_size
: test_setups
[i
].nonscaled_size
;
7456 if (test_setups
[i
].accepted_fvf
!= tests
[j
].fvf
)
7459 ptsize
= tests
[j
].zero_size
? 0.0f
: 32.0f
;
7460 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, *(DWORD
*)&ptsize
);
7461 ok(SUCCEEDED(hr
), "Failed to set pointsize, hr %#x.\n", hr
);
7463 ptsize
= tests
[j
].override_min
? 63.0f
: tests
[j
].zero_size
? 0.0f
: ptsizemin_orig
;
7464 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE_MIN
, *(DWORD
*)&ptsize
);
7465 ok(SUCCEEDED(hr
), "Failed to set minimum pointsize, hr %#x.\n", hr
);
7467 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSCALEENABLE
, tests
[j
].scale
);
7468 ok(SUCCEEDED(hr
), "Failed setting point scale state, hr %#x.\n", hr
);
7470 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
7471 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7473 hr
= IDirect3DDevice8_BeginScene(device
);
7474 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7475 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1,
7476 tests
[j
].vertex_data
, tests
[j
].vertex_size
);
7477 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7478 hr
= IDirect3DDevice8_EndScene(device
);
7479 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7481 if (tests
[j
].zero_size
)
7483 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7484 * it does the "useful" thing on all the drivers I tried. */
7485 /* On WARP it does draw some pixels, most of the time. */
7486 color
= getPixelColor(device
, 64, 64);
7487 ok(color_match(color
, 0x0000ffff, 0)
7488 || broken(color_match(color
, 0x00ff0000, 0))
7489 || broken(color_match(color
, 0x00ffff00, 0))
7490 || broken(color_match(color
, 0x00000000, 0))
7491 || broken(color_match(color
, 0x0000ff00, 0)),
7492 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7496 struct surface_readback rb
;
7498 get_rt_readback(rt
, &rb
);
7499 color
= get_readback_color(&rb
, 64 - size
/ 2 + 1, 64 - size
/ 2 + 1);
7500 ok(color_match(color
, 0x00ff0000, 0),
7501 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7502 color
= get_readback_color(&rb
, 64 + size
/ 2 - 1, 64 - size
/ 2 + 1);
7503 ok(color_match(color
, 0x00ffff00, 0),
7504 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7505 color
= get_readback_color(&rb
, 64 - size
/ 2 + 1, 64 + size
/ 2 - 1);
7506 ok(color_match(color
, 0x00000000, 0),
7507 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7508 color
= get_readback_color(&rb
, 64 + size
/ 2 - 1, 64 + size
/ 2 - 1);
7509 ok(color_match(color
, 0x0000ff00, 0),
7510 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7512 color
= get_readback_color(&rb
, 64 - size
/ 2 - 1, 64 - size
/ 2 - 1);
7513 ok(color_match(color
, 0xff00ffff, 0),
7514 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7515 color
= get_readback_color(&rb
, 64 + size
/ 2 + 1, 64 - size
/ 2 - 1);
7516 ok(color_match(color
, 0xff00ffff, 0),
7517 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7518 color
= get_readback_color(&rb
, 64 - size
/ 2 - 1, 64 + size
/ 2 + 1);
7519 ok(color_match(color
, 0xff00ffff, 0),
7520 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7521 color
= get_readback_color(&rb
, 64 + size
/ 2 + 1, 64 + size
/ 2 + 1);
7522 ok(color_match(color
, 0xff00ffff, 0),
7523 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color
, i
, j
, size
);
7525 release_surface_readback(&rb
);
7528 IDirect3DDevice8_SetVertexShader(device
, 0);
7529 IDirect3DDevice8_SetPixelShader(device
, 0);
7531 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
7533 IDirect3DDevice8_DeletePixelShader(device
, ps
);
7535 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
7536 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
7539 IDirect3DSurface8_Release(backbuffer
);
7540 IDirect3DSurface8_Release(depthstencil
);
7541 IDirect3DSurface8_Release(rt
);
7543 IDirect3DTexture8_Release(tex1
);
7544 IDirect3DTexture8_Release(tex2
);
7545 refcount
= IDirect3DDevice8_Release(device
);
7546 ok(!refcount
, "Device has %u references left.\n", refcount
);
7548 IDirect3D8_Release(d3d
);
7549 DestroyWindow(window
);
7552 static void test_multisample_mismatch(void)
7554 IDirect3DDevice8
*device
;
7559 IDirect3DSurface8
*rt_multi
, *ds
;
7561 window
= create_window();
7562 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
7563 ok(!!d3d
, "Failed to create a D3D object.\n");
7564 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
7565 D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
7567 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7568 IDirect3D8_Release(d3d
);
7572 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
7574 skip("Failed to create a D3D device, skipping tests.\n");
7578 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
7579 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt_multi
);
7580 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
7581 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &ds
);
7582 ok(SUCCEEDED(hr
), "Failed to get original depth/stencil, hr %#x.\n", hr
);
7584 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt_multi
, ds
);
7585 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
7587 IDirect3DSurface8_Release(ds
);
7588 IDirect3DSurface8_Release(rt_multi
);
7590 refcount
= IDirect3DDevice8_Release(device
);
7591 ok(!refcount
, "Device has %u references left.\n", refcount
);
7593 IDirect3D8_Release(d3d
);
7594 DestroyWindow(window
);
7597 static void test_texcoordindex(void)
7599 static const D3DMATRIX mat
=
7601 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7602 0.0f
, 0.0f
, 0.0f
, 0.0f
,
7603 0.0f
, 0.0f
, 0.0f
, 0.0f
,
7604 0.0f
, 0.0f
, 0.0f
, 0.0f
,
7609 struct vec2 texcoord1
;
7610 struct vec2 texcoord2
;
7611 struct vec2 texcoord3
;
7615 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
7616 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
7617 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
7618 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
7620 IDirect3DDevice8
*device
;
7624 IDirect3DTexture8
*texture1
, *texture2
;
7625 D3DLOCKED_RECT locked_rect
;
7630 window
= create_window();
7631 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
7632 ok(!!d3d
, "Failed to create a D3D object.\n");
7633 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
7635 skip("Failed to create a D3D device, skipping tests.\n");
7636 IDirect3D8_Release(d3d
);
7637 DestroyWindow(window
);
7641 hr
= IDirect3DDevice8_CreateTexture(device
, 2, 2, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture1
);
7642 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
7643 hr
= IDirect3DDevice8_CreateTexture(device
, 2, 2, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture2
);
7644 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
7646 hr
= IDirect3DTexture8_LockRect(texture1
, 0, &locked_rect
, NULL
, D3DLOCK_DISCARD
);
7647 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
7648 ptr
= locked_rect
.pBits
;
7649 ptr
[0] = 0xff000000;
7650 ptr
[1] = 0xff00ff00;
7651 ptr
[2] = 0xff0000ff;
7652 ptr
[3] = 0xff00ffff;
7653 hr
= IDirect3DTexture8_UnlockRect(texture1
, 0);
7654 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
7656 hr
= IDirect3DTexture8_LockRect(texture2
, 0, &locked_rect
, NULL
, D3DLOCK_DISCARD
);
7657 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
7658 ptr
= locked_rect
.pBits
;
7659 ptr
[0] = 0xff000000;
7660 ptr
[1] = 0xff0000ff;
7661 ptr
[2] = 0xffff0000;
7662 ptr
[3] = 0xffff00ff;
7663 hr
= IDirect3DTexture8_UnlockRect(texture2
, 0);
7664 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
7666 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture1
);
7667 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
7668 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture2
);
7669 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
7670 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX3
);
7671 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
7672 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
7673 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7674 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
7675 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
7676 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
7677 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
7678 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
7679 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
7680 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
7681 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
7682 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
7683 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
7684 hr
= IDirect3DDevice8_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
7685 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
7687 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
7688 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
7689 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
7690 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
7692 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
7693 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7695 hr
= IDirect3DDevice8_BeginScene(device
);
7696 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7697 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
7698 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7699 hr
= IDirect3DDevice8_EndScene(device
);
7700 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7702 color
= getPixelColor(device
, 160, 120);
7703 ok(color_match(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
7704 color
= getPixelColor(device
, 480, 120);
7705 ok(color_match(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
7706 color
= getPixelColor(device
, 160, 360);
7707 ok(color_match(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
7708 color
= getPixelColor(device
, 480, 360);
7709 ok(color_match(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
7711 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT2
);
7712 ok(SUCCEEDED(hr
), "Failed to set texture transform flags, hr %#x.\n", hr
);
7713 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_TEXTURE1
, &mat
);
7714 ok(SUCCEEDED(hr
), "Failed to set transformation matrix, hr %#x.\n", hr
);
7716 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
7717 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7719 hr
= IDirect3DDevice8_BeginScene(device
);
7720 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7721 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
7722 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7723 hr
= IDirect3DDevice8_EndScene(device
);
7724 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7726 color
= getPixelColor(device
, 160, 120);
7727 ok(color_match(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
7728 color
= getPixelColor(device
, 480, 120);
7729 ok(color_match(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
7730 color
= getPixelColor(device
, 160, 360);
7731 ok(color_match(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
7732 color
= getPixelColor(device
, 480, 360);
7733 ok(color_match(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
7735 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_DISABLE
);
7736 ok(SUCCEEDED(hr
), "Failed to set texture transform flags, hr %#x.\n", hr
);
7737 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
7738 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
7740 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
7741 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7743 hr
= IDirect3DDevice8_BeginScene(device
);
7744 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7745 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
7746 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7747 hr
= IDirect3DDevice8_EndScene(device
);
7748 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7750 color
= getPixelColor(device
, 160, 120);
7751 ok(color_match(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
7752 color
= getPixelColor(device
, 480, 120);
7753 ok(color_match(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
7754 color
= getPixelColor(device
, 160, 360);
7755 ok(color_match(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
7756 color
= getPixelColor(device
, 480, 360);
7757 ok(color_match(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
7759 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
7760 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
7762 IDirect3DTexture8_Release(texture1
);
7763 IDirect3DTexture8_Release(texture2
);
7765 refcount
= IDirect3DDevice8_Release(device
);
7766 ok(!refcount
, "Device has %u references left.\n", refcount
);
7767 IDirect3D8_Release(d3d
);
7768 DestroyWindow(window
);
7771 static void test_vshader_input(void)
7773 DWORD swapped_twotexcrd_shader
, swapped_onetexcrd_shader
= 0;
7774 DWORD swapped_twotex_wrongidx_shader
= 0, swapped_twotexcrd_rightorder_shader
;
7775 DWORD texcoord_color_shader
, color_ubyte_shader
, color_color_shader
, color_float_shader
;
7776 DWORD color_nocolor_shader
= 0;
7777 IDirect3DDevice8
*device
;
7785 static const DWORD swapped_shader_code
[] =
7787 0xfffe0101, /* vs_1_1 */
7788 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7789 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7790 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7791 0x0000ffff /* end */
7793 static const DWORD texcoord_color_shader_code
[] =
7795 0xfffe0101, /* vs_1_1 */
7796 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7797 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7798 0x0000ffff /* end */
7800 static const DWORD color_color_shader_code
[] =
7802 0xfffe0101, /* vs_1_1 */
7803 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7804 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7805 0x0000ffff /* end */
7807 static const float quad1
[] =
7809 -1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7810 -1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7811 0.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7812 0.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7814 static const float quad4
[] =
7816 0.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7817 0.0f
, 1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7818 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7819 1.0f
, 1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, -1.0f
, 0.5f
, 0.0f
,
7823 struct vec3 position
;
7828 {{-1.0f
, -1.0f
, 0.1f
}, 0x00ff8040},
7829 {{-1.0f
, 0.0f
, 0.1f
}, 0x00ff8040},
7830 {{ 0.0f
, -1.0f
, 0.1f
}, 0x00ff8040},
7831 {{ 0.0f
, 0.0f
, 0.1f
}, 0x00ff8040},
7835 {{ 0.0f
, -1.0f
, 0.1f
}, 0x00ff8040},
7836 {{ 0.0f
, 0.0f
, 0.1f
}, 0x00ff8040},
7837 {{ 1.0f
, -1.0f
, 0.1f
}, 0x00ff8040},
7838 {{ 1.0f
, 0.0f
, 0.1f
}, 0x00ff8040},
7842 struct vec3 position
;
7843 struct vec3 dummy
; /* testing D3DVSD_SKIP */
7848 {{-1.0f
, 0.0f
, 0.1f
}, {0.0f
}, 0x00ff8040},
7849 {{-1.0f
, 1.0f
, 0.1f
}, {0.0f
}, 0x00ff8040},
7850 {{ 0.0f
, 0.0f
, 0.1f
}, {0.0f
}, 0x00ff8040},
7851 {{ 0.0f
, 1.0f
, 0.1f
}, {0.0f
}, 0x00ff8040},
7853 static const float quad4_color
[] =
7855 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
,
7856 0.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
,
7857 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
,
7858 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
,
7860 static const DWORD decl_twotexcrd
[] =
7863 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7864 D3DVSD_REG(1, D3DVSDT_FLOAT4
), /* texcoord0 */
7865 D3DVSD_REG(2, D3DVSDT_FLOAT4
), /* texcoord1 */
7868 static const DWORD decl_twotexcrd_rightorder
[] =
7871 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7872 D3DVSD_REG(2, D3DVSDT_FLOAT4
), /* texcoord0 */
7873 D3DVSD_REG(1, D3DVSDT_FLOAT4
), /* texcoord1 */
7876 static const DWORD decl_onetexcrd
[] =
7879 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7880 D3DVSD_REG(1, D3DVSDT_FLOAT4
), /* texcoord0 */
7883 static const DWORD decl_twotexcrd_wrongidx
[] =
7886 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7887 D3DVSD_REG(2, D3DVSDT_FLOAT4
), /* texcoord1 */
7888 D3DVSD_REG(3, D3DVSDT_FLOAT4
), /* texcoord2 */
7891 static const DWORD decl_texcoord_color
[] =
7894 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7895 D3DVSD_REG(7, D3DVSDT_D3DCOLOR
), /* texcoord0 */
7898 static const DWORD decl_color_color
[] =
7901 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position */
7902 D3DVSD_SKIP(3), /* not used */
7903 D3DVSD_REG(5, D3DVSDT_D3DCOLOR
), /* diffuse */
7906 static const DWORD decl_color_ubyte
[] =
7909 D3DVSD_REG(0, D3DVSDT_FLOAT3
),
7910 D3DVSD_REG(5, D3DVSDT_UBYTE4
),
7913 static const DWORD decl_color_float
[] =
7916 D3DVSD_REG(0, D3DVSDT_FLOAT3
),
7917 D3DVSD_REG(5, D3DVSDT_FLOAT4
),
7920 static const DWORD decl_nocolor
[] =
7923 D3DVSD_REG(0, D3DVSDT_FLOAT3
),
7926 static const float normalize
[4] = {1.0f
/ 256.0f
, 1.0f
/ 256.0f
, 1.0f
/ 256.0f
, 1.0f
/ 256.0f
};
7927 static const float no_normalize
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
7929 window
= create_window();
7930 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
7931 ok(!!d3d
, "Failed to create a D3D object.\n");
7932 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
7934 skip("Failed to create a D3D device, skipping tests.\n");
7938 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
7939 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
7940 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
7942 skip("No vs_1_1 support, skipping tests.\n");
7943 IDirect3DDevice8_Release(device
);
7947 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_twotexcrd
, swapped_shader_code
, &swapped_twotexcrd_shader
, 0);
7948 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
7949 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_onetexcrd
, swapped_shader_code
, &swapped_onetexcrd_shader
, 0);
7950 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Unexpected error while creating vertex shader, hr %#x.\n", hr
);
7951 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_twotexcrd_wrongidx
, swapped_shader_code
, &swapped_twotex_wrongidx_shader
, 0);
7952 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Unexpected error while creating vertex shader, hr %#x.\n", hr
);
7953 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_twotexcrd_rightorder
, swapped_shader_code
, &swapped_twotexcrd_rightorder_shader
, 0);
7954 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
7956 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_texcoord_color
, texcoord_color_shader_code
, &texcoord_color_shader
, 0);
7957 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
7958 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_color_ubyte
, color_color_shader_code
, &color_ubyte_shader
, 0);
7959 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
7960 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_color_color
, color_color_shader_code
, &color_color_shader
, 0);
7961 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
7962 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_color_float
, color_color_shader_code
, &color_float_shader
, 0);
7963 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
7964 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_nocolor
, color_color_shader_code
, &color_nocolor_shader
, 0);
7965 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Unexpected error while creating vertex shader, hr %#x.\n", hr
);
7967 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
7968 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7970 hr
= IDirect3DDevice8_BeginScene(device
);
7971 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7973 hr
= IDirect3DDevice8_SetVertexShader(device
, swapped_twotexcrd_shader
);
7974 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
7976 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(float) * 11);
7977 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7979 hr
= IDirect3DDevice8_SetVertexShader(device
, swapped_twotexcrd_rightorder_shader
);
7980 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
7981 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(float) * 11);
7982 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7984 hr
= IDirect3DDevice8_EndScene(device
);
7985 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7987 color
= getPixelColor(device
, 160, 360);
7988 ok(color_match(color
, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color
);
7989 color
= getPixelColor(device
, 480, 160);
7990 ok(color
== 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color
);
7992 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
7993 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
7995 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
7996 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
7998 hr
= IDirect3DDevice8_BeginScene(device
);
7999 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8001 hr
= IDirect3DDevice8_SetVertexShader(device
, texcoord_color_shader
);
8002 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
8003 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1_color
, sizeof(quad1_color
[0]));
8004 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8006 hr
= IDirect3DDevice8_SetVertexShader(device
, color_ubyte_shader
);
8007 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
8009 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, normalize
, 1);
8010 ok(SUCCEEDED(hr
), "Failed to set vertex shader constant, hr %#x.\n", hr
);
8011 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2_color
, sizeof(quad2_color
[0]));
8012 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8014 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, no_normalize
, 1);
8015 ok(SUCCEEDED(hr
), "Failed to set vertex shader constant, hr %#x.\n", hr
);
8016 hr
= IDirect3DDevice8_SetVertexShader(device
, color_color_shader
);
8017 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
8018 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3_color
, sizeof(quad3_color
[0]));
8019 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8021 hr
= IDirect3DDevice8_SetVertexShader(device
, color_float_shader
);
8022 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
8023 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4_color
, sizeof(float) * 7);
8024 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8026 hr
= IDirect3DDevice8_EndScene(device
);
8027 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8029 IDirect3DDevice8_SetVertexShader(device
, 0);
8031 color
= getPixelColor(device
, 160, 360);
8032 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8033 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color
);
8034 color
= getPixelColor(device
, 480, 360);
8035 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8036 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color
);
8037 color
= getPixelColor(device
, 160, 120);
8038 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8039 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color
);
8040 color
= getPixelColor(device
, 480, 160);
8041 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8042 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color
);
8044 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8045 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
8047 IDirect3DDevice8_DeleteVertexShader(device
, swapped_twotexcrd_shader
);
8048 IDirect3DDevice8_DeleteVertexShader(device
, swapped_onetexcrd_shader
);
8049 IDirect3DDevice8_DeleteVertexShader(device
, swapped_twotex_wrongidx_shader
);
8050 IDirect3DDevice8_DeleteVertexShader(device
, swapped_twotexcrd_rightorder_shader
);
8051 IDirect3DDevice8_DeleteVertexShader(device
, texcoord_color_shader
);
8052 IDirect3DDevice8_DeleteVertexShader(device
, color_ubyte_shader
);
8053 IDirect3DDevice8_DeleteVertexShader(device
, color_color_shader
);
8054 IDirect3DDevice8_DeleteVertexShader(device
, color_float_shader
);
8055 IDirect3DDevice8_DeleteVertexShader(device
, color_nocolor_shader
);
8057 refcount
= IDirect3DDevice8_Release(device
);
8058 ok(!refcount
, "Device has %u references left.\n", refcount
);
8060 IDirect3D8_Release(d3d
);
8061 DestroyWindow(window
);
8064 static void test_fixed_function_fvf(void)
8066 IDirect3DDevice8
*device
;
8076 struct vec3 position
;
8081 {{-1.0f
, -1.0f
, 0.1f
}, 0x00ffff00},
8082 {{-1.0f
, 0.0f
, 0.1f
}, 0x00ffff00},
8083 {{ 0.0f
, -1.0f
, 0.1f
}, 0x00ffff00},
8084 {{ 0.0f
, 0.0f
, 0.1f
}, 0x00ffff00},
8086 static const struct vec3 quad2
[] =
8088 {-1.0f
, -1.0f
, 0.1f
},
8089 {-1.0f
, 0.0f
, 0.1f
},
8090 { 0.0f
, -1.0f
, 0.1f
},
8091 { 0.0f
, 0.0f
, 0.1f
},
8095 struct vec4 position
;
8098 quad_transformed
[] =
8100 {{ 90.0f
, 110.0f
, 0.1f
, 2.0f
}, 0x00ffff00},
8101 {{570.0f
, 110.0f
, 0.1f
, 2.0f
}, 0x00ffff00},
8102 {{ 90.0f
, 300.0f
, 0.1f
, 2.0f
}, 0x00ffff00},
8103 {{570.0f
, 300.0f
, 0.1f
, 2.0f
}, 0x00ffff00},
8106 window
= create_window();
8107 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8108 ok(!!d3d
, "Failed to create a D3D object.\n");
8109 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
8111 skip("Failed to create a D3D device, skipping tests.\n");
8115 memset(&caps
, 0, sizeof(caps
));
8116 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
8117 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
8119 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 1.0f
, 0);
8120 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
8122 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
8123 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
8125 hr
= IDirect3DDevice8_BeginScene(device
);
8126 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8128 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
8129 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
8130 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
8131 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8133 hr
= IDirect3DDevice8_EndScene(device
);
8134 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8136 color
= getPixelColor(device
, 160, 360);
8137 ok(color
== 0x00ffff00,
8138 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color
);
8139 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8141 /* Test with no diffuse color attribute. */
8142 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0, 0);
8143 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %08x\n", hr
);
8145 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
8146 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
8147 hr
= IDirect3DDevice8_BeginScene(device
);
8148 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8149 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad2
, sizeof(quad2
[0]));
8150 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8151 hr
= IDirect3DDevice8_EndScene(device
);
8152 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8154 color
= getPixelColor(device
, 160, 360);
8155 ok(color
== 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color
);
8156 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8158 /* Test what happens with specular lighting enabled and no specular color attribute. */
8159 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 1.0f
, 0);
8160 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
8161 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SPECULARENABLE
, TRUE
);
8162 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
8163 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
8164 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
8165 hr
= IDirect3DDevice8_BeginScene(device
);
8166 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8168 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad1
, sizeof(quad1
[0]));
8169 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8171 hr
= IDirect3DDevice8_EndScene(device
);
8172 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8173 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SPECULARENABLE
, FALSE
);
8174 ok(SUCCEEDED(hr
), "Failed to disable specular lighting, hr %#x.\n", hr
);
8176 color
= getPixelColor(device
, 160, 360);
8177 ok(color
== 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color
);
8179 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8181 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
8182 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
8184 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0, 0);
8185 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
8187 hr
= IDirect3DDevice8_BeginScene(device
);
8188 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8189 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad_transformed
, sizeof(quad_transformed
[0]));
8190 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8191 hr
= IDirect3DDevice8_EndScene(device
);
8192 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8194 color
= getPixelColor(device
, 88, 108);
8195 ok(color
== 0x000000ff,
8196 "pixel 88/108 has color %08x, expected 0x000000ff\n", color
);
8197 color
= getPixelColor(device
, 92, 108);
8198 ok(color
== 0x000000ff,
8199 "pixel 92/108 has color %08x, expected 0x000000ff\n", color
);
8200 color
= getPixelColor(device
, 88, 112);
8201 ok(color
== 0x000000ff,
8202 "pixel 88/112 has color %08x, expected 0x000000ff\n", color
);
8203 color
= getPixelColor(device
, 92, 112);
8204 ok(color
== 0x00ffff00,
8205 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color
);
8207 color
= getPixelColor(device
, 568, 108);
8208 ok(color
== 0x000000ff,
8209 "pixel 568/108 has color %08x, expected 0x000000ff\n", color
);
8210 color
= getPixelColor(device
, 572, 108);
8211 ok(color
== 0x000000ff,
8212 "pixel 572/108 has color %08x, expected 0x000000ff\n", color
);
8213 color
= getPixelColor(device
, 568, 112);
8214 ok(color
== 0x00ffff00,
8215 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color
);
8216 color
= getPixelColor(device
, 572, 112);
8217 ok(color
== 0x000000ff,
8218 "pixel 572/112 has color %08x, expected 0x000000ff\n", color
);
8220 color
= getPixelColor(device
, 88, 298);
8221 ok(color
== 0x000000ff,
8222 "pixel 88/298 has color %08x, expected 0x000000ff\n", color
);
8223 color
= getPixelColor(device
, 92, 298);
8224 ok(color
== 0x00ffff00,
8225 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color
);
8226 color
= getPixelColor(device
, 88, 302);
8227 ok(color
== 0x000000ff,
8228 "pixel 88/302 has color %08x, expected 0x000000ff\n", color
);
8229 color
= getPixelColor(device
, 92, 302);
8230 ok(color
== 0x000000ff,
8231 "pixel 92/302 has color %08x, expected 0x000000ff\n", color
);
8233 color
= getPixelColor(device
, 568, 298);
8234 ok(color
== 0x00ffff00,
8235 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color
);
8236 color
= getPixelColor(device
, 572, 298);
8237 ok(color
== 0x000000ff,
8238 "pixel 572/298 has color %08x, expected 0x000000ff\n", color
);
8239 color
= getPixelColor(device
, 568, 302);
8240 ok(color
== 0x000000ff,
8241 "pixel 568/302 has color %08x, expected 0x000000ff\n", color
);
8242 color
= getPixelColor(device
, 572, 302);
8243 ok(color
== 0x000000ff,
8244 "pixel 572/302 has color %08x, expected 0x000000ff\n", color
);
8246 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8248 refcount
= IDirect3DDevice8_Release(device
);
8249 ok(!refcount
, "Device has %u references left.\n", refcount
);
8251 IDirect3D8_Release(d3d
);
8252 DestroyWindow(window
);
8255 static void test_flip(void)
8257 IDirect3DDevice8
*device
;
8262 IDirect3DSurface8
*back_buffers
[3], *test_surface
;
8265 D3DPRESENT_PARAMETERS present_parameters
= {0};
8267 window
= create_window();
8268 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8269 ok(!!d3d
, "Failed to create a D3D object.\n");
8271 present_parameters
.BackBufferWidth
= 640;
8272 present_parameters
.BackBufferHeight
= 480;
8273 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
8274 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
8275 present_parameters
.hDeviceWindow
= window
;
8276 present_parameters
.Windowed
= TRUE
;
8277 present_parameters
.BackBufferCount
= 3;
8278 present_parameters
.Flags
= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER
;
8279 if (FAILED(hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
8280 window
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
)))
8282 skip("Failed to create a D3D device, skipping tests.\n");
8283 IDirect3D8_Release(d3d
);
8284 DestroyWindow(window
);
8288 for (i
= 0; i
< ARRAY_SIZE(back_buffers
); ++i
)
8290 hr
= IDirect3DDevice8_GetBackBuffer(device
, i
, D3DBACKBUFFER_TYPE_MONO
, &back_buffers
[i
]);
8291 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
8293 hr
= IDirect3DDevice8_GetRenderTarget(device
, &test_surface
);
8294 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8295 ok(test_surface
== back_buffers
[0], "Expected render target %p, got %p.\n", back_buffers
[0], test_surface
);
8296 IDirect3DSurface8_Release(test_surface
);
8299 hr
= IDirect3DDevice8_SetRenderTarget(device
, back_buffers
[0], NULL
);
8300 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
8301 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
8302 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x\n", hr
);
8304 hr
= IDirect3DDevice8_SetRenderTarget(device
, back_buffers
[1], NULL
);
8305 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
8306 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
8307 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x\n", hr
);
8309 hr
= IDirect3DDevice8_SetRenderTarget(device
, back_buffers
[2], NULL
);
8310 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
8311 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
8312 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x\n", hr
);
8314 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8315 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
8317 /* Render target is unmodified. */
8318 hr
= IDirect3DDevice8_GetRenderTarget(device
, &test_surface
);
8319 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8320 ok(test_surface
== back_buffers
[2], "Expected render target %p, got %p.\n", back_buffers
[2], test_surface
);
8321 IDirect3DSurface8_Release(test_surface
);
8323 /* Backbuffer surface pointers are unmodified */
8324 for (i
= 0; i
< ARRAY_SIZE(back_buffers
); ++i
)
8326 hr
= IDirect3DDevice8_GetBackBuffer(device
, i
, D3DBACKBUFFER_TYPE_MONO
, &test_surface
);
8327 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
8328 ok(test_surface
== back_buffers
[i
], "Expected back buffer %u = %p, got %p.\n",
8329 i
, back_buffers
[i
], test_surface
);
8330 IDirect3DSurface8_Release(test_surface
);
8333 /* Contents were changed. */
8334 color
= get_surface_color(back_buffers
[0], 1, 1);
8335 ok(color
== 0xff00ff00, "Got unexpected color 0x%08x.\n", color
);
8336 color
= get_surface_color(back_buffers
[1], 1, 1);
8337 ok(color
== 0xff0000ff, "Got unexpected color 0x%08x.\n", color
);
8339 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff808080, 0.0f
, 0);
8340 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x\n", hr
);
8342 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8343 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
8345 color
= get_surface_color(back_buffers
[0], 1, 1);
8346 ok(color
== 0xff0000ff, "Got unexpected color 0x%08x.\n", color
);
8347 color
= get_surface_color(back_buffers
[1], 1, 1);
8348 ok(color
== 0xff808080, "Got unexpected color 0x%08x.\n", color
);
8350 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8351 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
8353 color
= get_surface_color(back_buffers
[0], 1, 1);
8354 ok(color
== 0xff808080, "Got unexpected color 0x%08x.\n", color
);
8356 for (i
= 0; i
< ARRAY_SIZE(back_buffers
); ++i
)
8357 IDirect3DSurface8_Release(back_buffers
[i
]);
8359 refcount
= IDirect3DDevice8_Release(device
);
8360 ok(!refcount
, "Device has %u references left.\n", refcount
);
8362 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
8363 D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
8365 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8369 present_parameters
.BackBufferCount
= 2;
8370 present_parameters
.MultiSampleType
= D3DMULTISAMPLE_2_SAMPLES
;
8371 present_parameters
.Flags
= 0;
8372 hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
8373 window
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
8375 for (i
= 0; i
< present_parameters
.BackBufferCount
; ++i
)
8377 hr
= IDirect3DDevice8_GetBackBuffer(device
, i
, D3DBACKBUFFER_TYPE_MONO
, &back_buffers
[i
]);
8378 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
8381 hr
= IDirect3DDevice8_SetRenderTarget(device
, back_buffers
[1], NULL
);
8382 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
8383 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff808080, 0.0f
, 0);
8384 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
8386 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8387 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
8389 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
8390 D3DMULTISAMPLE_NONE
, TRUE
, &test_surface
);
8391 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8392 hr
= IDirect3DDevice8_CopyRects(device
, back_buffers
[0], NULL
, 0, test_surface
, NULL
);
8393 ok(SUCCEEDED(hr
), "CopyRects failed, hr %#x.\n", hr
);
8395 color
= get_surface_color(test_surface
, 1, 1);
8396 ok(color
== 0xff808080, "Got unexpected color 0x%08x.\n", color
);
8398 IDirect3DSurface8_Release(test_surface
);
8399 for (i
= 0; i
< present_parameters
.BackBufferCount
; ++i
)
8400 IDirect3DSurface8_Release(back_buffers
[i
]);
8402 refcount
= IDirect3DDevice8_Release(device
);
8403 ok(!refcount
, "Device has %u references left.\n", refcount
);
8406 IDirect3D8_Release(d3d
);
8407 DestroyWindow(window
);
8410 static void test_uninitialized_varyings(void)
8412 static const D3DMATRIX mat
=
8414 1.0f
, 0.0f
, 0.0f
, 0.0f
,
8415 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8416 0.0f
, 0.0f
, 1.0f
, 0.0f
,
8417 0.0f
, 0.0f
, 0.0f
, 1.0f
,
8419 static const struct vec3 quad
[] =
8421 {-1.0f
, -1.0f
, 0.1f
},
8422 {-1.0f
, 1.0f
, 0.1f
},
8423 { 1.0f
, -1.0f
, 0.1f
},
8424 { 1.0f
, 1.0f
, 0.1f
},
8426 static const DWORD decl
[] =
8429 D3DVSD_REG(0, D3DVSDT_FLOAT3
),
8430 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8433 static const DWORD vs1_code
[] =
8435 0xfffe0101, /* vs_1_1 */
8436 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8439 static const DWORD vs1_partial_code
[] =
8441 0xfffe0101, /* vs_1_1 */
8442 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8443 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8444 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8445 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8448 static const DWORD ps1_diffuse_code
[] =
8450 0xffff0101, /* ps_1_1 */
8451 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8454 static const DWORD ps1_specular_code
[] =
8456 0xffff0101, /* ps_1_1 */
8457 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8460 static const DWORD ps1_texcoord_code
[] =
8462 0xffff0101, /* ps_1_1 */
8463 0x00000040, 0xb00f0000, /* texcoord t0 */
8464 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8474 BOOL allow_zero_alpha
;
8478 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8479 * while on Nvidia it's the opposite. Just allow both.
8481 * Partially initialized varyings reliably handle the component that has been initialized.
8482 * The uninitialized components generally follow the rule above, with some exceptions on
8483 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
8484 * 0.5 and 1.0 without a sensible pattern. */
8487 {D3DVS_VERSION(1, 1), vs1_code
, 0, NULL
, 0xffffffff},
8488 { 0, NULL
, D3DPS_VERSION(1, 1), ps1_texcoord_code
, 0xff000000, TRUE
},
8489 {D3DVS_VERSION(1, 1), vs1_code
, D3DPS_VERSION(1, 1), ps1_diffuse_code
, 0xffffffff},
8490 {D3DVS_VERSION(1, 1), vs1_code
, D3DPS_VERSION(1, 1), ps1_specular_code
, 0xff000000, TRUE
, FALSE
, TRUE
},
8491 {D3DVS_VERSION(1, 1), vs1_code
, D3DPS_VERSION(1, 1), ps1_texcoord_code
, 0xff000000, TRUE
},
8492 {D3DVS_VERSION(1, 1), vs1_partial_code
, 0, NULL
, 0xff7fffff, FALSE
, TRUE
},
8493 {D3DVS_VERSION(1, 1), vs1_partial_code
, D3DPS_VERSION(1, 1), ps1_diffuse_code
, 0xff7fffff, FALSE
, TRUE
},
8494 {D3DVS_VERSION(1, 1), vs1_partial_code
, D3DPS_VERSION(1, 1), ps1_specular_code
, 0xff7f0000, TRUE
, TRUE
},
8495 {D3DVS_VERSION(1, 1), vs1_partial_code
, D3DPS_VERSION(1, 1), ps1_texcoord_code
, 0xff7f0000, TRUE
, TRUE
},
8497 IDirect3DDevice8
*device
;
8505 IDirect3DSurface8
*backbuffer
;
8506 D3DADAPTER_IDENTIFIER8 identifier
;
8507 struct surface_readback rb
;
8511 window
= create_window();
8512 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8513 ok(!!d3d
, "Failed to create a D3D object.\n");
8514 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
8516 skip("Failed to create a D3D device, skipping tests.\n");
8517 IDirect3D8_Release(d3d
);
8518 DestroyWindow(window
);
8522 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
8523 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#x.\n", hr
);
8524 warp
= adapter_is_warp(&identifier
);
8526 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
8527 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8529 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
8530 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
8532 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLD
, &mat
);
8533 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
8534 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_VIEW
, &mat
);
8535 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
8536 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &mat
);
8537 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
8538 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
8539 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
8540 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
8541 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
8542 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
8543 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
8544 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_STENCILENABLE
, FALSE
);
8545 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
8546 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CULLMODE
, D3DCULL_NONE
);
8547 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
8549 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8551 if (caps
.VertexShaderVersion
< tests
[i
].vs_version
8552 || caps
.PixelShaderVersion
< tests
[i
].ps_version
)
8554 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i
);
8559 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, tests
[i
].vs
, &vs
, 0);
8560 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x (case %u).\n", hr
, i
);
8561 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
8562 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
8567 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
8568 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
8572 hr
= IDirect3DDevice8_CreatePixelShader(device
, tests
[i
].ps
, &ps
);
8573 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x (case %u).\n", hr
, i
);
8580 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
8581 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
8583 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
8584 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
8586 hr
= IDirect3DDevice8_BeginScene(device
);
8587 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8589 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
8590 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8592 hr
= IDirect3DDevice8_EndScene(device
);
8593 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8595 get_rt_readback(backbuffer
, &rb
);
8596 color
= get_readback_color(&rb
, 320, 240);
8597 ok(color_match(color
, tests
[i
].expected
, 1)
8598 || (tests
[i
].allow_zero_alpha
&& color_match(color
, tests
[i
].expected
& 0x00ffffff, 1))
8599 || (broken(warp
&& tests
[i
].broken_warp
))
8600 || broken(tests
[i
].partial
&& color_match(color
& 0x00ff0000, tests
[i
].expected
& 0x00ff0000, 1)),
8601 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
8602 release_surface_readback(&rb
);
8605 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
8607 IDirect3DDevice8_DeletePixelShader(device
, ps
);
8610 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8611 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
8613 IDirect3DSurface8_Release(backbuffer
);
8614 refcount
= IDirect3DDevice8_Release(device
);
8615 ok(!refcount
, "Device has %u references left.\n", refcount
);
8616 IDirect3D8_Release(d3d
);
8617 DestroyWindow(window
);
8620 static void test_shademode(void)
8622 IDirect3DVertexBuffer8
*vb_strip
;
8623 IDirect3DVertexBuffer8
*vb_list
;
8624 IDirect3DDevice8
*device
;
8625 DWORD color0
, color1
;
8634 static const DWORD decl
[] =
8637 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
8638 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
),
8641 static const DWORD vs1_code
[] =
8643 0xfffe0101, /* vs_1_1 */
8644 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8645 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8648 static const DWORD ps1_code
[] =
8650 0xffff0101, /* ps_1_1 */
8651 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8656 struct vec3 position
;
8661 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
8662 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
8663 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
8664 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
8668 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
8669 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
8670 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
8672 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
8673 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
8674 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
8676 static const struct test_shader
8682 vs_1
= {D3DVS_VERSION(1, 1), vs1_code
},
8684 ps_1
= {D3DPS_VERSION(1, 1), ps1_code
};
8687 const struct test_shader
*vs
, *ps
;
8690 DWORD color0
, color1
;
8694 {&novs
, &nops
, D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
8695 {&novs
, &nops
, D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
8696 {&novs
, &nops
, D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
8697 {&novs
, &nops
, D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
8698 {&novs
, &nops
, D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
8699 {&novs
, &nops
, D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
8700 {&vs_1
, &ps_1
, D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
8701 {&vs_1
, &ps_1
, D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
8702 {&vs_1
, &ps_1
, D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
8703 {&vs_1
, &ps_1
, D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
8704 {&novs
, &ps_1
, D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
8705 {&vs_1
, &nops
, D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
8708 window
= create_window();
8709 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8710 ok(!!d3d
, "Failed to create a D3D object.\n");
8711 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
8713 skip("Failed to create a D3D device, skipping tests.\n");
8714 IDirect3D8_Release(d3d
);
8715 DestroyWindow(window
);
8719 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
8720 ok(hr
== D3D_OK
, "Failed to disable lighting, hr %#x.\n", hr
);
8721 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
8722 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
8724 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad_strip
), 0, 0, D3DPOOL_MANAGED
, &vb_strip
);
8725 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
8726 hr
= IDirect3DVertexBuffer8_Lock(vb_strip
, 0, sizeof(quad_strip
), &data
, 0);
8727 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
8728 memcpy(data
, quad_strip
, sizeof(quad_strip
));
8729 hr
= IDirect3DVertexBuffer8_Unlock(vb_strip
);
8730 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8732 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad_list
), 0, 0, D3DPOOL_MANAGED
, &vb_list
);
8733 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
8734 hr
= IDirect3DVertexBuffer8_Lock(vb_list
, 0, sizeof(quad_list
), &data
, 0);
8735 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
8736 memcpy(data
, quad_list
, sizeof(quad_list
));
8737 hr
= IDirect3DVertexBuffer8_Unlock(vb_list
);
8738 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8740 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
8741 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
8743 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8744 * the color fixups we have to do for FLAT shading will be dependent on that. */
8746 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8748 if (tests
[i
].vs
->version
)
8750 if (caps
.VertexShaderVersion
>= tests
[i
].vs
->version
)
8752 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, tests
[i
].vs
->code
, &vs
, 0);
8753 ok(hr
== D3D_OK
, "Failed to create vertex shader, hr %#x.\n", hr
);
8754 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
8755 ok(hr
== D3D_OK
, "Failed to set vertex shader, hr %#x.\n", hr
);
8759 skip("Shader version unsupported, skipping some tests.\n");
8766 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
8767 ok(hr
== D3D_OK
, "Failed to set FVF, hr %#x.\n", hr
);
8769 if (tests
[i
].ps
->version
)
8771 if (caps
.PixelShaderVersion
>= tests
[i
].ps
->version
)
8773 hr
= IDirect3DDevice8_CreatePixelShader(device
, tests
[i
].ps
->code
, &ps
);
8774 ok(hr
== D3D_OK
, "Failed to create pixel shader, hr %#x.\n", hr
);
8775 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
8776 ok(hr
== D3D_OK
, "Failed to set pixel shader, hr %#x.\n", hr
);
8780 skip("Shader version unsupported, skipping some tests.\n");
8783 IDirect3DDevice8_SetVertexShader(device
, 0);
8784 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
8794 hr
= IDirect3DDevice8_SetStreamSource(device
, 0,
8795 tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
, sizeof(quad_strip
[0]));
8796 ok(hr
== D3D_OK
, "Failed to set stream source, hr %#x.\n", hr
);
8798 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
8799 ok(hr
== D3D_OK
, "Failed to clear, hr %#x.\n", hr
);
8801 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SHADEMODE
, tests
[i
].shademode
);
8802 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
8804 hr
= IDirect3DDevice8_BeginScene(device
);
8805 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8806 hr
= IDirect3DDevice8_DrawPrimitive(device
, tests
[i
].primtype
, 0, 2);
8807 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8808 hr
= IDirect3DDevice8_EndScene(device
);
8809 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8811 color0
= getPixelColor(device
, 100, 100); /* Inside first triangle */
8812 color1
= getPixelColor(device
, 500, 350); /* Inside second triangle */
8814 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8815 * each triangle. This requires EXT_provoking_vertex or similar
8816 * functionality being available. */
8817 /* PHONG should be the same as GOURAUD, since no hardware implements
8819 ok(color_match(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8820 i
, color0
, tests
[i
].color0
);
8821 ok(color_match(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8822 i
, color1
, tests
[i
].color1
);
8824 IDirect3DDevice8_SetVertexShader(device
, 0);
8825 IDirect3DDevice8_SetPixelShader(device
, 0);
8828 IDirect3DDevice8_DeletePixelShader(device
, ps
);
8830 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
8833 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8834 ok(hr
== D3D_OK
, "Failed to present, hr %#x.\n", hr
);
8836 IDirect3DVertexBuffer8_Release(vb_strip
);
8837 IDirect3DVertexBuffer8_Release(vb_list
);
8838 refcount
= IDirect3DDevice8_Release(device
);
8839 ok(!refcount
, "Device has %u references left.\n", refcount
);
8840 IDirect3D8_Release(d3d
);
8841 DestroyWindow(window
);
8844 static void test_multisample_init(void)
8846 IDirect3DDevice8
*device
;
8848 IDirect3DSurface8
*back
, *multi
;
8854 struct surface_readback rb
;
8855 BOOL all_zero
= TRUE
;
8857 window
= create_window();
8858 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8859 ok(!!d3d
, "Failed to create a D3D object.\n");
8861 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
8862 D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
8864 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8868 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
8870 skip("Failed to create a D3D device, skipping tests.\n");
8874 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &back
);
8875 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
8876 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
8877 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &multi
);
8878 ok(SUCCEEDED(hr
), "Failed to create multisampled render target, hr %#x.\n", hr
);
8880 hr
= IDirect3DDevice8_CopyRects(device
, multi
, NULL
, 0, back
, NULL
);
8881 ok(SUCCEEDED(hr
), "CopyRects failed, hr %#x.\n", hr
);
8883 get_rt_readback(back
, &rb
);
8884 for (y
= 0; y
< 480; ++y
)
8886 for (x
= 0; x
< 640; ++x
)
8888 color
= get_readback_color(&rb
, x
, y
);
8889 if (!color_match(color
, 0x00000000, 0))
8898 release_surface_readback(&rb
);
8899 ok(all_zero
, "Got unexpected color 0x%08x, position %ux%u.\n", color
, x
, y
);
8901 IDirect3DSurface8_Release(multi
);
8902 IDirect3DSurface8_Release(back
);
8904 refcount
= IDirect3DDevice8_Release(device
);
8905 ok(!refcount
, "Device has %u references left.\n", refcount
);
8908 IDirect3D8_Release(d3d
);
8909 DestroyWindow(window
);
8912 static void test_texture_blending(void)
8914 #define STATE_END() {0xffffffff, 0xffffffff}
8915 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8917 IDirect3DTexture8
*texture_bumpmap
, *texture_red
;
8918 IDirect3DSurface8
*backbuffer
;
8919 struct surface_readback rb
;
8920 D3DLOCKED_RECT locked_rect
;
8921 IDirect3DDevice8
*device
;
8922 unsigned int i
, j
, k
;
8932 struct vec3 position
;
8937 {{-1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8938 {{-1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8939 {{ 1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8940 {{ 1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8943 static const float bumpenvmat
[4] = {1.0f
, 1.0f
, 0.0f
, 0.0f
};
8945 struct texture_stage_state
8947 D3DTEXTURESTAGESTATETYPE name
;
8951 struct texture_stage
8961 struct texture_stage_state state
[20];
8964 static const struct texture_stage default_stage_state
=
8968 {D3DTSS_COLOROP
, D3DTOP_DISABLE
},
8969 {D3DTSS_COLORARG1
, D3DTA_TEXTURE
},
8970 {D3DTSS_COLORARG2
, D3DTA_CURRENT
},
8971 {D3DTSS_ALPHAOP
, D3DTOP_DISABLE
},
8972 {D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
},
8973 {D3DTSS_ALPHAARG2
, D3DTA_CURRENT
},
8974 {D3DTSS_BUMPENVMAT00
, 0},
8975 {D3DTSS_BUMPENVMAT01
, 0},
8976 {D3DTSS_BUMPENVMAT10
, 0},
8977 {D3DTSS_BUMPENVMAT11
, 0},
8978 {D3DTSS_BUMPENVLSCALE
, 0},
8979 {D3DTSS_BUMPENVLOFFSET
, 0},
8980 {D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_DISABLE
},
8981 {D3DTSS_COLORARG0
, D3DTA_CURRENT
},
8982 {D3DTSS_ALPHAARG0
, D3DTA_CURRENT
},
8983 {D3DTSS_RESULTARG
, D3DTA_CURRENT
},
8991 D3DCOLOR expected_color
;
8992 struct texture_stage stage
[8];
8997 D3DTEXOPCAPS_DISABLE
,
9009 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
,
9015 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9016 {D3DTSS_COLORARG1
, D3DTA_CURRENT
},
9024 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
,
9030 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9031 {D3DTSS_COLORARG1
, D3DTA_CURRENT
},
9032 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9033 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9040 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
,
9046 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9047 {D3DTSS_COLORARG1
, D3DTA_DIFFUSE
},
9048 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9049 {D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
},
9056 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
,
9062 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9063 {D3DTSS_COLORARG1
, D3DTA_TEMP
},
9064 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9065 {D3DTSS_ALPHAARG1
, D3DTA_TEMP
},
9073 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
,
9079 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9080 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9081 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9082 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9083 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9084 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9085 {D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
},
9093 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9101 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
,
9107 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9108 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9109 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9110 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9111 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9112 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9113 {D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
},
9120 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9128 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
,
9134 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9135 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9136 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9137 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9138 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9139 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9140 {D3DTSS_ALPHAARG1
, D3DTA_TEMP
},
9147 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9148 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9149 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9157 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
,
9163 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9164 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9165 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9166 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9167 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9168 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9169 {D3DTSS_ALPHAARG1
, D3DTA_TEMP
},
9176 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9177 {D3DTSS_COLORARG1
, D3DTA_TEXTURE
},
9178 {D3DTSS_COLORARG2
, D3DTA_CURRENT
},
9179 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9180 {D3DTSS_ALPHAARG1
, D3DTA_TEMP
},
9188 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
,
9194 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9195 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9196 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9197 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9198 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9199 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9200 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9207 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9208 {D3DTSS_COLORARG1
, D3DTA_TEXTURE
},
9209 {D3DTSS_COLORARG2
, D3DTA_CURRENT
},
9210 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9211 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9220 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
9227 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9228 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9229 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9230 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9231 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9232 {D3DTSS_ALPHAOP
, D3DTOP_ADD
},
9233 {D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
},
9234 {D3DTSS_ALPHAARG2
, D3DTA_CURRENT
},
9241 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9242 {D3DTSS_COLORARG1
, D3DTA_TEXTURE
},
9243 {D3DTSS_COLORARG2
, D3DTA_CURRENT
},
9244 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9245 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9253 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
| D3DTEXOPCAPS_MODULATE
9254 | D3DTEXOPCAPS_MODULATE2X
,
9260 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9261 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9262 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9263 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9264 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9265 {D3DTSS_ALPHAOP
, D3DTOP_MODULATE2X
},
9266 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9267 {D3DTSS_ALPHAARG2
, D3DTA_DIFFUSE
},
9274 {D3DTSS_COLOROP
, D3DTOP_MODULATE
},
9275 {D3DTSS_COLORARG1
, D3DTA_CURRENT
},
9276 {D3DTSS_COLORARG2
, D3DTA_CURRENT
},
9277 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9278 {D3DTSS_ALPHAARG1
, D3DTA_CURRENT
},
9286 D3DTEXOPCAPS_DISABLE
| D3DTEXOPCAPS_SELECTARG1
| D3DTEXOPCAPS_BUMPENVMAP
,
9292 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9293 {D3DTSS_COLORARG1
, D3DTA_DIFFUSE
},
9294 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9295 {D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
},
9296 {D3DTSS_RESULTARG
, D3DTA_TEMP
},
9303 {D3DTSS_COLOROP
, D3DTOP_BUMPENVMAP
},
9304 {D3DTSS_BUMPENVMAT00
, *(DWORD
*)&bumpenvmat
[0]},
9305 {D3DTSS_BUMPENVMAT01
, *(DWORD
*)&bumpenvmat
[1]},
9306 {D3DTSS_BUMPENVMAT10
, *(DWORD
*)&bumpenvmat
[2]},
9307 {D3DTSS_BUMPENVMAT11
, *(DWORD
*)&bumpenvmat
[3]},
9308 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9309 {D3DTSS_ALPHAARG1
, D3DTA_TEMP
},
9310 {D3DTSS_RESULTARG
, D3DTA_TEMP
},
9317 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9318 {D3DTSS_COLORARG1
, D3DTA_TEXTURE
},
9319 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9320 {D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
},
9327 {D3DTSS_COLOROP
, D3DTOP_SELECTARG1
},
9328 {D3DTSS_COLORARG1
, D3DTA_TEMP
},
9329 {D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
},
9330 {D3DTSS_ALPHAARG1
, D3DTA_TEMP
},
9339 window
= create_window();
9340 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9341 ok(!!d3d
, "Failed to create a D3D object.\n");
9342 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
9344 skip("Failed to create a D3D device.\n");
9348 memset(&caps
, 0, sizeof(caps
));
9349 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9350 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr
);
9352 if(!(caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_TSSARGTEMP
))
9354 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9355 IDirect3DDevice8_Release(device
);
9359 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
,
9360 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, D3DFMT_V8U8
)))
9362 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9363 IDirect3DDevice8_Release(device
);
9367 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
9368 ok(hr
== D3D_OK
, "Can't get back buffer, hr %#x.\n", hr
);
9370 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_V8U8
, D3DPOOL_MANAGED
, &texture_bumpmap
);
9371 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr
);
9372 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture_red
);
9373 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr
);
9375 memset(&locked_rect
, 0, sizeof(locked_rect
));
9376 hr
= IDirect3DTexture8_LockRect(texture_bumpmap
, 0, &locked_rect
, NULL
, 0);
9377 ok(SUCCEEDED(hr
), "LockRect failed, hr %#x.\n", hr
);
9378 *((WORD
*)locked_rect
.pBits
) = 0xff00;
9379 hr
= IDirect3DTexture8_UnlockRect(texture_bumpmap
, 0);
9380 ok(SUCCEEDED(hr
), "UnlockRect failed, hr %#x.\n", hr
);
9382 memset(&locked_rect
, 0, sizeof(locked_rect
));
9383 hr
= IDirect3DTexture8_LockRect(texture_red
, 0, &locked_rect
, NULL
, 0);
9384 ok(SUCCEEDED(hr
), "LockRect failed, hr %#x.\n", hr
);
9385 *((DWORD
*)locked_rect
.pBits
) = 0x00ff0000;
9386 hr
= IDirect3DTexture8_UnlockRect(texture_red
, 0);
9387 ok(SUCCEEDED(hr
), "UnlockRect failed, hr %#x.\n", hr
);
9389 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
9390 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
9391 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
9392 ok(hr
== D3D_OK
, "Failed to disable lighting, hr %#x.\n", hr
);
9394 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
9396 const struct test
*current_test
= &tests
[i
];
9398 if ((caps
.TextureOpCaps
& current_test
->tex_op_caps
) != current_test
->tex_op_caps
)
9400 skip("Texture operations %#x not supported.\n", current_test
->tex_op_caps
);
9404 for (j
= 0; j
< caps
.MaxTextureBlendStages
; ++j
)
9406 IDirect3DTexture8
*current_texture
= NULL
;
9408 for (k
= 0; !IS_STATE_END(default_stage_state
.state
[k
]); ++k
)
9410 hr
= IDirect3DDevice8_SetTextureStageState(device
, j
,
9411 default_stage_state
.state
[k
].name
, default_stage_state
.state
[k
].value
);
9412 ok(SUCCEEDED(hr
), "Test %u: SetTextureStageState failed, hr %#x.\n", i
, hr
);
9415 if (current_test
->stage
[j
].texture
!= TEXTURE_INVALID
)
9417 const struct texture_stage_state
*current_state
= current_test
->stage
[j
].state
;
9419 switch (current_test
->stage
[j
].texture
)
9422 current_texture
= texture_red
;
9424 case TEXTURE_BUMPMAP
:
9425 current_texture
= texture_bumpmap
;
9428 current_texture
= NULL
;
9432 for (k
= 0; !IS_STATE_END(current_state
[k
]); ++k
)
9434 hr
= IDirect3DDevice8_SetTextureStageState(device
, j
,
9435 current_state
[k
].name
, current_state
[k
].value
);
9436 ok(SUCCEEDED(hr
), "Test %u: SetTextureStageState failed, hr %#x.\n", i
, hr
);
9440 hr
= IDirect3DDevice8_SetTexture(device
, j
, (IDirect3DBaseTexture8
*)current_texture
);
9441 ok(SUCCEEDED(hr
), "Test %u: SetTexture failed, hr %#x.\n", i
, hr
);
9444 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
9445 ok(hr
== D3D_OK
, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i
, hr
);
9447 hr
= IDirect3DDevice8_BeginScene(device
);
9448 ok(SUCCEEDED(hr
), "Test %u: BeginScene failed, hr %#x.\n", i
, hr
);
9449 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(quad
[0]));
9450 ok(SUCCEEDED(hr
), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i
, hr
);
9451 hr
= IDirect3DDevice8_EndScene(device
);
9452 ok(SUCCEEDED(hr
), "Test %u: EndScene failed, hr %#x.\n", i
, hr
);
9454 get_rt_readback(backbuffer
, &rb
);
9455 color
= get_readback_color(&rb
, 320, 240);
9456 ok(color_match(color
, current_test
->expected_color
, 1),
9457 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i
, color
, current_test
->expected_color
);
9458 release_surface_readback(&rb
);
9459 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
9460 ok(SUCCEEDED(hr
), "Test %u: Present failed, hr %#x.\n", i
, hr
);
9463 IDirect3DTexture8_Release(texture_bumpmap
);
9464 IDirect3DTexture8_Release(texture_red
);
9465 IDirect3DSurface8_Release(backbuffer
);
9466 refcount
= IDirect3DDevice8_Release(device
);
9467 ok(!refcount
, "Device has %u references left.\n", refcount
);
9469 IDirect3D8_Release(d3d
);
9470 DestroyWindow(window
);
9473 static void test_color_clamping(void)
9475 static const D3DMATRIX mat
=
9477 1.0f
, 0.0f
, 0.0f
, 0.0f
,
9478 0.0f
, 1.0f
, 0.0f
, 0.0f
,
9479 0.0f
, 0.0f
, 1.0f
, 0.0f
,
9480 0.0f
, 0.0f
, 0.0f
, 1.0f
,
9482 static const struct vec3 quad
[] =
9484 {-1.0f
, -1.0f
, 0.1f
},
9485 {-1.0f
, 1.0f
, 0.1f
},
9486 { 1.0f
, -1.0f
, 0.1f
},
9487 { 1.0f
, 1.0f
, 0.1f
},
9489 static const DWORD decl
[] =
9492 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
9493 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9496 static const DWORD vs1_code
[] =
9498 0xfffe0101, /* vs_1_1 */
9499 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9500 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9501 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9504 static const DWORD ps1_code
[] =
9506 0xffff0101, /* ps_1_1 */
9507 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9508 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9509 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9518 D3DCOLOR expected
, broken
;
9522 {0, NULL
, 0, NULL
, 0x00404040},
9523 {0, NULL
, D3DPS_VERSION(1, 1), ps1_code
, 0x00404040, 0x00808080},
9524 {D3DVS_VERSION(1, 1), vs1_code
, 0, NULL
, 0x00404040},
9525 {D3DVS_VERSION(1, 1), vs1_code
, D3DPS_VERSION(1, 1), ps1_code
, 0x007f7f7f},
9527 IDirect3DDevice8
*device
;
9537 window
= create_window();
9538 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9539 ok(!!d3d
, "Failed to create a D3D object.\n");
9540 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
9542 skip("Failed to create a D3D device, skipping tests.\n");
9543 IDirect3D8_Release(d3d
);
9544 DestroyWindow(window
);
9548 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9549 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9551 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLD
, &mat
);
9552 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
9553 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_VIEW
, &mat
);
9554 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
9555 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &mat
);
9556 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
9557 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
9558 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
9559 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
9560 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
9561 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
9562 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
9563 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_STENCILENABLE
, FALSE
);
9564 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
9565 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CULLMODE
, D3DCULL_NONE
);
9566 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
9567 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
9568 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
9570 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_TEXTUREFACTOR
, 0xff404040);
9571 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#x.\n", hr
);
9572 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
9573 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
9574 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
9575 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
9576 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
9577 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
9578 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
9579 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
9580 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
9581 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
9582 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
9583 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
9585 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
9587 if (caps
.VertexShaderVersion
< tests
[i
].vs_version
9588 || caps
.PixelShaderVersion
< tests
[i
].ps_version
)
9590 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i
);
9595 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, tests
[i
].vs
, &vs
, 0);
9596 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x (case %u).\n", hr
, i
);
9604 hr
= IDirect3DDevice8_CreatePixelShader(device
, tests
[i
].ps
, &ps
);
9605 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x (case %u).\n", hr
, i
);
9612 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
9613 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
9614 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
9615 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
9617 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
9618 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9620 hr
= IDirect3DDevice8_BeginScene(device
);
9621 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9623 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
9624 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9626 hr
= IDirect3DDevice8_EndScene(device
);
9627 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9629 color
= getPixelColor(device
, 320, 240);
9630 ok(color_match(color
, tests
[i
].expected
, 1) || broken(color_match(color
, tests
[i
].broken
, 1)),
9631 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
9633 if (vs
!= D3DFVF_XYZ
)
9634 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
9636 IDirect3DDevice8_DeletePixelShader(device
, ps
);
9639 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
9640 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
9642 refcount
= IDirect3DDevice8_Release(device
);
9643 ok(!refcount
, "Device has %u references left.\n", refcount
);
9644 IDirect3D8_Release(d3d
);
9645 DestroyWindow(window
);
9648 static void test_edge_antialiasing_blending(void)
9650 IDirect3DDevice8
*device
;
9660 struct vec3 position
;
9665 {{-1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9666 {{-1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9667 {{ 1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9668 {{ 1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9672 struct vec3 position
;
9677 {{-1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9678 {{-1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9679 {{ 1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9680 {{ 1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9683 window
= create_window();
9684 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
9685 ok(!!d3d8
, "Failed to create a D3D object.\n");
9686 if (!(device
= create_device(d3d8
, window
, window
, TRUE
)))
9688 skip("Failed to create a D3D device.\n");
9689 IDirect3D8_Release(d3d8
);
9690 DestroyWindow(window
);
9694 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9695 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9696 trace("Edge antialiasing support: %#x.\n", caps
.RasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
9698 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
9699 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
9700 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
9701 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
9702 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
9703 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
9705 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
9706 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
9707 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_BLENDOP
, D3DBLENDOP_ADD
);
9708 ok(SUCCEEDED(hr
), "Failed to set blend op, hr %#x.\n", hr
);
9709 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
9710 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
9711 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_DESTALPHA
);
9712 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
9714 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
9715 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
9716 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
9717 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
9718 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
9719 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
9720 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
9721 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
9723 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
9724 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
9726 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
9727 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9728 hr
= IDirect3DDevice8_BeginScene(device
);
9729 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9730 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, green_quad
, sizeof(*green_quad
));
9731 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9732 hr
= IDirect3DDevice8_EndScene(device
);
9733 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9734 color
= getPixelColor(device
, 320, 240);
9735 ok(color_match(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
9737 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
9738 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9739 hr
= IDirect3DDevice8_BeginScene(device
);
9740 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9741 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, red_quad
, sizeof(*red_quad
));
9742 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9743 hr
= IDirect3DDevice8_EndScene(device
);
9744 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9745 color
= getPixelColor(device
, 320, 240);
9746 ok(color_match(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
9748 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, FALSE
);
9749 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
9751 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
9752 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9753 hr
= IDirect3DDevice8_BeginScene(device
);
9754 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9755 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, green_quad
, sizeof(*green_quad
));
9756 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9757 hr
= IDirect3DDevice8_EndScene(device
);
9758 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9759 color
= getPixelColor(device
, 320, 240);
9760 ok(color_match(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
9762 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
9763 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9764 hr
= IDirect3DDevice8_BeginScene(device
);
9765 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9766 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, red_quad
, sizeof(*red_quad
));
9767 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9768 hr
= IDirect3DDevice8_EndScene(device
);
9769 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9770 color
= getPixelColor(device
, 320, 240);
9771 ok(color_match(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9773 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_EDGEANTIALIAS
, TRUE
);
9774 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
9776 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
9777 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9778 hr
= IDirect3DDevice8_BeginScene(device
);
9779 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9780 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, green_quad
, sizeof(*green_quad
));
9781 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9782 hr
= IDirect3DDevice8_EndScene(device
);
9783 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9784 color
= getPixelColor(device
, 320, 240);
9785 ok(color_match(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
9787 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
9788 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9789 hr
= IDirect3DDevice8_BeginScene(device
);
9790 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9791 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, red_quad
, sizeof(*red_quad
));
9792 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9793 hr
= IDirect3DDevice8_EndScene(device
);
9794 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9795 color
= getPixelColor(device
, 320, 240);
9796 ok(color_match(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9798 refcount
= IDirect3DDevice8_Release(device
);
9799 ok(!refcount
, "Device has %u references left.\n", refcount
);
9800 IDirect3D8_Release(d3d8
);
9801 DestroyWindow(window
);
9804 /* This test shows that 0xffff is valid index in D3D8. */
9805 static void test_max_index16(void)
9807 static const struct vertex
9809 struct vec3 position
;
9814 {{-1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9815 {{-1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9816 {{ 1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9817 {{ 1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9819 static const unsigned short indices
[] = {0, 1, 2, 0xffff};
9820 static const unsigned int vertex_count
= 0xffff + 1;
9822 D3DADAPTER_IDENTIFIER8 identifier
;
9823 IDirect3DVertexBuffer8
*vb
;
9824 IDirect3DIndexBuffer8
*ib
;
9825 IDirect3DDevice8
*device
;
9826 struct vertex
*vb_data
;
9836 window
= create_window();
9837 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
9838 ok(!!d3d8
, "Failed to create a D3D object.\n");
9840 hr
= IDirect3D8_GetAdapterIdentifier(d3d8
, D3DADAPTER_DEFAULT
, 0, &identifier
);
9841 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#x.\n", hr
);
9842 warp
= adapter_is_warp(&identifier
);
9844 if (!(device
= create_device(d3d8
, window
, window
, TRUE
)))
9846 skip("Failed to create a D3D device.\n");
9847 IDirect3D8_Release(d3d8
);
9848 DestroyWindow(window
);
9852 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9853 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
9854 if (caps
.MaxVertexIndex
< 0xffff)
9856 skip("Max vertex index is lower than 0xffff (%#x).\n", caps
.MaxVertexIndex
);
9857 IDirect3DDevice8_Release(device
);
9858 IDirect3D8_Release(d3d8
);
9859 DestroyWindow(window
);
9863 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, vertex_count
* sizeof(*green_quad
), 0,
9864 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, D3DPOOL_MANAGED
, &vb
);
9865 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
9867 hr
= IDirect3DDevice8_CreateIndexBuffer(device
, sizeof(indices
), 0,
9868 D3DFMT_INDEX16
, D3DPOOL_MANAGED
, &ib
);
9869 ok(SUCCEEDED(hr
), "Failed to create index buffer, hr %#x.\n", hr
);
9871 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
9872 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
9873 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
9874 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
9875 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
9876 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
9878 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
9879 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
9881 hr
= IDirect3DVertexBuffer8_Lock(vb
, 0, sizeof(green_quad
), (BYTE
**)&vb_data
, 0);
9882 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
9883 vb_data
[0] = green_quad
[0];
9884 vb_data
[1] = green_quad
[1];
9885 vb_data
[2] = green_quad
[2];
9886 vb_data
[0xffff] = green_quad
[3];
9887 hr
= IDirect3DVertexBuffer8_Unlock(vb
);
9888 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9890 hr
= IDirect3DIndexBuffer8_Lock(ib
, 0, sizeof(indices
), &data
, 0);
9891 ok(hr
== D3D_OK
, "Failed to lock index buffer, hr %#x.\n", hr
);
9892 memcpy(data
, indices
, sizeof(indices
));
9893 hr
= IDirect3DIndexBuffer8_Unlock(ib
);
9894 ok(hr
== D3D_OK
, "Failed to unlock index buffer, hr %#x.\n", hr
);
9896 hr
= IDirect3DDevice8_SetIndices(device
, ib
, 0);
9897 ok(hr
== D3D_OK
, "Failed to set index buffer, hr %#x.\n", hr
);
9898 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, sizeof(struct vertex
));
9899 ok(hr
== D3D_OK
, "Failed to set stream source, hr %#x.\n", hr
);
9901 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
9902 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9903 hr
= IDirect3DDevice8_BeginScene(device
);
9904 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9905 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, vertex_count
, 0, 2);
9906 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9907 hr
= IDirect3DDevice8_EndScene(device
);
9908 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9909 color
= getPixelColor(device
, 20, 20);
9910 ok(color_match(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
9911 color
= getPixelColor(device
, 320, 240);
9912 ok(color_match(color
, 0x0000ff00, 1) || broken(warp
), "Got unexpected color 0x%08x.\n", color
);
9913 color
= getPixelColor(device
, 620, 460);
9914 ok(color_match(color
, 0x0000ff00, 1) || broken(warp
), "Got unexpected color 0x%08x.\n", color
);
9916 IDirect3DIndexBuffer8_Release(ib
);
9917 IDirect3DVertexBuffer8_Release(vb
);
9918 refcount
= IDirect3DDevice8_Release(device
);
9919 ok(!refcount
, "Device has %u references left.\n", refcount
);
9920 IDirect3D8_Release(d3d8
);
9921 DestroyWindow(window
);
9924 static void test_backbuffer_resize(void)
9926 D3DPRESENT_PARAMETERS present_parameters
= {0};
9927 IDirect3DSurface8
*backbuffer
;
9928 IDirect3DDevice8
*device
;
9937 struct vec3 position
;
9942 {{-1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9943 {{-1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9944 {{ 1.0f
, -1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9945 {{ 1.0f
, 1.0f
, 0.1f
}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9948 window
= create_window();
9949 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9950 ok(!!d3d
, "Failed to create a D3D object.\n");
9951 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
9953 skip("Failed to create a D3D device.\n");
9957 /* Wine d3d8 implementation had a bug which was triggered by a
9958 * SetRenderTarget() call with an unreferenced surface. */
9959 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
9960 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
9961 refcount
= IDirect3DSurface8_Release(backbuffer
);
9962 ok(!refcount
, "Surface has %u references left.\n", refcount
);
9963 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, NULL
);
9964 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
9965 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, NULL
);
9966 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
9968 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
9969 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9970 color
= getPixelColor(device
, 1, 1);
9971 ok(color
== 0x00ff0000, "Got unexpected color 0x%08x.\n", color
);
9973 present_parameters
.BackBufferWidth
= 800;
9974 present_parameters
.BackBufferHeight
= 600;
9975 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
9976 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
9977 present_parameters
.hDeviceWindow
= NULL
;
9978 present_parameters
.Windowed
= TRUE
;
9979 present_parameters
.EnableAutoDepthStencil
= TRUE
;
9980 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
9981 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
9982 ok(SUCCEEDED(hr
), "Failed to reset, hr %#x.\n", hr
);
9984 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
9985 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
9986 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
9987 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
9988 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
9989 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
9990 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
9991 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
9993 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
9994 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
9995 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, NULL
);
9996 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
9997 IDirect3DSurface8_Release(backbuffer
);
9999 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10000 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10001 color
= getPixelColor(device
, 1, 1);
10002 ok(color
== 0x00ffff00, "Got unexpected color 0x%08x.\n", color
);
10003 color
= getPixelColor(device
, 700, 500);
10004 ok(color
== 0x00ffff00, "Got unexpected color 0x%08x.\n", color
);
10006 hr
= IDirect3DDevice8_BeginScene(device
);
10007 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10008 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
10009 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10010 hr
= IDirect3DDevice8_EndScene(device
);
10011 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10012 color
= getPixelColor(device
, 1, 1);
10013 ok(color
== 0x0000ff00, "Got unexpected color 0x%08x.\n", color
);
10014 color
= getPixelColor(device
, 700, 500);
10015 ok(color
== 0x0000ff00, "Got unexpected color 0x%08x.\n", color
);
10017 refcount
= IDirect3DDevice8_Release(device
);
10018 ok(!refcount
, "Device has %u references left.\n", refcount
);
10020 IDirect3D8_Release(d3d
);
10021 DestroyWindow(window
);
10024 static void test_drawindexedprimitiveup(void)
10026 static const struct vertex
10028 struct vec3 position
;
10033 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
10034 {{-1.0f
, 1.0f
, 0.1f
}, 0xff0000ff},
10035 {{ 1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
10036 {{ 1.0f
, 1.0f
, 0.1f
}, 0xff0000ff},
10038 {{-1.0f
, -1.0f
, 0.1f
}, 0xff0000ff},
10039 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
10040 {{ 1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
10041 {{ 1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
10043 static const unsigned short indices
[] = {0, 1, 2, 3, 4, 5, 6, 7};
10044 IDirect3DDevice8
*device
;
10051 window
= create_window();
10052 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10053 ok(!!d3d
, "Failed to create a D3D object.\n");
10055 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
10057 skip("Failed to create a D3D device.\n");
10058 IDirect3D8_Release(d3d
);
10059 DestroyWindow(window
);
10063 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
10064 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
10065 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
10066 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
10067 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
10068 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
10070 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
10071 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10072 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
10073 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10074 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
10075 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
10076 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
10077 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
10079 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10080 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
10082 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
10083 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10085 hr
= IDirect3DDevice8_BeginScene(device
);
10086 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10087 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 4, 4, 2, indices
+ 4, D3DFMT_INDEX16
, quad
, sizeof(*quad
));
10088 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10089 hr
= IDirect3DDevice8_EndScene(device
);
10090 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10092 color
= getPixelColor(device
, 160, 120);
10093 ok(color_match(color
, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color
);
10094 color
= getPixelColor(device
, 480, 120);
10095 ok(color_match(color
, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color
);
10096 color
= getPixelColor(device
, 160, 360);
10097 ok(color_match(color
, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color
);
10098 color
= getPixelColor(device
, 480, 360);
10099 ok(color_match(color
, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color
);
10101 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
10102 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10104 hr
= IDirect3DDevice8_BeginScene(device
);
10105 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10106 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 0, 4, 2, indices
, D3DFMT_INDEX16
, quad
, sizeof(*quad
));
10107 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10108 hr
= IDirect3DDevice8_EndScene(device
);
10109 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10111 color
= getPixelColor(device
, 160, 120);
10112 ok(color_match(color
, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color
);
10113 color
= getPixelColor(device
, 480, 120);
10114 ok(color_match(color
, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color
);
10115 color
= getPixelColor(device
, 160, 360);
10116 ok(color_match(color
, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color
);
10117 color
= getPixelColor(device
, 480, 360);
10118 ok(color_match(color
, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color
);
10120 refcount
= IDirect3DDevice8_Release(device
);
10121 ok(!refcount
, "Device has %u references left.\n", refcount
);
10122 IDirect3D8_Release(d3d
);
10123 DestroyWindow(window
);
10126 static void test_map_synchronisation(void)
10128 LARGE_INTEGER frequency
, diff
, ts
[3];
10129 unsigned int i
, j
, tri_count
, size
;
10130 D3DADAPTER_IDENTIFIER8 identifier
;
10131 IDirect3DVertexBuffer8
*buffer
;
10132 IDirect3DDevice8
*device
;
10133 BOOL unsynchronised
, ret
;
10141 static const struct
10143 unsigned int flags
;
10144 BOOL unsynchronised
;
10149 {D3DLOCK_NOOVERWRITE
, TRUE
},
10150 {D3DLOCK_DISCARD
, FALSE
},
10151 {D3DLOCK_NOOVERWRITE
| D3DLOCK_DISCARD
, TRUE
},
10154 static const struct quad
10158 struct vec3 position
;
10165 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10166 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10167 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10168 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
10174 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
10175 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
10176 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
10177 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
10180 struct quad
*quads
;
10182 window
= create_window();
10183 ok(!!window
, "Failed to create a window.\n");
10185 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10186 ok(!!d3d
, "Failed to create a D3D object.\n");
10187 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
10189 skip("Failed to create a D3D device, skipping tests.\n");
10190 IDirect3D8_Release(d3d
);
10191 DestroyWindow(window
);
10195 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
10196 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#x.\n", hr
);
10197 /* Maps are always synchronised on WARP. */
10198 if (adapter_is_warp(&identifier
))
10200 skip("Running on WARP, skipping test.\n");
10204 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
10205 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10207 tri_count
= 0x1000;
10208 if (tri_count
> caps
.MaxPrimitiveCount
)
10210 skip("Device supports only %u primitives, skipping test.\n", caps
.MaxPrimitiveCount
);
10213 size
= (tri_count
+ 2) * sizeof(*quad1
.strip
);
10215 ret
= QueryPerformanceFrequency(&frequency
);
10216 ok(ret
, "Failed to get performance counter frequency.\n");
10218 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, size
,
10219 D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
, 0, D3DPOOL_DEFAULT
, &buffer
);
10220 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
10221 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, size
, (BYTE
**)&quads
, D3DLOCK_DISCARD
);
10222 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
10223 for (j
= 0; j
< size
/ sizeof(*quads
); ++j
)
10227 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
10228 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10230 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
10231 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10232 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10233 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
10234 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, buffer
, sizeof(*quads
->strip
));
10235 ok(SUCCEEDED(hr
), "Failed to set stream source, hr %#x.\n", hr
);
10237 /* Initial draw to initialise states, compile shaders, etc. */
10238 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
10239 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10240 hr
= IDirect3DDevice8_BeginScene(device
);
10241 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10242 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, tri_count
);
10243 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10244 hr
= IDirect3DDevice8_EndScene(device
);
10245 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10246 /* Read the result to ensure the GPU has finished drawing. */
10247 colour
= getPixelColor(device
, 320, 240);
10249 /* Time drawing tri_count triangles. */
10250 ret
= QueryPerformanceCounter(&ts
[0]);
10251 ok(ret
, "Failed to read performance counter.\n");
10252 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
10253 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10254 hr
= IDirect3DDevice8_BeginScene(device
);
10255 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10256 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, tri_count
);
10257 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10258 hr
= IDirect3DDevice8_EndScene(device
);
10259 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10260 colour
= getPixelColor(device
, 320, 240);
10261 /* Time drawing a single triangle. */
10262 ret
= QueryPerformanceCounter(&ts
[1]);
10263 ok(ret
, "Failed to read performance counter.\n");
10264 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
10265 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10266 hr
= IDirect3DDevice8_BeginScene(device
);
10267 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10268 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 1);
10269 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10270 hr
= IDirect3DDevice8_EndScene(device
);
10271 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10272 colour
= getPixelColor(device
, 320, 240);
10273 ret
= QueryPerformanceCounter(&ts
[2]);
10274 ok(ret
, "Failed to read performance counter.\n");
10276 IDirect3DVertexBuffer8_Release(buffer
);
10278 /* Estimate the number of triangles we can draw in 100ms. */
10279 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
10280 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
10281 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
10282 if (tri_count
> caps
.MaxPrimitiveCount
)
10284 skip("Would need to draw %u triangles, but the device only supports %u primitives.\n",
10285 tri_count
, caps
.MaxPrimitiveCount
);
10288 size
= (tri_count
+ 2) * sizeof(*quad1
.strip
);
10290 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10292 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, size
,
10293 D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
, 0, D3DPOOL_DEFAULT
, &buffer
);
10294 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
10295 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, size
, (BYTE
**)&quads
, D3DLOCK_DISCARD
);
10296 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
10297 for (j
= 0; j
< size
/ sizeof(*quads
); ++j
)
10301 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
10302 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10304 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, buffer
, sizeof(*quads
->strip
));
10305 ok(SUCCEEDED(hr
), "Failed to set stream source, hr %#x.\n", hr
);
10307 /* Start a draw operation. */
10308 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
10309 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10310 hr
= IDirect3DDevice8_BeginScene(device
);
10311 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10312 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, tri_count
);
10313 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10314 hr
= IDirect3DDevice8_EndScene(device
);
10315 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10317 /* Map the last quad while the draw is in progress. */
10318 hr
= IDirect3DVertexBuffer8_Lock(buffer
, size
- sizeof(quad2
),
10319 sizeof(quad2
), (BYTE
**)&quads
, tests
[i
].flags
);
10320 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
10322 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
10323 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10325 colour
= getPixelColor(device
, 320, 240);
10326 unsynchronised
= color_match(colour
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
10327 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
10328 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
10330 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
10331 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
10333 IDirect3DVertexBuffer8_Release(buffer
);
10337 refcount
= IDirect3DDevice8_Release(device
);
10338 ok(!refcount
, "Device has %u references left.\n", refcount
);
10339 IDirect3D8_Release(d3d
);
10340 DestroyWindow(window
);
10343 static void test_viewport(void)
10345 static const struct
10348 RECT expected_rect
;
10349 const char *message
;
10353 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
10354 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
10355 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
10356 {{ 0, 0, 2000, 1600}, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
10357 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
10358 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
10360 static const struct vec3 quad
[] =
10362 {-1.5f
, -0.5f
, 0.1f
},
10363 {-1.5f
, 0.5f
, 0.1f
},
10364 { 0.5f
, -0.5f
, 0.1f
},
10365 { 0.5f
, 0.5f
, 0.1f
},
10367 static const struct vec2 rt_sizes
[] =
10369 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
10371 struct surface_readback rb
;
10372 IDirect3DDevice8
*device
;
10373 IDirect3DSurface8
*rt
;
10380 window
= create_window();
10381 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10382 ok(!!d3d
, "Failed to create a D3D object.\n");
10383 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
10385 skip("Failed to create a D3D device, skipping tests.\n");
10389 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_FALSE
);
10390 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#x.\n", hr
);
10391 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
10392 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
10394 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
10395 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
10397 /* This crashes on Windows. */
10398 /* hr = IDirect3DDevice8_SetViewport(device, NULL); */
10400 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
10404 hr
= IDirect3DDevice8_CreateRenderTarget(device
, rt_sizes
[i
].x
, rt_sizes
[i
].y
,
10405 D3DFMT_A8R8G8B8
, D3DMULTISAMPLE_NONE
, TRUE
, &rt
);
10406 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x (i %u).\n", hr
, i
);
10407 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, NULL
);
10408 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x (i %u).\n", hr
, i
);
10412 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &rt
);
10413 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
10416 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
10418 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 1.0f
, 0);
10419 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x (i %u, j %u).\n", hr
, i
, j
);
10421 hr
= IDirect3DDevice8_SetViewport(device
, &tests
[j
].vp
);
10422 if (tests
[j
].vp
.X
+ tests
[j
].vp
.Width
> rt_sizes
[i
].x
10423 || tests
[j
].vp
.Y
+ tests
[j
].vp
.Height
> rt_sizes
[i
].y
)
10425 ok(hr
== D3DERR_INVALIDCALL
,
10426 "Setting the viewport returned unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
10431 ok(SUCCEEDED(hr
), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
10434 hr
= IDirect3DDevice8_BeginScene(device
);
10435 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
10436 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
10437 ok(SUCCEEDED(hr
), "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
10438 hr
= IDirect3DDevice8_EndScene(device
);
10439 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
10441 get_rt_readback(rt
, &rb
);
10442 check_rect(&rb
, tests
[j
].expected_rect
, tests
[j
].message
);
10443 release_surface_readback(&rb
);
10446 IDirect3DSurface8_Release(rt
);
10449 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
10450 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
10452 refcount
= IDirect3DDevice8_Release(device
);
10453 ok(!refcount
, "Device has %u references left.\n", refcount
);
10455 IDirect3D8_Release(d3d
);
10456 DestroyWindow(window
);
10459 static void test_color_vertex(void)
10461 IDirect3DDevice8
*device
;
10462 D3DMATERIAL8 material
;
10470 /* The idea here is to set up ambient light parameters in a way that the
10471 * ambient colour from the material is just passed through. The emissive
10472 * colour is just passed through anyway. The sum of ambient + emissive
10473 * should allow deduction of where the material colour came from.
10475 * Note that in cases without a D3DFVF_DIFFUSE flag the first colour value
10476 * in the struct will be fed into the specular vertex colour slot. */
10477 static const struct
10479 DWORD fvf
, color_vertex
, ambient
, emissive
, result
;
10483 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, FALSE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x000000c0},
10485 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ffff00},
10486 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_MATERIAL
, D3DMCS_COLOR2
, 0x0000ff80},
10487 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x00ff0040},
10488 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR1
, 0x00ff0000},
10489 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR2
, D3DMCS_COLOR2
, 0x0000ff00},
10491 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ff0080},
10492 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x000000c0},
10493 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_MATERIAL
, D3DMCS_COLOR2
, 0x00ff0080},
10494 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ff0040},
10495 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x00ff0040},
10496 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR2
, D3DMCS_MATERIAL
, 0x000000c0},
10498 {0, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x000000c0},
10500 static const struct
10502 struct vec3 position
;
10508 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
10509 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
10510 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
10511 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
10514 window
= create_window();
10515 ok(!!window
, "Failed to create a window.\n");
10517 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10518 ok(!!d3d
, "Failed to create a D3D object.\n");
10519 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
10521 skip("Failed to create a D3D device, skipping tests.\n");
10522 IDirect3D8_Release(d3d
);
10523 DestroyWindow(window
);
10527 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
10528 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10529 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_AMBIENT
, 0xffffffff);
10530 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10532 memset(&material
, 0, sizeof(material
));
10533 material
.Ambient
.b
= 0.5f
;
10534 material
.Emissive
.b
= 0.25f
;
10535 hr
= IDirect3DDevice8_SetMaterial(device
, &material
);
10536 ok(SUCCEEDED(hr
), "Failed to set material, hr %#x\n", hr
);
10538 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10540 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORVERTEX
, tests
[i
].color_vertex
);
10541 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10542 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_AMBIENTMATERIALSOURCE
, tests
[i
].ambient
);
10543 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10544 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_EMISSIVEMATERIALSOURCE
, tests
[i
].emissive
);
10545 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10546 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| tests
[i
].fvf
);
10547 ok(SUCCEEDED(hr
), "Failed to set vertex format, hr %#x.\n", hr
);
10549 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10550 ok(SUCCEEDED(hr
), "Failed to clear depth/stencil, hr %#x.\n", hr
);
10552 hr
= IDirect3DDevice8_BeginScene(device
);
10553 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10554 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
10555 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10556 hr
= IDirect3DDevice8_EndScene(device
);
10557 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10559 colour
= getPixelColor(device
, 320, 240);
10560 ok(color_match(colour
, tests
[i
].result
, 1),
10561 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
10562 tests
[i
].result
, i
, colour
);
10565 refcount
= IDirect3DDevice8_Release(device
);
10566 ok(!refcount
, "Device has %u references left.\n", refcount
);
10567 IDirect3D8_Release(d3d
);
10568 DestroyWindow(window
);
10571 static void test_sysmem_draw(void)
10573 IDirect3DVertexBuffer8
*vb
, *vb_s0
, *vb_s1
, *dst_vb
, *get_vb
;
10574 D3DPRESENT_PARAMETERS present_parameters
= {0};
10575 IDirect3DTexture8
*texture
;
10576 IDirect3DIndexBuffer8
*ib
;
10577 IDirect3DDevice8
*device
;
10578 unsigned int i
, stride
;
10579 struct vec4
*dst_data
;
10589 static const DWORD texture_data
[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
10590 static const DWORD decl
[] =
10593 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
10595 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
),
10598 static const struct
10600 struct vec3 position
;
10605 {{-0.5f
, -0.5f
, 0.0f
}, 0xffff0000},
10606 {{-0.5f
, 0.5f
, 0.0f
}, 0xff00ff00},
10607 {{ 0.5f
, -0.5f
, 0.0f
}, 0xff0000ff},
10608 {{ 0.5f
, 0.5f
, 0.0f
}, 0xffffffff},
10610 static const struct vec3 quad_s0
[] =
10612 {-1.0f
, -1.0f
, 0.0f
},
10613 {-1.0f
, 1.0f
, 0.0f
},
10614 { 1.0f
, -1.0f
, 0.0f
},
10615 { 1.0f
, 1.0f
, 0.0f
},
10617 {-1.0f
, -1.0f
, 0.0f
},
10618 {-1.0f
, 1.0f
, 0.0f
},
10619 { 1.0f
, -1.0f
, 0.0f
},
10620 { 1.0f
, 1.0f
, 0.0f
},
10622 static const DWORD quad_s1
[] =
10634 static const short indices
[] = {0, 1, 2, 3};
10636 window
= create_window();
10637 ok(!!window
, "Failed to create a window.\n");
10639 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10640 ok(!!d3d
, "Failed to create a D3D object.\n");
10642 present_parameters
.BackBufferWidth
= 640;
10643 present_parameters
.BackBufferHeight
= 480;
10644 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
10645 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
10646 present_parameters
.hDeviceWindow
= window
;
10647 present_parameters
.Windowed
= TRUE
;
10648 present_parameters
.EnableAutoDepthStencil
= TRUE
;
10649 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
10650 if (FAILED(hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
10651 window
, D3DCREATE_MIXED_VERTEXPROCESSING
, &present_parameters
, &device
)))
10653 skip("Failed to create a D3D device, skipping tests.\n");
10654 IDirect3D8_Release(d3d
);
10655 DestroyWindow(window
);
10659 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
10660 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10662 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad
), 0, 0, D3DPOOL_SYSTEMMEM
, &vb
);
10663 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10664 hr
= IDirect3DVertexBuffer8_Lock(vb
, 0, sizeof(quad
), &data
, 0);
10665 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10666 memcpy(data
, quad
, sizeof(quad
));
10667 hr
= IDirect3DVertexBuffer8_Unlock(vb
);
10668 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10670 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10671 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10673 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10674 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10675 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, sizeof(*quad
));
10676 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10678 hr
= IDirect3DDevice8_BeginScene(device
);
10679 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10680 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 2);
10681 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10682 hr
= IDirect3DDevice8_EndScene(device
);
10683 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10685 colour
= getPixelColor(device
, 320, 240);
10686 ok(color_match(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
10688 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, ARRAY_SIZE(quad
) * sizeof(*dst_data
),
10689 0, D3DFVF_XYZRHW
, D3DPOOL_SYSTEMMEM
, &dst_vb
);
10690 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10691 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SOFTWAREVERTEXPROCESSING
, TRUE
);
10692 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10693 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10694 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10695 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, sizeof(*quad
));
10696 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10698 hr
= IDirect3DDevice8_ProcessVertices(device
, 0, 0, ARRAY_SIZE(quad
), dst_vb
, 0);
10699 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10700 hr
= IDirect3DVertexBuffer8_Lock(dst_vb
, 0, 0, (BYTE
**)&dst_data
, 0);
10701 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10702 for (i
= 0; i
< ARRAY_SIZE(quad
); ++i
)
10704 ok(compare_vec4(&dst_data
[i
], quad
[i
].position
.x
* 320.0f
+ 320.0f
,
10705 -quad
[i
].position
.y
* 240.0f
+ 240.0f
, 0.0f
, 1.0f
, 4),
10706 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
10707 i
, dst_data
[i
].x
, dst_data
[i
].y
, dst_data
[i
].z
, dst_data
[i
].w
);
10709 hr
= IDirect3DVertexBuffer8_Unlock(dst_vb
);
10710 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10712 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SOFTWAREVERTEXPROCESSING
, FALSE
);
10713 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10714 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10715 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10716 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, sizeof(*quad
));
10717 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10719 hr
= IDirect3DDevice8_CreateIndexBuffer(device
, sizeof(indices
), 0,
10720 D3DFMT_INDEX16
, D3DPOOL_SYSTEMMEM
, &ib
);
10721 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10722 hr
= IDirect3DIndexBuffer8_Lock(ib
, 0, sizeof(indices
), &data
, 0);
10723 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10724 memcpy(data
, indices
, sizeof(indices
));
10725 hr
= IDirect3DIndexBuffer8_Unlock(ib
);
10726 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10728 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10729 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10731 hr
= IDirect3DDevice8_SetIndices(device
, ib
, 0);
10732 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10734 hr
= IDirect3DDevice8_BeginScene(device
);
10735 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10736 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 4, 0, 2);
10737 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10738 hr
= IDirect3DDevice8_EndScene(device
);
10739 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10741 colour
= getPixelColor(device
, 320, 240);
10742 ok(color_match(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
10744 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, NULL
, &vs
, 0);
10745 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10746 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
10747 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10749 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad_s0
), 0, 0, D3DPOOL_SYSTEMMEM
, &vb_s0
);
10750 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10751 hr
= IDirect3DVertexBuffer8_Lock(vb_s0
, 0, sizeof(quad_s0
), &data
, 0);
10752 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10753 memcpy(data
, quad_s0
, sizeof(quad_s0
));
10754 hr
= IDirect3DVertexBuffer8_Unlock(vb_s0
);
10755 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10756 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad_s1
), 0, 0, D3DPOOL_SYSTEMMEM
, &vb_s1
);
10757 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10758 hr
= IDirect3DVertexBuffer8_Lock(vb_s1
, 0, sizeof(quad_s1
), &data
, 0);
10759 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10760 memcpy(data
, quad_s1
, sizeof(quad_s1
));
10761 hr
= IDirect3DVertexBuffer8_Unlock(vb_s1
);
10762 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10764 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb_s0
, sizeof(*quad_s0
));
10765 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10766 hr
= IDirect3DDevice8_SetStreamSource(device
, 1, vb_s1
, sizeof(*quad_s1
));
10767 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10769 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10770 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10772 hr
= IDirect3DDevice8_BeginScene(device
);
10773 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10774 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 4, 0, 2);
10775 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10776 hr
= IDirect3DDevice8_EndScene(device
);
10777 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10779 colour
= getPixelColor(device
, 320, 240);
10780 ok(color_match(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
10782 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10783 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10785 hr
= IDirect3DDevice8_SetIndices(device
, ib
, 4);
10786 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10788 hr
= IDirect3DDevice8_BeginScene(device
);
10789 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10790 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 5, 0, 2);
10791 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10792 hr
= IDirect3DDevice8_EndScene(device
);
10793 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10795 colour
= getPixelColor(device
, 320, 240);
10796 ok(color_match(colour
, 0x00443322, 1), "Got unexpected colour 0x%08x.\n", colour
);
10798 /* Test that releasing but not unbinding a vertex buffer doesn't break. */
10799 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10800 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10801 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, sizeof(*quad
));
10802 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10803 hr
= IDirect3DDevice8_SetIndices(device
, ib
, 0);
10804 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10806 refcount
= IDirect3DVertexBuffer8_Release(vb_s1
);
10807 ok(!refcount
, "Unexpected refcount %u.\n", refcount
);
10808 hr
= IDirect3DDevice8_GetStreamSource(device
, 1, &get_vb
, &stride
);
10809 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10810 ok(get_vb
== vb_s1
, "Got unexpected vertex buffer %p.\n", get_vb
);
10811 refcount
= IDirect3DVertexBuffer8_Release(get_vb
);
10812 ok(!refcount
, "Unexpected refcount %u.\n", refcount
);
10814 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10815 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10817 hr
= IDirect3DDevice8_BeginScene(device
);
10818 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10819 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 4, 0, 2);
10820 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10821 hr
= IDirect3DDevice8_EndScene(device
);
10822 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10824 colour
= getPixelColor(device
, 320, 240);
10825 ok(color_match(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
10827 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
10828 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10829 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb_s0
, sizeof(*quad_s0
));
10830 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10832 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10833 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10835 hr
= IDirect3DDevice8_BeginScene(device
);
10836 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10837 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 4, 0, 2);
10838 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10839 hr
= IDirect3DDevice8_EndScene(device
);
10840 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10842 colour
= getPixelColor(device
, 320, 240);
10843 ok(color_match(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
10845 hr
= IDirect3DDevice8_CreateTexture(device
, 2, 2, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_SYSTEMMEM
, &texture
);
10846 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10847 memset(&lr
, 0, sizeof(lr
));
10848 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lr
, NULL
, 0);
10849 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10850 memcpy(lr
.pBits
, texture_data
, sizeof(texture_data
));
10851 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
10852 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10854 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
10855 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10857 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
10858 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10860 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
10861 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10863 hr
= IDirect3DDevice8_BeginScene(device
);
10864 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10865 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 2);
10866 ok(hr
== D3D_OK
|| hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
10867 hr
= IDirect3DDevice8_EndScene(device
);
10868 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10870 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
10871 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10873 IDirect3DTexture8_Release(texture
);
10874 IDirect3DVertexBuffer8_Release(vb_s0
);
10875 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
10876 IDirect3DIndexBuffer8_Release(ib
);
10877 IDirect3DVertexBuffer8_Release(dst_vb
);
10878 IDirect3DVertexBuffer8_Release(vb
);
10879 refcount
= IDirect3DDevice8_Release(device
);
10880 ok(!refcount
, "Device has %u references left.\n", refcount
);
10881 IDirect3D8_Release(d3d
);
10882 DestroyWindow(window
);
10885 static void test_alphatest(void)
10887 #define ALPHATEST_PASSED 0x0000ff00
10888 #define ALPHATEST_FAILED 0x00ff0000
10889 IDirect3DDevice8
*device
;
10900 static const struct
10903 D3DCOLOR color_less
;
10904 D3DCOLOR color_equal
;
10905 D3DCOLOR color_greater
;
10909 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
10910 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
10911 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
10912 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
10913 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
10914 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
10915 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
10916 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
10918 static const struct
10920 struct vec3 position
;
10925 {{-1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
10926 {{-1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
10927 {{ 1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
10928 {{ 1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
10931 window
= create_window();
10932 ok(!!window
, "Failed to create a window.\n");
10934 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10935 ok(!!d3d
, "Failed to create a D3D object.\n");
10937 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
10939 skip("Failed to create a D3D device, skipping tests.\n");
10943 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
10944 ok(hr
== D3D_OK
, "Failed to clear, hr %#x.\n", hr
);
10946 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
10947 ok(hr
== D3D_OK
, "Failed to disable lighting, hr %#x.\n", hr
);
10948 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHATESTENABLE
, TRUE
);
10949 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState, hr %#x.\n", hr
);
10950 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10951 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader failed, hr %#x.\n", hr
);
10954 for (j
= 0; j
< 2; ++j
)
10958 /* Try a pixel shader instead of fixed function. The wined3d code
10959 * may emulate the alpha test either for performance reasons
10960 * (floating point RTs) or to work around driver bugs (GeForce
10961 * 7x00 cards on MacOS). There may be a different codepath for ffp
10962 * and shader in this case, and the test should cover both. */
10963 static const DWORD shader_code
[] =
10965 0xffff0101, /* ps_1_1 */
10966 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10967 0x0000ffff /* end */
10969 memset(&caps
, 0, sizeof(caps
));
10970 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
10971 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps failed, hr %#x.\n", hr
);
10972 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
10975 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code
, &ps
);
10976 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader failed, hr %#x.\n", hr
);
10977 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
10978 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader failed, hr %#x.\n", hr
);
10981 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10983 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHAFUNC
, test_data
[i
].func
);
10984 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr
);
10986 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
10987 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr %#x.\n", hr
);
10988 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHAREF
, 0x70);
10989 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr
);
10990 hr
= IDirect3DDevice8_BeginScene(device
);
10991 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed, hr %#x.\n", hr
);
10992 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
10993 ok(hr
== D3D_OK
, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#x.\n", hr
);
10994 hr
= IDirect3DDevice8_EndScene(device
);
10995 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed, hr %#x.\n", hr
);
10996 color
= getPixelColor(device
, 320, 240);
10997 ok(color_match(color
, test_data
[i
].color_greater
, 0),
10998 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
10999 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
11000 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
11001 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr %#x.\n", hr
);
11003 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
11004 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr %#x.\n", hr
);
11005 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHAREF
, 0xff70);
11006 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr
);
11007 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ALPHAREF
, &value
);
11008 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetRenderState failed, hr %#x.\n", hr
);
11009 ok(value
== 0xff70, "Unexpected D3DRS_ALPHAREF value %#x.\n", value
);
11010 hr
= IDirect3DDevice8_BeginScene(device
);
11011 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed, hr %#x.\n", hr
);
11012 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
11013 ok(hr
== D3D_OK
, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#x.\n", hr
);
11014 hr
= IDirect3DDevice8_EndScene(device
);
11015 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed, hr %#x.\n", hr
);
11016 color
= getPixelColor(device
, 320, 240);
11017 ok(color_match(color
, test_data
[i
].color_greater
, 0),
11018 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
11019 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
11020 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
11021 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr %#x.\n", hr
);
11025 IDirect3DDevice8_DeletePixelShader(device
, ps
);
11027 refcount
= IDirect3DDevice8_Release(device
);
11028 ok(!refcount
, "Device has %u references left.\n", refcount
);
11030 IDirect3D8_Release(d3d
);
11031 DestroyWindow(window
);
11034 static void test_desktop_window(void)
11036 IDirect3DDevice8
*device
;
11043 window
= create_window();
11044 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
11045 ok(!!d3d
, "Failed to create a D3D object.\n");
11046 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
11048 skip("Failed to create a D3D device, skipping tests.\n");
11049 IDirect3D8_Release(d3d
);
11050 DestroyWindow(window
);
11053 IDirect3DDevice8_Release(device
);
11054 DestroyWindow(window
);
11056 device
= create_device(d3d
, GetDesktopWindow(), GetDesktopWindow(), TRUE
);
11057 ok(!!device
, "Failed to create a D3D device.\n");
11059 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
11060 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11061 color
= getPixelColor(device
, 1, 1);
11062 ok(color
== 0x00ff0000, "Got unexpected color 0x%08x.\n", color
);
11064 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
11065 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
11067 refcount
= IDirect3DDevice8_Release(device
);
11068 ok(!refcount
, "Device has %u references left.\n", refcount
);
11070 IDirect3D8_Release(d3d
);
11075 D3DADAPTER_IDENTIFIER8 identifier
;
11079 if (!(d3d
= Direct3DCreate8(D3D_SDK_VERSION
)))
11081 skip("Failed to create D3D8 object.\n");
11085 memset(&identifier
, 0, sizeof(identifier
));
11086 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
11087 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#x.\n", hr
);
11088 trace("Driver string: \"%s\"\n", identifier
.Driver
);
11089 trace("Description string: \"%s\"\n", identifier
.Description
);
11090 /* Only Windows XP's default VGA driver should have an empty description */
11091 ok(identifier
.Description
[0] || broken(!strcmp(identifier
.Driver
, "vga.dll")), "Empty driver description.\n");
11092 trace("Driver version %d.%d.%d.%d\n",
11093 HIWORD(U(identifier
.DriverVersion
).HighPart
), LOWORD(U(identifier
.DriverVersion
).HighPart
),
11094 HIWORD(U(identifier
.DriverVersion
).LowPart
), LOWORD(U(identifier
.DriverVersion
).LowPart
));
11096 IDirect3D8_Release(d3d
);
11099 depth_clamp_test();
11101 test_specular_lighting();
11107 test_scalar_instructions();
11108 fog_with_shader_test();
11112 depth_buffer_test();
11113 depth_buffer2_test();
11116 multisample_copy_rects_test();
11119 fog_special_test();
11120 volume_dxtn_test();
11121 volume_v16u16_test();
11122 add_dirty_rect_test();
11123 test_3dc_formats();
11124 test_fog_interpolation();
11125 test_negative_fixedfunction_fog();
11126 test_table_fog_zw();
11127 test_signed_formats();
11128 test_updatetexture();
11130 test_multisample_mismatch();
11131 test_texcoordindex();
11132 test_vshader_input();
11133 test_fixed_function_fvf();
11135 test_uninitialized_varyings();
11137 test_multisample_init();
11138 test_texture_blending();
11139 test_color_clamping();
11140 test_edge_antialiasing_blending();
11141 test_max_index16();
11142 test_backbuffer_resize();
11143 test_drawindexedprimitiveup();
11144 test_map_synchronisation();
11146 test_color_vertex();
11147 test_sysmem_draw();
11149 test_desktop_window();