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 */
24 #include "wine/test.h"
41 static BOOL
color_match(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
43 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
45 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
47 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
49 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
53 static DWORD
getPixelColor(IDirect3DDevice8
*device
, UINT x
, UINT y
)
56 IDirect3DTexture8
*tex
= NULL
;
57 IDirect3DSurface8
*surf
= NULL
, *backbuf
= NULL
;
59 D3DLOCKED_RECT lockedRect
;
60 RECT rectToLock
= {x
, y
, x
+1, y
+1};
62 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8
, D3DPOOL_SYSTEMMEM
, &tex
);
63 if(FAILED(hr
) || !tex
) /* This is not a test */
65 trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr
);
68 hr
= IDirect3DTexture8_GetSurfaceLevel(tex
, 0, &surf
);
69 if(FAILED(hr
) || !tex
) /* This is not a test */
71 trace("Can't get surface from texture, hr=%#08x\n", hr
);
76 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuf
);
79 trace("Can't get the render target, hr=%#08x\n", hr
);
83 hr
= IDirect3DDevice8_CopyRects(device
, backbuf
, NULL
, 0, surf
, NULL
);
86 trace("Can't read the render target, hr=%#08x\n", hr
);
91 hr
= IDirect3DSurface8_LockRect(surf
, &lockedRect
, &rectToLock
, D3DLOCK_READONLY
);
94 trace("Can't lock the offscreen surface, hr=%#08x\n", hr
);
98 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
99 * really important for these tests
101 ret
= ((DWORD
*) lockedRect
.pBits
)[0] & 0x00ffffff;
102 hr
= IDirect3DSurface8_UnlockRect(surf
);
105 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr
);
109 if(backbuf
) IDirect3DSurface8_Release(backbuf
);
110 if(surf
) IDirect3DSurface8_Release(surf
);
111 if(tex
) IDirect3DTexture8_Release(tex
);
115 static IDirect3DDevice8
*create_device(IDirect3D8
*d3d
, HWND device_window
, HWND focus_window
, BOOL windowed
)
117 D3DPRESENT_PARAMETERS present_parameters
= {0};
118 IDirect3DDevice8
*device
;
120 present_parameters
.Windowed
= windowed
;
121 present_parameters
.hDeviceWindow
= device_window
;
122 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
123 present_parameters
.BackBufferWidth
= 640;
124 present_parameters
.BackBufferHeight
= 480;
125 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
126 present_parameters
.EnableAutoDepthStencil
= TRUE
;
127 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
129 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
130 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
)))
143 static void test_sanity(void)
145 IDirect3DDevice8
*device
;
152 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
153 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
154 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
155 ok(!!d3d
, "Failed to create a D3D object.\n");
156 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
158 skip("Failed to create a D3D device, skipping tests.\n");
162 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
163 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
164 color
= getPixelColor(device
, 1, 1);
165 ok(color
== 0x00ff0000, "Got unexpected color 0x%08x.\n", color
);
167 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
168 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
170 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ddee, 1.0f
, 0);
171 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
172 color
= getPixelColor(device
, 639, 479);
173 ok(color
== 0x0000ddee, "Got unexpected color 0x%08x.\n", color
);
175 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
176 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
178 refcount
= IDirect3DDevice8_Release(device
);
179 ok(!refcount
, "Device has %u references left.\n", refcount
);
181 IDirect3D8_Release(d3d
);
182 DestroyWindow(window
);
185 static void lighting_test(void)
187 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
188 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
189 IDirect3DDevice8
*device
;
198 struct vec3 position
;
203 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
204 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
205 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
206 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
210 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
211 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
212 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
213 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
215 static const struct nvertex unlitnquad
[] =
217 { 0.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
218 { 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
219 { 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
220 { 1.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
222 static const struct nvertex litnquad
[] =
224 { 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xffffff00},
225 { 0.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xffffff00},
226 { 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xffffff00},
227 { 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xffffff00},
229 static const WORD Indices
[] = {0, 1, 2, 2, 3, 0};
230 static const D3DMATRIX mat
=
232 1.0f
, 0.0f
, 0.0f
, 0.0f
,
233 0.0f
, 1.0f
, 0.0f
, 0.0f
,
234 0.0f
, 0.0f
, 1.0f
, 0.0f
,
235 0.0f
, 0.0f
, 0.0f
, 1.0f
,
238 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
239 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
240 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
241 ok(!!d3d
, "Failed to create a D3D object.\n");
242 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
244 skip("Failed to create a D3D device, skipping tests.\n");
248 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
249 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
251 /* Setup some states that may cause issues */
252 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &mat
);
253 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
254 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_VIEW
, &mat
);
255 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
256 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &mat
);
257 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
258 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
259 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
260 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
261 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
262 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
263 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
264 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_STENCILENABLE
, FALSE
);
265 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
266 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHATESTENABLE
, FALSE
);
267 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
268 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, FALSE
);
269 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
270 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CULLMODE
, D3DCULL_NONE
);
271 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr
);
272 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
);
273 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr
);
275 hr
= IDirect3DDevice8_SetVertexShader(device
, fvf
);
276 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
278 hr
= IDirect3DDevice8_BeginScene(device
);
279 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
281 /* No lights are defined... That means, lit vertices should be entirely black. */
282 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
283 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
284 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
285 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, unlitquad
, sizeof(unlitquad
[0]));
286 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
288 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
289 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
290 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
291 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, litquad
, sizeof(litquad
[0]));
292 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
294 hr
= IDirect3DDevice8_SetVertexShader(device
, nfvf
);
295 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
297 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
298 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
299 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
300 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, unlitnquad
, sizeof(unlitnquad
[0]));
301 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
303 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
304 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
305 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
306 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, litnquad
, sizeof(litnquad
[0]));
307 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
309 hr
= IDirect3DDevice8_EndScene(device
);
310 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
312 color
= getPixelColor(device
, 160, 360); /* Lower left quad - unlit without normals */
313 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color
);
314 color
= getPixelColor(device
, 160, 120); /* Upper left quad - lit without normals */
315 ok(color
== 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color
);
316 color
= getPixelColor(device
, 480, 360); /* Lower right quad - unlit with normals */
317 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color
);
318 color
= getPixelColor(device
, 480, 120); /* Upper right quad - lit with normals */
319 ok(color
== 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color
);
321 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
323 refcount
= IDirect3DDevice8_Release(device
);
324 ok(!refcount
, "Device has %u references left.\n", refcount
);
326 IDirect3D8_Release(d3d
);
327 DestroyWindow(window
);
330 static void clear_test(void)
332 /* Tests the correctness of clearing parameters */
333 D3DRECT rect_negneg
, rect
[2];
334 IDirect3DDevice8
*device
;
341 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
342 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
343 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
344 ok(!!d3d
, "Failed to create a D3D object.\n");
345 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
347 skip("Failed to create a D3D device, skipping tests.\n");
351 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
352 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
354 /* Positive x, negative y */
360 /* Positive x, positive y */
365 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
366 * is ignored, the positive is still cleared afterwards
368 hr
= IDirect3DDevice8_Clear(device
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
369 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
371 /* negative x, negative y */
372 rect_negneg
.x1
= 640;
373 rect_negneg
.y1
= 240;
374 rect_negneg
.x2
= 320;
376 hr
= IDirect3DDevice8_Clear(device
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
377 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
379 color
= getPixelColor(device
, 160, 360); /* lower left quad */
380 ok(color
== 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color
);
381 color
= getPixelColor(device
, 160, 120); /* upper left quad */
382 ok(color
== 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color
);
383 color
= getPixelColor(device
, 480, 360); /* lower right quad */
384 ok(color
== 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color
);
385 color
= getPixelColor(device
, 480, 120); /* upper right quad */
386 ok(color
== 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color
);
388 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
390 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
391 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
397 hr
= IDirect3DDevice8_Clear(device
, 0, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
398 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
400 color
= getPixelColor(device
, 320, 240);
401 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
402 "Clear with count = 0, rect != NULL has color %#08x\n", color
);
404 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
406 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
407 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
408 hr
= IDirect3DDevice8_Clear(device
, 1, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
409 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
411 color
= getPixelColor(device
, 320, 240);
412 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
413 "Clear with count = 1, rect = NULL has color %#08x\n", color
);
415 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
417 refcount
= IDirect3DDevice8_Release(device
);
418 ok(!refcount
, "Device has %u references left.\n", refcount
);
420 IDirect3D8_Release(d3d
);
421 DestroyWindow(window
);
424 static void fog_test(void)
426 float start
= 0.0f
, end
= 1.0f
;
427 IDirect3DDevice8
*device
;
435 /* Gets full z based fog with linear fog, no fog with specular color. */
444 {-1.0f
, -1.0f
, 0.1f
, 0xffff0000, 0xff000000},
445 {-1.0f
, 0.0f
, 0.1f
, 0xffff0000, 0xff000000},
446 { 0.0f
, 0.0f
, 0.1f
, 0xffff0000, 0xff000000},
447 { 0.0f
, -1.0f
, 0.1f
, 0xffff0000, 0xff000000},
449 /* Ok, I am too lazy to deal with transform matrices. */
452 {-1.0f
, 0.0f
, 1.0f
, 0xffff0000, 0xff000000},
453 {-1.0f
, 1.0f
, 1.0f
, 0xffff0000, 0xff000000},
454 { 0.0f
, 1.0f
, 1.0f
, 0xffff0000, 0xff000000},
455 { 0.0f
, 0.0f
, 1.0f
, 0xffff0000, 0xff000000},
459 {-1.0f
, -1.0f
, 0.5f
, 0xffff0000, 0xff000000},
460 {-1.0f
, 0.0f
, 0.5f
, 0xffff0000, 0xff000000},
461 { 0.0f
, 0.0f
, 0.5f
, 0xffff0000, 0xff000000},
462 { 0.0f
, -1.0f
, 0.5f
, 0xffff0000, 0xff000000},
466 {-1.0f
, 0.0f
, 1.5f
, 0xffff0000, 0xff000000},
467 {-1.0f
, 1.0f
, 1.5f
, 0xffff0000, 0xff000000},
468 { 0.0f
, 1.0f
, 1.5f
, 0xffff0000, 0xff000000},
469 { 0.0f
, 0.0f
, 1.5f
, 0xffff0000, 0xff000000},
472 /* Untransformed ones. Give them a different diffuse color to make the
473 * test look nicer. It also makes making sure that they are drawn
474 * correctly easier. */
483 {320.0f
, 0.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
484 {640.0f
, 0.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
485 {640.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
486 {320.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
490 {320.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
491 {640.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
492 {640.0f
, 480.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
493 {320.0f
, 480.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
495 static const D3DMATRIX ident_mat
=
497 1.0f
, 0.0f
, 0.0f
, 0.0f
,
498 0.0f
, 1.0f
, 0.0f
, 0.0f
,
499 0.0f
, 0.0f
, 1.0f
, 0.0f
,
500 0.0f
, 0.0f
, 0.0f
, 1.0f
,
502 static const D3DMATRIX world_mat1
=
504 1.0f
, 0.0f
, 0.0f
, 0.0f
,
505 0.0f
, 1.0f
, 0.0f
, 0.0f
,
506 0.0f
, 0.0f
, 1.0f
, 0.0f
,
507 0.0f
, 0.0f
, -0.5f
, 1.0f
,
509 static const D3DMATRIX world_mat2
=
511 1.0f
, 0.0f
, 0.0f
, 0.0f
,
512 0.0f
, 1.0f
, 0.0f
, 0.0f
,
513 0.0f
, 0.0f
, 1.0f
, 0.0f
,
514 0.0f
, 0.0f
, 1.0f
, 1.0f
,
516 static const D3DMATRIX proj_mat
=
518 1.0f
, 0.0f
, 0.0f
, 0.0f
,
519 0.0f
, 1.0f
, 0.0f
, 0.0f
,
520 0.0f
, 0.0f
, 1.0f
, 0.0f
,
521 0.0f
, 0.0f
, -1.0f
, 1.0f
,
523 static const WORD Indices
[] = {0, 1, 2, 2, 3, 0};
525 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
526 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
527 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
528 ok(!!d3d
, "Failed to create a D3D object.\n");
529 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
531 skip("Failed to create a D3D device, skipping tests.\n");
535 memset(&caps
, 0, sizeof(caps
));
536 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
537 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr
);
538 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
539 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %#08x\n", hr
);
541 /* Setup initial states: No lighting, fog on, fog color */
542 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
543 ok(SUCCEEDED(hr
), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr
);
544 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
545 ok(hr
== D3D_OK
, "Turning off lighting returned %#08x\n", hr
);
546 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
547 ok(hr
== D3D_OK
, "Turning on fog calculations returned %#08x\n", hr
);
548 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xFF00FF00 /* A nice green */);
549 ok(hr
== D3D_OK
, "Setting fog color returned %#08x\n", hr
);
550 /* Some of the tests seem to depend on the projection matrix explicitly
551 * being set to an identity matrix, even though that's the default.
552 * (AMD Radeon HD 6310, Windows 7) */
553 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &ident_mat
);
554 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
556 /* First test: Both table fog and vertex fog off */
557 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
558 ok(hr
== D3D_OK
, "Turning off table fog returned %#08x\n", hr
);
559 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
560 ok(hr
== D3D_OK
, "Turning off vertex fog returned %#08x\n", hr
);
562 /* Start = 0, end = 1. Should be default, but set them */
563 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, *((DWORD
*) &start
));
564 ok(hr
== D3D_OK
, "Setting fog start returned %#08x\n", hr
);
565 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, *((DWORD
*) &end
));
566 ok(hr
== D3D_OK
, "Setting fog start returned %#08x\n", hr
);
568 hr
= IDirect3DDevice8_BeginScene(device
);
569 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
571 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
572 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
573 /* Untransformed, vertex fog = NONE, table fog = NONE:
574 * Read the fog weighting from the specular color. */
575 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
576 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, untransformed_1
, sizeof(untransformed_1
[0]));
577 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
579 /* This makes it use the Z value. */
580 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_LINEAR
);
581 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
582 /* Untransformed, vertex fog != none (or table fog != none):
583 * Use the Z value as input into the equation. */
584 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
585 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, untransformed_2
, sizeof(untransformed_2
[0]));
586 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
588 /* Transformed vertices. */
589 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
590 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
591 /* Transformed, vertex fog != NONE, pixel fog == NONE:
592 * Use specular color alpha component. */
593 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
594 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, transformed_1
, sizeof(transformed_1
[0]));
595 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
597 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
598 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
599 /* Transformed, table fog != none, vertex anything:
600 * Use Z value as input to the fog equation. */
601 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
602 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, transformed_2
, sizeof(transformed_2
[0]));
603 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
605 hr
= IDirect3DDevice8_EndScene(device
);
606 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
608 color
= getPixelColor(device
, 160, 360);
609 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
610 "Untransformed vertex with no table or vertex fog has color %08x\n", color
);
611 color
= getPixelColor(device
, 160, 120);
612 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
613 "Untransformed vertex with linear vertex fog has color %08x\n", color
);
614 color
= getPixelColor(device
, 480, 120);
615 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
616 "Transformed vertex with linear vertex fog has color %08x\n", color
);
617 color
= getPixelColor(device
, 480, 360);
618 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
619 "Transformed vertex with linear table fog has color %08x\n", color
);
621 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
623 if (caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
)
625 /* A simple fog + non-identity world matrix test */
626 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &world_mat1
);
627 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
629 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
630 ok(hr
== D3D_OK
, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr
);
631 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
632 ok(hr
== D3D_OK
, "Turning off vertex fog returned %#08x\n", hr
);
634 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
635 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %#08x\n", hr
);
637 hr
= IDirect3DDevice8_BeginScene(device
);
638 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
639 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
640 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
641 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
642 2, Indices
, D3DFMT_INDEX16
, far_quad1
, sizeof(far_quad1
[0]));
643 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
644 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
645 2, Indices
, D3DFMT_INDEX16
, far_quad2
, sizeof(far_quad2
[0]));
646 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
647 hr
= IDirect3DDevice8_EndScene(device
);
648 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
650 color
= getPixelColor(device
, 160, 360);
651 ok(color_match(color
, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color
);
652 color
= getPixelColor(device
, 160, 120);
653 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
654 "Fogged out quad has color %08x\n", color
);
656 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
658 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
659 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &world_mat2
);
660 ok(hr
== D3D_OK
, "SetTransform returned %#08x\n", hr
);
661 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &proj_mat
);
662 ok(hr
== D3D_OK
, "SetTransform returned %#08x\n", hr
);
664 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
665 ok(hr
== D3D_OK
, "Clear returned %#08x\n", hr
);
667 hr
= IDirect3DDevice8_BeginScene(device
);
668 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
669 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
670 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
671 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
672 2, Indices
, D3DFMT_INDEX16
, untransformed_1
, sizeof(untransformed_1
[0]));
673 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
674 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
675 2, Indices
, D3DFMT_INDEX16
, untransformed_2
, sizeof(untransformed_2
[0]));
676 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
677 hr
= IDirect3DDevice8_EndScene(device
);
678 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
680 color
= getPixelColor(device
, 160, 360);
681 ok(color_match(color
, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color
);
682 color
= getPixelColor(device
, 160, 120);
683 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
684 "Fogged out quad has color %08x\n", color
);
686 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
690 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
693 refcount
= IDirect3DDevice8_Release(device
);
694 ok(!refcount
, "Device has %u references left.\n", refcount
);
696 IDirect3D8_Release(d3d
);
697 DestroyWindow(window
);
700 /* This tests fog in combination with shaders.
701 * What's tested: linear fog (vertex and table) with pixel shader
702 * linear table fog with non foggy vertex shader
703 * vertex fog with foggy vertex shader, non-linear
704 * fog with shader, non-linear fog with foggy shader,
705 * linear table fog with foggy shader */
706 static void fog_with_shader_test(void)
708 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
709 DWORD vertex_shader
[3] = {D3DFVF_XYZ
| D3DFVF_DIFFUSE
, 0, 0};
710 DWORD pixel_shader
[2] = {0, 0};
711 IDirect3DDevice8
*device
;
725 /* Basic vertex shader without fog computation ("non foggy") */
726 static const DWORD vertex_shader_code1
[] =
728 0xfffe0100, /* vs.1.0 */
729 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
730 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
733 /* Basic vertex shader with reversed fog computation ("foggy") */
734 static const DWORD vertex_shader_code2
[] =
736 0xfffe0100, /* vs.1.0 */
737 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
738 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
739 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
740 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
743 /* Basic pixel shader */
744 static const DWORD pixel_shader_code
[] =
746 0xffff0101, /* ps_1_1 */
747 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
752 struct vec3 position
;
757 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
758 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
759 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
760 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
762 static const DWORD decl
[] =
765 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
766 D3DVSD_REG(1, D3DVSDT_D3DCOLOR
), /* diffuse color, v1 */
769 static const float vs_constant
[4] = {-1.25f
, 0.0f
, -0.9f
, 0.0f
};
770 /* This reference data was collected on a nVidia GeForce 7600GS
771 * driver version 84.19 DirectX version 9.0c on Windows XP */
772 static const struct test_data_t
778 unsigned int color
[11];
782 /* Only pixel shader */
783 {0, 1, D3DFOG_NONE
, D3DFOG_LINEAR
,
784 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
785 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
786 {0, 1, D3DFOG_EXP
, D3DFOG_LINEAR
,
787 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
788 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
789 {0, 1, D3DFOG_EXP2
, D3DFOG_LINEAR
,
790 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
791 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
792 {0, 1, D3DFOG_LINEAR
, D3DFOG_NONE
,
793 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
794 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
795 {0, 1, D3DFOG_LINEAR
, D3DFOG_LINEAR
,
796 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
797 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
800 {1, 0, D3DFOG_NONE
, D3DFOG_NONE
,
801 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
802 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
803 {1, 0, D3DFOG_NONE
, D3DFOG_LINEAR
,
804 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
805 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
806 {1, 0, D3DFOG_EXP
, D3DFOG_LINEAR
,
807 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
808 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
810 {1, 0, D3DFOG_EXP2
, D3DFOG_LINEAR
,
811 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
812 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
813 {1, 0, D3DFOG_LINEAR
, D3DFOG_LINEAR
,
814 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
815 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
817 /* Vertex shader and pixel shader */
818 /* The next 4 tests would read the fog coord output, but it isn't available.
819 * The result is a fully fogged quad, no matter what the Z coord is. */
820 {1, 1, D3DFOG_NONE
, D3DFOG_NONE
,
821 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
822 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
823 {1, 1, D3DFOG_LINEAR
, D3DFOG_NONE
,
824 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
825 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
826 {1, 1, D3DFOG_EXP
, D3DFOG_NONE
,
827 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
828 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
829 {1, 1, D3DFOG_EXP2
, D3DFOG_NONE
,
830 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
831 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
833 /* These use the Z coordinate with linear table fog */
834 {1, 1, D3DFOG_NONE
, D3DFOG_LINEAR
,
835 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
836 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
837 {1, 1, D3DFOG_EXP
, D3DFOG_LINEAR
,
838 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
839 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
840 {1, 1, D3DFOG_EXP2
, D3DFOG_LINEAR
,
841 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
842 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
843 {1, 1, D3DFOG_LINEAR
, D3DFOG_LINEAR
,
844 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
845 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
847 /* Non-linear table fog without fog coord */
848 {1, 1, D3DFOG_NONE
, D3DFOG_EXP
,
849 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
850 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
851 {1, 1, D3DFOG_NONE
, D3DFOG_EXP2
,
852 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
853 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
855 /* These tests fail on older Nvidia drivers */
856 /* Foggy vertex shader */
857 {2, 0, D3DFOG_NONE
, D3DFOG_NONE
,
858 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
859 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
860 {2, 0, D3DFOG_EXP
, D3DFOG_NONE
,
861 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
862 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
863 {2, 0, D3DFOG_EXP2
, D3DFOG_NONE
,
864 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
865 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
866 {2, 0, D3DFOG_LINEAR
, D3DFOG_NONE
,
867 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
868 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
870 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
871 * all using the fixed fog-coord linear fog */
872 {2, 1, D3DFOG_NONE
, D3DFOG_NONE
,
873 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
874 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
875 {2, 1, D3DFOG_EXP
, D3DFOG_NONE
,
876 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
877 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
878 {2, 1, D3DFOG_EXP2
, D3DFOG_NONE
,
879 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
880 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
881 {2, 1, D3DFOG_LINEAR
, D3DFOG_NONE
,
882 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
883 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
885 /* These use table fog. Here the shader-provided fog coordinate is
886 * ignored and the z coordinate used instead */
887 {2, 1, D3DFOG_NONE
, D3DFOG_EXP
,
888 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
889 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
890 {2, 1, D3DFOG_NONE
, D3DFOG_EXP2
,
891 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
892 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
893 {2, 1, D3DFOG_NONE
, D3DFOG_LINEAR
,
894 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
895 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
897 static const D3DMATRIX identity
=
899 1.0f
, 0.0f
, 0.0f
, 0.0f
,
900 0.0f
, 1.0f
, 0.0f
, 0.0f
,
901 0.0f
, 0.0f
, 1.0f
, 0.0f
,
902 0.0f
, 0.0f
, 0.0f
, 1.0f
,
905 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
906 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
907 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
908 ok(!!d3d
, "Failed to create a D3D object.\n");
909 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
911 skip("Failed to create a D3D device, skipping tests.\n");
915 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
916 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
917 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1) || caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
919 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
920 IDirect3DDevice8_Release(device
);
924 /* NOTE: changing these values will not affect the tests with foggy vertex
925 * shader, as the values are hardcoded in the shader constant. */
929 /* Some of the tests seem to depend on the projection matrix explicitly
930 * being set to an identity matrix, even though that's the default.
931 * (AMD Radeon HD 6310, Windows 7) */
932 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
933 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
935 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vertex_shader_code1
, &vertex_shader
[1], 0);
936 ok(SUCCEEDED(hr
), "CreateVertexShader failed (%08x)\n", hr
);
937 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vertex_shader_code2
, &vertex_shader
[2], 0);
938 ok(SUCCEEDED(hr
), "CreateVertexShader failed (%08x)\n", hr
);
939 hr
= IDirect3DDevice8_CreatePixelShader(device
, pixel_shader_code
, &pixel_shader
[1]);
940 ok(SUCCEEDED(hr
), "CreatePixelShader failed (%08x)\n", hr
);
942 /* Set shader constant value */
943 hr
= IDirect3DDevice8_SetVertexShader(device
, vertex_shader
[2]);
944 ok(SUCCEEDED(hr
), "SetVertexShader failed (%08x)\n", hr
);
945 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, vs_constant
, 1);
946 ok(hr
== D3D_OK
, "Setting vertex shader constant failed (%08x)\n", hr
);
948 /* Setup initial states: No lighting, fog on, fog color */
949 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
950 ok(hr
== D3D_OK
, "Turning off lighting failed (%08x)\n", hr
);
951 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
952 ok(hr
== D3D_OK
, "Turning on fog calculations failed (%08x)\n", hr
);
953 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xFF00FF00 /* A nice green */);
954 ok(hr
== D3D_OK
, "Setting fog color failed (%08x)\n", hr
);
956 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
957 ok(hr
== D3D_OK
, "Turning off table fog failed (%08x)\n", hr
);
958 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
959 ok(hr
== D3D_OK
, "Turning off vertex fog failed (%08x)\n", hr
);
961 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
962 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, start
.i
);
963 ok(hr
== D3D_OK
, "Setting fog start failed (%08x)\n", hr
);
964 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, end
.i
);
965 ok(hr
== D3D_OK
, "Setting fog end failed (%08x)\n", hr
);
967 for (i
= 0; i
< sizeof(test_data
)/sizeof(test_data
[0]); ++i
)
969 hr
= IDirect3DDevice8_SetVertexShader(device
, vertex_shader
[test_data
[i
].vshader
]);
970 ok(SUCCEEDED(hr
), "SetVertexShader failed (%08x)\n", hr
);
971 hr
= IDirect3DDevice8_SetPixelShader(device
, pixel_shader
[test_data
[i
].pshader
]);
972 ok(SUCCEEDED(hr
), "SetPixelShader failed (%08x)\n", hr
);
973 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, test_data
[i
].vfog
);
974 ok( hr
== D3D_OK
, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr
);
975 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, test_data
[i
].tfog
);
976 ok( hr
== D3D_OK
, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr
);
978 for(j
= 0; j
< 11; ++j
)
980 /* Don't use the whole zrange to prevent rounding errors */
981 quad
[0].position
.z
= 0.001f
+ j
/ 10.02f
;
982 quad
[1].position
.z
= 0.001f
+ j
/ 10.02f
;
983 quad
[2].position
.z
= 0.001f
+ j
/ 10.02f
;
984 quad
[3].position
.z
= 0.001f
+ j
/ 10.02f
;
986 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff00ff, 1.0f
, 0);
987 ok(hr
== D3D_OK
, "IDirect3DDevice9_Clear failed (%08x)\n", hr
);
989 hr
= IDirect3DDevice8_BeginScene(device
);
990 ok( hr
== D3D_OK
, "BeginScene returned failed (%08x)\n", hr
);
992 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(quad
[0]));
993 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed (%08x)\n", hr
);
995 hr
= IDirect3DDevice8_EndScene(device
);
996 ok(hr
== D3D_OK
, "EndScene failed (%08x)\n", hr
);
998 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
999 color
= getPixelColor(device
, 128, 240);
1000 ok(color_match(color
, test_data
[i
].color
[j
], 13),
1001 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1002 test_data
[i
].vshader
, test_data
[i
].pshader
,
1003 test_data
[i
].vfog
, test_data
[i
].tfog
, j
, color
, test_data
[i
].color
[j
]);
1005 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1009 IDirect3DDevice8_DeleteVertexShader(device
, vertex_shader
[1]);
1010 IDirect3DDevice8_DeleteVertexShader(device
, vertex_shader
[2]);
1011 IDirect3DDevice8_DeleteVertexShader(device
, pixel_shader
[1]);
1012 refcount
= IDirect3DDevice8_Release(device
);
1013 ok(!refcount
, "Device has %u references left.\n", refcount
);
1015 IDirect3D8_Release(d3d
);
1016 DestroyWindow(window
);
1019 static void cnd_test(void)
1021 DWORD shader_11_coissue_2
, shader_12_coissue_2
, shader_13_coissue_2
, shader_14_coissue_2
;
1022 DWORD shader_11_coissue
, shader_12_coissue
, shader_13_coissue
, shader_14_coissue
;
1023 DWORD shader_11
, shader_12
, shader_13
, shader_14
;
1024 IDirect3DDevice8
*device
;
1032 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1033 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1034 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1035 * in 1.x pixel shaders. */
1036 static const DWORD shader_code_11
[] =
1038 0xffff0101, /* ps_1_1 */
1039 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1040 0x00000040, 0xb00f0000, /* texcoord t0 */
1041 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1042 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1043 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1044 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1045 0x0000ffff /* end */
1047 static const DWORD shader_code_12
[] =
1049 0xffff0102, /* ps_1_2 */
1050 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1051 0x00000040, 0xb00f0000, /* texcoord t0 */
1052 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1053 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1054 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1055 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1056 0x0000ffff /* end */
1058 static const DWORD shader_code_13
[] =
1060 0xffff0103, /* ps_1_3 */
1061 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1062 0x00000040, 0xb00f0000, /* texcoord t0 */
1063 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1064 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1065 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1066 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1067 0x0000ffff /* end */
1069 static const DWORD shader_code_14
[] =
1071 0xffff0104, /* ps_1_3 */
1072 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1073 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1074 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1075 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1076 0x0000ffff /* end */
1079 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1080 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1081 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1082 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1083 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1086 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1087 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1088 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1089 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1091 static const DWORD shader_code_11_coissue
[] =
1093 0xffff0101, /* ps_1_1 */
1094 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1095 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1096 0x00000040, 0xb00f0000, /* texcoord t0 */
1097 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1098 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1099 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1100 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1101 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1102 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1103 0x0000ffff /* end */
1105 static const DWORD shader_code_11_coissue_2
[] =
1107 0xffff0101, /* ps_1_1 */
1108 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1109 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1110 0x00000040, 0xb00f0000, /* texcoord t0 */
1111 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1112 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1113 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1114 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1115 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1116 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1117 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1118 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1119 0x0000ffff /* end */
1121 static const DWORD shader_code_12_coissue
[] =
1123 0xffff0102, /* ps_1_2 */
1124 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1125 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1126 0x00000040, 0xb00f0000, /* texcoord t0 */
1127 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1128 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1129 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1130 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1131 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1132 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1133 0x0000ffff /* end */
1135 static const DWORD shader_code_12_coissue_2
[] =
1137 0xffff0102, /* ps_1_2 */
1138 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1139 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1140 0x00000040, 0xb00f0000, /* texcoord t0 */
1141 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1142 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1143 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1144 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1145 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1146 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1147 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1148 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1149 0x0000ffff /* end */
1151 static const DWORD shader_code_13_coissue
[] =
1153 0xffff0103, /* ps_1_3 */
1154 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1155 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1156 0x00000040, 0xb00f0000, /* texcoord t0 */
1157 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1158 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1159 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1160 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1161 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1162 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1163 0x0000ffff /* end */
1165 static const DWORD shader_code_13_coissue_2
[] =
1167 0xffff0103, /* ps_1_3 */
1168 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1169 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1170 0x00000040, 0xb00f0000, /* texcoord t0 */
1171 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1172 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1173 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1174 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1175 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1176 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1177 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1178 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1179 0x0000ffff /* end */
1181 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1182 * texcrd result to cnd, it will compare against 0.5. */
1183 static const DWORD shader_code_14_coissue
[] =
1185 0xffff0104, /* ps_1_4 */
1186 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1187 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1188 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1189 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1190 0x0000ffff /* end */
1192 static const DWORD shader_code_14_coissue_2
[] =
1194 0xffff0104, /* ps_1_4 */
1195 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1196 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1197 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1198 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1199 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1200 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1201 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1202 0x0000ffff /* end */
1204 static const float quad1
[] =
1206 -1.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1207 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1208 0.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1209 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1211 static const float quad2
[] =
1213 0.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1214 0.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1215 1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1216 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1218 static const float quad3
[] =
1220 0.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1221 0.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1222 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1223 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1225 static const float quad4
[] =
1227 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1228 -1.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1229 0.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1230 0.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1232 static const float test_data_c1
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
1233 static const float test_data_c2
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
1234 static const float test_data_c1_coi
[4] = {0.0f
, 1.0f
, 0.0f
, 0.0f
};
1235 static const float test_data_c2_coi
[4] = {1.0f
, 0.0f
, 1.0f
, 1.0f
};
1237 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1238 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
1239 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1240 ok(!!d3d
, "Failed to create a D3D object.\n");
1241 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1243 skip("Failed to create a D3D device, skipping tests.\n");
1247 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1248 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1249 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 4))
1251 skip("No ps_1_4 support, skipping tests.\n");
1252 IDirect3DDevice8_Release(device
);
1256 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
1257 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1259 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11
, &shader_11
);
1260 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1261 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12
, &shader_12
);
1262 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1263 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13
, &shader_13
);
1264 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1265 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14
, &shader_14
);
1266 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1267 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11_coissue
, &shader_11_coissue
);
1268 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1269 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12_coissue
, &shader_12_coissue
);
1270 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1271 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13_coissue
, &shader_13_coissue
);
1272 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1273 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14_coissue
, &shader_14_coissue
);
1274 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1275 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11_coissue_2
, &shader_11_coissue_2
);
1276 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1277 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12_coissue_2
, &shader_12_coissue_2
);
1278 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1279 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13_coissue_2
, &shader_13_coissue_2
);
1280 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1281 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14_coissue_2
, &shader_14_coissue_2
);
1282 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1284 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, test_data_c1
, 1);
1285 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1286 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 2, test_data_c2
, 1);
1287 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1288 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
1289 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1291 hr
= IDirect3DDevice8_BeginScene(device
);
1292 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1294 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11
);
1295 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1296 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1297 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1299 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12
);
1300 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1301 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1302 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1304 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13
);
1305 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1306 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1307 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1309 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14
);
1310 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1311 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1312 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1314 hr
= IDirect3DDevice8_EndScene(device
);
1315 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1317 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
1318 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1320 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1321 color
= getPixelColor(device
, 158, 118);
1322 ok(color
== 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color
);
1323 color
= getPixelColor(device
, 162, 118);
1324 ok(color
== 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color
);
1325 color
= getPixelColor(device
, 158, 122);
1326 ok(color
== 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color
);
1327 color
= getPixelColor(device
, 162, 122);
1328 ok(color
== 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color
);
1330 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1331 color
= getPixelColor(device
, 158, 358);
1332 ok(color
== 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color
);
1333 color
= getPixelColor(device
, 162, 358);
1334 ok(color_match(color
, 0x00000000, 1),
1335 "pixel 162, 358 has color %08x, expected 0x00000000\n", color
);
1336 color
= getPixelColor(device
, 158, 362);
1337 ok(color
== 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color
);
1338 color
= getPixelColor(device
, 162, 362);
1339 ok(color_match(color
, 0x00000000, 1),
1340 "pixel 162, 362 has color %08x, expected 0x00000000\n", color
);
1343 color
= getPixelColor(device
, 478, 358);
1344 ok(color
== 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color
);
1345 color
= getPixelColor(device
, 482, 358);
1346 ok(color_match(color
, 0x00000000, 1),
1347 "pixel 482, 358 has color %08x, expected 0x00000000\n", color
);
1348 color
= getPixelColor(device
, 478, 362);
1349 ok(color
== 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color
);
1350 color
= getPixelColor(device
, 482, 362);
1351 ok(color_match(color
, 0x00000000, 1),
1352 "pixel 482, 362 has color %08x, expected 0x00000000\n", color
);
1355 color
= getPixelColor(device
, 478, 118);
1356 ok(color
== 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color
);
1357 color
= getPixelColor(device
, 482, 118);
1358 ok(color_match(color
, 0x00000000, 1),
1359 "pixel 482, 118 has color %08x, expected 0x00000000\n", color
);
1360 color
= getPixelColor(device
, 478, 122);
1361 ok(color
== 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color
);
1362 color
= getPixelColor(device
, 482, 122);
1363 ok(color_match(color
, 0x00000000, 1),
1364 "pixel 482, 122 has color %08x, expected 0x00000000\n", color
);
1366 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1367 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1369 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ffff, 0.0f
, 0);
1370 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1371 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, test_data_c1_coi
, 1);
1372 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1373 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 2, test_data_c2_coi
, 1);
1374 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1376 hr
= IDirect3DDevice8_BeginScene(device
);
1377 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1379 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11_coissue
);
1380 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1381 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1382 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1384 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12_coissue
);
1385 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1386 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1387 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1389 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13_coissue
);
1390 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1391 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1392 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1394 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14_coissue
);
1395 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1396 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1397 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1399 hr
= IDirect3DDevice8_EndScene(device
);
1400 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1402 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
1403 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1405 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1406 * that we swapped the values in c1 and c2 to make the other tests return some color
1408 color
= getPixelColor(device
, 158, 118);
1409 ok(color
== 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color
);
1410 color
= getPixelColor(device
, 162, 118);
1411 ok(color
== 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color
);
1412 color
= getPixelColor(device
, 158, 122);
1413 ok(color
== 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color
);
1414 color
= getPixelColor(device
, 162, 122);
1415 ok(color
== 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color
);
1417 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1418 * (The Win7 nvidia driver always selects c2)
1420 color
= getPixelColor(device
, 158, 358);
1421 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1422 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color
);
1423 color
= getPixelColor(device
, 162, 358);
1424 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1425 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color
);
1426 color
= getPixelColor(device
, 158, 362);
1427 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1428 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color
);
1429 color
= getPixelColor(device
, 162, 362);
1430 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1431 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color
);
1434 color
= getPixelColor(device
, 478, 358);
1435 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1436 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color
);
1437 color
= getPixelColor(device
, 482, 358);
1438 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1439 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color
);
1440 color
= getPixelColor(device
, 478, 362);
1441 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1442 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color
);
1443 color
= getPixelColor(device
, 482, 362);
1444 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1445 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color
);
1448 color
= getPixelColor(device
, 478, 118);
1449 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1450 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color
);
1451 color
= getPixelColor(device
, 482, 118);
1452 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1453 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color
);
1454 color
= getPixelColor(device
, 478, 122);
1455 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1456 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color
);
1457 color
= getPixelColor(device
, 482, 122);
1458 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1459 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color
);
1461 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1462 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1464 /* Retest with the coissue flag on the alpha instruction instead. This
1465 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1466 * the same as coissue on .rgb. */
1467 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ffff, 0.0f
, 0);
1468 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1470 hr
= IDirect3DDevice8_BeginScene(device
);
1471 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1473 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11_coissue_2
);
1474 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1475 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1476 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1478 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12_coissue_2
);
1479 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1480 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1481 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1483 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13_coissue_2
);
1484 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1485 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1486 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1488 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14_coissue_2
);
1489 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1490 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1491 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1493 hr
= IDirect3DDevice8_EndScene(device
);
1494 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1497 color
= getPixelColor(device
, 158, 118);
1498 ok(color
== 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color
);
1499 color
= getPixelColor(device
, 162, 118);
1500 ok(color
== 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color
);
1501 color
= getPixelColor(device
, 158, 122);
1502 ok(color
== 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color
);
1503 color
= getPixelColor(device
, 162, 122);
1504 ok(color
== 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color
);
1507 color
= getPixelColor(device
, 238, 358);
1508 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1509 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color
);
1510 color
= getPixelColor(device
, 242, 358);
1511 ok(color_match(color
, 0x00000000, 1),
1512 "pixel 242, 358 has color %08x, expected 0x00000000\n", color
);
1513 color
= getPixelColor(device
, 238, 362);
1514 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1515 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color
);
1516 color
= getPixelColor(device
, 242, 362);
1517 ok(color_match(color
, 0x00000000, 1),
1518 "pixel 242, 362 has color %08x, expected 0x00000000\n", color
);
1521 color
= getPixelColor(device
, 558, 358);
1522 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1523 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color
);
1524 color
= getPixelColor(device
, 562, 358);
1525 ok(color_match(color
, 0x00000000, 1),
1526 "pixel 562, 358 has color %08x, expected 0x00000000\n", color
);
1527 color
= getPixelColor(device
, 558, 362);
1528 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1529 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color
);
1530 color
= getPixelColor(device
, 562, 362);
1531 ok(color_match(color
, 0x00000000, 1),
1532 "pixel 562, 362 has color %08x, expected 0x00000000\n", color
);
1535 color
= getPixelColor(device
, 558, 118);
1536 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1537 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color
);
1538 color
= getPixelColor(device
, 562, 118);
1539 ok(color_match(color
, 0x00000000, 1),
1540 "pixel 562, 118 has color %08x, expected 0x00000000\n", color
);
1541 color
= getPixelColor(device
, 558, 122);
1542 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1543 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color
);
1544 color
= getPixelColor(device
, 562, 122);
1545 ok(color_match(color
, 0x00000000, 1),
1546 "pixel 562, 122 has color %08x, expected 0x00000000\n", color
);
1548 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1549 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1551 IDirect3DDevice8_DeletePixelShader(device
, shader_14_coissue_2
);
1552 IDirect3DDevice8_DeletePixelShader(device
, shader_13_coissue_2
);
1553 IDirect3DDevice8_DeletePixelShader(device
, shader_12_coissue_2
);
1554 IDirect3DDevice8_DeletePixelShader(device
, shader_11_coissue_2
);
1555 IDirect3DDevice8_DeletePixelShader(device
, shader_14_coissue
);
1556 IDirect3DDevice8_DeletePixelShader(device
, shader_13_coissue
);
1557 IDirect3DDevice8_DeletePixelShader(device
, shader_12_coissue
);
1558 IDirect3DDevice8_DeletePixelShader(device
, shader_11_coissue
);
1559 IDirect3DDevice8_DeletePixelShader(device
, shader_14
);
1560 IDirect3DDevice8_DeletePixelShader(device
, shader_13
);
1561 IDirect3DDevice8_DeletePixelShader(device
, shader_12
);
1562 IDirect3DDevice8_DeletePixelShader(device
, shader_11
);
1563 refcount
= IDirect3DDevice8_Release(device
);
1564 ok(!refcount
, "Device has %u references left.\n", refcount
);
1566 IDirect3D8_Release(d3d
);
1567 DestroyWindow(window
);
1570 static void z_range_test(void)
1572 IDirect3DDevice8
*device
;
1583 struct vec3 position
;
1588 {{-1.0f
, 0.0f
, 1.1f
}, 0xffff0000},
1589 {{-1.0f
, 1.0f
, 1.1f
}, 0xffff0000},
1590 {{ 1.0f
, 0.0f
, -1.1f
}, 0xffff0000},
1591 {{ 1.0f
, 1.0f
, -1.1f
}, 0xffff0000},
1595 {{-1.0f
, 0.0f
, 1.1f
}, 0xff0000ff},
1596 {{-1.0f
, 1.0f
, 1.1f
}, 0xff0000ff},
1597 {{ 1.0f
, 0.0f
, -1.1f
}, 0xff0000ff},
1598 {{ 1.0f
, 1.0f
, -1.1f
}, 0xff0000ff},
1602 struct vec4 position
;
1607 {{640.0f
, 240.0f
, -1.1f
, 1.0f
}, 0xffffff00},
1608 {{640.0f
, 480.0f
, -1.1f
, 1.0f
}, 0xffffff00},
1609 {{ 0.0f
, 240.0f
, 1.1f
, 1.0f
}, 0xffffff00},
1610 {{ 0.0f
, 480.0f
, 1.1f
, 1.0f
}, 0xffffff00},
1614 {{640.0f
, 240.0f
, -1.1f
, 1.0f
}, 0xff00ff00},
1615 {{640.0f
, 480.0f
, -1.1f
, 1.0f
}, 0xff00ff00},
1616 {{ 0.0f
, 240.0f
, 1.1f
, 1.0f
}, 0xff00ff00},
1617 {{ 0.0f
, 480.0f
, 1.1f
, 1.0f
}, 0xff00ff00},
1619 static const DWORD shader_code
[] =
1621 0xfffe0101, /* vs_1_1 */
1622 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1623 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1624 0x0000ffff /* end */
1626 static const float color_const_1
[] = {1.0f
, 0.0f
, 0.0f
, 1.0f
};
1627 static const float color_const_2
[] = {0.0f
, 0.0f
, 1.0f
, 1.0f
};
1628 static const DWORD vertex_declaration
[] =
1631 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
1635 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1636 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
1637 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1638 ok(!!d3d
, "Failed to create a D3D object.\n");
1639 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1641 skip("Failed to create a D3D device, skipping tests.\n");
1645 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1646 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1648 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1649 * then call Present. Then clear the color buffer to make sure it has some defined content
1650 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1651 * by the depth value. */
1652 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.75f
, 0);
1653 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
1654 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1655 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
1656 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
1657 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
1659 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
1660 ok(SUCCEEDED(hr
), "Failed to disabled lighting, hr %#x.\n", hr
);
1661 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
1662 ok(SUCCEEDED(hr
), "Failed to enable clipping, hr %#x.\n", hr
);
1663 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
1664 ok(SUCCEEDED(hr
), "Failed to enable z test, hr %#x.\n", hr
);
1665 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
1666 ok(SUCCEEDED(hr
), "Failed to disable z writes, hr %#x.\n", hr
);
1667 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_GREATER
);
1668 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1669 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
1670 ok(SUCCEEDED(hr
), "Failed set FVF, hr %#x.\n", hr
);
1672 hr
= IDirect3DDevice8_BeginScene(device
);
1673 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1675 /* Test the untransformed vertex path */
1676 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
1677 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1678 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESS
);
1679 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1680 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
1681 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1683 /* Test the transformed vertex path */
1684 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
1685 ok(SUCCEEDED(hr
), "Failed set FVF, hr %#x.\n", hr
);
1687 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(quad4
[0]));
1688 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1689 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_GREATER
);
1690 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1691 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(quad3
[0]));
1692 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1694 hr
= IDirect3DDevice8_EndScene(device
);
1695 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1697 /* Do not test the exact corner pixels, but go pretty close to them */
1699 /* Clipped because z > 1.0 */
1700 color
= getPixelColor(device
, 28, 238);
1701 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1702 color
= getPixelColor(device
, 28, 241);
1703 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
1704 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1706 ok(color_match(color
, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
1708 /* Not clipped, > z buffer clear value(0.75).
1710 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
1711 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
1712 * equal to a stored depth buffer value of 0.5. */
1713 color
= getPixelColor(device
, 31, 238);
1714 ok(color_match(color
, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1715 color
= getPixelColor(device
, 31, 241);
1716 ok(color_match(color
, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
1717 color
= getPixelColor(device
, 100, 238);
1718 ok(color_match(color
, 0x00ff0000, 0) || broken(color_match(color
, 0x00ffffff, 0)),
1719 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1720 color
= getPixelColor(device
, 100, 241);
1721 ok(color_match(color
, 0x00ffff00, 0) || broken(color_match(color
, 0x00ffffff, 0)),
1722 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
1724 /* Not clipped, < z buffer clear value */
1725 color
= getPixelColor(device
, 104, 238);
1726 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1727 color
= getPixelColor(device
, 104, 241);
1728 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color
);
1729 color
= getPixelColor(device
, 318, 238);
1730 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1731 color
= getPixelColor(device
, 318, 241);
1732 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color
);
1734 /* Clipped because z < 0.0 */
1735 color
= getPixelColor(device
, 321, 238);
1736 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1737 color
= getPixelColor(device
, 321, 241);
1738 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
1739 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1741 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1743 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1744 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
1746 /* Test the shader path */
1747 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
1749 skip("Vertex shaders not supported\n");
1750 IDirect3DDevice8_Release(device
);
1753 hr
= IDirect3DDevice8_CreateVertexShader(device
, vertex_declaration
, shader_code
, &shader
, 0);
1754 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
1756 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
1757 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
1759 hr
= IDirect3DDevice8_SetVertexShader(device
, shader
);
1760 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1762 hr
= IDirect3DDevice8_BeginScene(device
);
1763 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1765 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, color_const_1
, 1);
1766 ok(SUCCEEDED(hr
), "Failed to set vs constant 0, hr %#x.\n", hr
);
1767 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
1768 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1770 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESS
);
1771 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1772 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, color_const_2
, 1);
1773 ok(SUCCEEDED(hr
), "Failed to set vs constant 0, hr %#x.\n", hr
);
1774 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
1775 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1777 hr
= IDirect3DDevice8_EndScene(device
);
1778 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1780 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
1781 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1783 hr
= IDirect3DDevice8_DeleteVertexShader(device
, shader
);
1784 ok(SUCCEEDED(hr
), "Failed to delete vertex shader, hr %#x.\n", hr
);
1787 color
= getPixelColor(device
, 28, 238);
1788 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1790 /* 1.0 < z < 0.75 */
1791 color
= getPixelColor(device
, 31, 238);
1792 ok(color_match(color
, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1793 color
= getPixelColor(device
, 100, 238);
1794 ok(color_match(color
, 0x00ff0000, 0) || broken(color_match(color
, 0x00ffffff, 0)),
1795 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1797 /* 0.75 < z < 0.0 */
1798 color
= getPixelColor(device
, 104, 238);
1799 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1800 color
= getPixelColor(device
, 318, 238);
1801 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1804 color
= getPixelColor(device
, 321, 238);
1805 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1807 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1808 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
1810 refcount
= IDirect3DDevice8_Release(device
);
1811 ok(!refcount
, "Device has %u references left.\n", refcount
);
1813 IDirect3D8_Release(d3d
);
1814 DestroyWindow(window
);
1817 static void test_scalar_instructions(void)
1819 IDirect3DDevice8
*device
;
1829 static const struct vec3 quad
[] =
1831 {-1.0f
, -1.0f
, 0.0f
},
1832 {-1.0f
, 1.0f
, 0.0f
},
1833 { 1.0f
, -1.0f
, 0.0f
},
1834 { 1.0f
, 1.0f
, 0.0f
},
1836 static const DWORD decl
[] =
1839 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* dcl_position v0 */
1840 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
1843 static const DWORD rcp_test
[] =
1845 0xfffe0101, /* vs_1_1 */
1846 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1847 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1848 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1849 0x00303030, /* enough to make Windows happy. */
1850 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1851 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
1852 0x0000ffff /* END */
1854 static const DWORD rsq_test
[] =
1856 0xfffe0101, /* vs_1_1 */
1857 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1858 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1859 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1860 0x00303030, /* enough to make Windows happy. */
1861 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1862 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
1863 0x0000ffff /* END */
1865 static const DWORD exp_test
[] =
1867 0xfffe0101, /* vs_1_1 */
1868 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1869 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1870 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1871 0x00303030, /* enough to make Windows happy. */
1872 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1873 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
1874 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
1875 0x0000ffff, /* END */
1877 static const DWORD expp_test
[] =
1879 0xfffe0101, /* vs_1_1 */
1880 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1881 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1882 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1883 0x00303030, /* enough to make Windows happy. */
1884 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1885 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
1886 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
1887 0x0000ffff, /* END */
1889 static const DWORD log_test
[] =
1891 0xfffe0101, /* vs_1_1 */
1892 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1893 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1894 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1895 0x00303030, /* enough to make Windows happy. */
1896 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1897 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
1898 0x0000ffff, /* END */
1900 static const DWORD logp_test
[] =
1902 0xfffe0101, /* vs_1_1 */
1903 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1904 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1905 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1906 0x00303030, /* enough to make Windows happy. */
1907 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1908 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
1909 0x0000ffff, /* END */
1914 const DWORD
*byte_code
;
1916 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
1917 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
1918 D3DCOLOR broken_color
;
1922 {"rcp_test", rcp_test
, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1923 {"rsq_test", rsq_test
, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1924 {"exp_test", exp_test
, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
1925 {"expp_test", expp_test
, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1926 {"log_test", log_test
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
1927 {"logp_test", logp_test
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1930 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1931 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
1932 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1933 ok(!!d3d
, "Failed to create a D3D object.\n");
1934 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1936 skip("Failed to create a D3D device, skipping tests.\n");
1940 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1941 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1942 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
1944 skip("No vs_1_1 support, skipping tests.\n");
1945 IDirect3DDevice8_Release(device
);
1949 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
1951 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff336699, 0.0f
, 0);
1952 ok(SUCCEEDED(hr
), "%s: Failed to clear, hr %#x.\n", test_data
[i
].name
, hr
);
1954 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, test_data
[i
].byte_code
, &shader
, 0);
1955 ok(SUCCEEDED(hr
), "%s: Failed to create vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1956 hr
= IDirect3DDevice8_SetVertexShader(device
, shader
);
1957 ok(SUCCEEDED(hr
), "%s: Failed to set vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1959 hr
= IDirect3DDevice8_BeginScene(device
);
1960 ok(SUCCEEDED(hr
), "%s: Failed to begin scene, hr %#x.\n", test_data
[i
].name
, hr
);
1961 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], 3 * sizeof(float));
1962 ok(SUCCEEDED(hr
), "%s: Failed to draw primitive, hr %#x.\n", test_data
[i
].name
, hr
);
1963 hr
= IDirect3DDevice8_EndScene(device
);
1964 ok(SUCCEEDED(hr
), "%s: Failed to end scene, hr %#x.\n", test_data
[i
].name
, hr
);
1966 color
= getPixelColor(device
, 320, 240);
1967 ok(color_match(color
, test_data
[i
].color
, 4) || broken(color_match(color
, test_data
[i
].broken_color
, 4)),
1968 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
1969 test_data
[i
].name
, color
, test_data
[i
].color
);
1971 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1972 ok(SUCCEEDED(hr
), "%s: Failed to present, hr %#x.\n", test_data
[i
].name
, hr
);
1974 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
1975 ok(SUCCEEDED(hr
), "%s: Failed to set vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1976 hr
= IDirect3DDevice8_DeleteVertexShader(device
, shader
);
1977 ok(SUCCEEDED(hr
), "%s: Failed to delete vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1980 refcount
= IDirect3DDevice8_Release(device
);
1981 ok(!refcount
, "Device has %u references left.\n", refcount
);
1983 IDirect3D8_Release(d3d
);
1984 DestroyWindow(window
);
1987 static void offscreen_test(void)
1989 IDirect3DSurface8
*backbuffer
, *offscreen
, *depthstencil
;
1990 IDirect3DTexture8
*offscreenTexture
;
1991 IDirect3DDevice8
*device
;
1998 static const float quad
[][5] =
2000 {-0.5f
, -0.5f
, 0.1f
, 0.0f
, 0.0f
},
2001 {-0.5f
, 0.5f
, 0.1f
, 0.0f
, 1.0f
},
2002 { 0.5f
, -0.5f
, 0.1f
, 1.0f
, 0.0f
},
2003 { 0.5f
, 0.5f
, 0.1f
, 1.0f
, 1.0f
},
2006 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2007 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2008 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2009 ok(!!d3d
, "Failed to create a D3D object.\n");
2010 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2012 skip("Failed to create a D3D device, skipping tests.\n");
2016 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
2017 ok(hr
== D3D_OK
, "Clear failed, hr = %#08x\n", hr
);
2019 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2020 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2021 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
, "Creating the offscreen render target failed, hr = %#08x\n", hr
);
2022 if (!offscreenTexture
)
2024 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2025 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2026 D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2027 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
, "Creating the offscreen render target failed, hr = %#08x\n", hr
);
2028 if (!offscreenTexture
)
2030 skip("Cannot create an offscreen render target.\n");
2031 IDirect3DDevice8_Release(device
);
2036 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
2037 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr
);
2039 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2040 ok(hr
== D3D_OK
, "Can't get back buffer, hr = %#08x\n", hr
);
2042 hr
= IDirect3DTexture8_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
2043 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %#08x\n", hr
);
2045 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2046 ok(hr
== D3D_OK
, "SetVertexShader failed, hr = %#08x\n", hr
);
2048 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
2049 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2050 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2051 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2052 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_NONE
);
2053 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr
);
2054 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_NONE
);
2055 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr
);
2056 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2057 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %08x\n", hr
);
2059 hr
= IDirect3DDevice8_BeginScene(device
);
2060 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2062 hr
= IDirect3DDevice8_SetRenderTarget(device
, offscreen
, depthstencil
);
2063 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2064 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 1.0f
, 0);
2065 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2067 /* Draw without textures - Should result in a white quad. */
2068 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2069 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2071 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
2072 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2073 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)offscreenTexture
);
2074 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2076 /* This time with the texture .*/
2077 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2078 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2080 hr
= IDirect3DDevice8_EndScene(device
);
2081 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2083 /* Center quad - should be white */
2084 color
= getPixelColor(device
, 320, 240);
2085 ok(color
== 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2086 /* Some quad in the cleared part of the texture */
2087 color
= getPixelColor(device
, 170, 240);
2088 ok(color
== 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color
);
2089 /* Part of the originally cleared back buffer */
2090 color
= getPixelColor(device
, 10, 10);
2091 ok(color
== 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2092 color
= getPixelColor(device
, 10, 470);
2093 ok(color
== 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2095 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2097 IDirect3DSurface8_Release(backbuffer
);
2098 IDirect3DTexture8_Release(offscreenTexture
);
2099 IDirect3DSurface8_Release(offscreen
);
2100 IDirect3DSurface8_Release(depthstencil
);
2101 refcount
= IDirect3DDevice8_Release(device
);
2102 ok(!refcount
, "Device has %u references left.\n", refcount
);
2104 IDirect3D8_Release(d3d
);
2105 DestroyWindow(window
);
2108 static void alpha_test(void)
2110 IDirect3DSurface8
*backbuffer
, *offscreen
, *depthstencil
;
2111 IDirect3DTexture8
*offscreenTexture
;
2112 IDirect3DDevice8
*device
;
2121 struct vec3 position
;
2126 {{-1.0f
, -1.0f
, 0.1f
}, 0x4000ff00},
2127 {{-1.0f
, 0.0f
, 0.1f
}, 0x4000ff00},
2128 {{ 1.0f
, -1.0f
, 0.1f
}, 0x4000ff00},
2129 {{ 1.0f
, 0.0f
, 0.1f
}, 0x4000ff00},
2133 {{-1.0f
, 0.0f
, 0.1f
}, 0xc00000ff},
2134 {{-1.0f
, 1.0f
, 0.1f
}, 0xc00000ff},
2135 {{ 1.0f
, 0.0f
, 0.1f
}, 0xc00000ff},
2136 {{ 1.0f
, 1.0f
, 0.1f
}, 0xc00000ff},
2138 static const float composite_quad
[][5] =
2140 { 0.0f
, -1.0f
, 0.1f
, 0.0f
, 1.0f
},
2141 { 0.0f
, 1.0f
, 0.1f
, 0.0f
, 0.0f
},
2142 { 1.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
},
2143 { 1.0f
, 1.0f
, 0.1f
, 1.0f
, 0.0f
},
2146 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2147 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2148 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2149 ok(!!d3d
, "Failed to create a D3D object.\n");
2150 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2152 skip("Failed to create a D3D device, skipping tests.\n");
2156 /* Clear the render target with alpha = 0.5 */
2157 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x80ff0000, 1.0f
, 0);
2158 ok(hr
== D3D_OK
, "Clear failed, hr = %08x\n", hr
);
2160 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2161 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2162 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2164 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
2165 ok(SUCCEEDED(hr
), "Failed to get depth/stencil buffer, hr %#x.\n", hr
);
2166 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2167 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
2169 hr
= IDirect3DTexture8_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
2170 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %#08x\n", hr
);
2172 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2173 ok(hr
== D3D_OK
, "SetVertexShader failed, hr = %#08x\n", hr
);
2175 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
2176 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2177 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2178 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2179 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_NONE
);
2180 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr
);
2181 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_NONE
);
2182 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr
);
2183 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2184 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %08x\n", hr
);
2186 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2187 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2188 hr
= IDirect3DDevice8_BeginScene(device
);
2189 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2191 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2192 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2193 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2194 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2195 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2196 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
2197 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2199 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_DESTALPHA
);
2200 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2201 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVDESTALPHA
);
2202 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2203 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2204 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2206 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2207 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2208 * "don't work" on render targets without alpha channel, they give
2209 * essentially ZERO and ONE blend factors. */
2210 hr
= IDirect3DDevice8_SetRenderTarget(device
, offscreen
, 0);
2211 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2212 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x80ff0000, 0.0, 0);
2213 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2215 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2216 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2217 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2218 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2219 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
2220 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2222 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_DESTALPHA
);
2223 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2224 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVDESTALPHA
);
2225 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2226 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2227 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2229 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
2230 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2232 /* Render the offscreen texture onto the frame buffer to be able to
2233 * compare it regularly. Disable alpha blending for the final
2235 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, FALSE
);
2236 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2237 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2238 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2240 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) offscreenTexture
);
2241 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2242 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, composite_quad
, sizeof(float) * 5);
2243 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2245 hr
= IDirect3DDevice8_EndScene(device
);
2246 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2248 color
= getPixelColor(device
, 160, 360);
2249 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2250 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color
);
2252 color
= getPixelColor(device
, 160, 120);
2253 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2254 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color
);
2256 color
= getPixelColor(device
, 480, 360);
2257 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2258 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color
);
2260 color
= getPixelColor(device
, 480, 120);
2261 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2262 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color
);
2264 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2266 IDirect3DSurface8_Release(backbuffer
);
2267 IDirect3DTexture8_Release(offscreenTexture
);
2268 IDirect3DSurface8_Release(offscreen
);
2269 IDirect3DSurface8_Release(depthstencil
);
2270 refcount
= IDirect3DDevice8_Release(device
);
2271 ok(!refcount
, "Device has %u references left.\n", refcount
);
2273 IDirect3D8_Release(d3d
);
2274 DestroyWindow(window
);
2277 static void p8_texture_test(void)
2279 IDirect3DTexture8
*texture
, *texture2
;
2280 IDirect3DDevice8
*device
;
2281 PALETTEENTRY table
[256];
2282 unsigned char *data
;
2292 static const float quad
[] =
2294 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
,
2295 -1.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
,
2296 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
,
2297 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
,
2299 static const float quad2
[] =
2301 -1.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
,
2302 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
,
2303 1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
,
2304 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
,
2307 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2308 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2309 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2310 ok(!!d3d
, "Failed to create a D3D object.\n");
2311 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2313 skip("Failed to create a D3D device, skipping tests.\n");
2317 if (IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
,
2318 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, D3DFMT_P8
) != D3D_OK
)
2320 skip("D3DFMT_P8 textures not supported.\n");
2321 IDirect3DDevice8_Release(device
);
2325 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_P8
, D3DPOOL_MANAGED
, &texture2
);
2326 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2327 memset(&lr
, 0, sizeof(lr
));
2328 hr
= IDirect3DTexture8_LockRect(texture2
, 0, &lr
, NULL
, 0);
2329 ok(hr
== D3D_OK
, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr
);
2332 hr
= IDirect3DTexture8_UnlockRect(texture2
, 0);
2333 ok(hr
== D3D_OK
, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr
);
2335 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_P8
, D3DPOOL_MANAGED
, &texture
);
2336 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2337 memset(&lr
, 0, sizeof(lr
));
2338 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lr
, NULL
, 0);
2339 ok(hr
== D3D_OK
, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr
);
2342 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
2343 ok(hr
== D3D_OK
, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr
);
2345 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000, 1.0f
, 0);
2346 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2348 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2349 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2350 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2351 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2353 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2354 alpha of every entry is set to 1.0, which MS says is required when there's no
2355 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2356 for (i
= 0; i
< 256; i
++) {
2357 table
[i
].peRed
= table
[i
].peGreen
= table
[i
].peBlue
= 0;
2358 table
[i
].peFlags
= 0xff;
2360 table
[1].peRed
= 0xff;
2361 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, table
);
2362 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2365 table
[1].peBlue
= 0xff;
2366 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 1, table
);
2367 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2369 hr
= IDirect3DDevice8_BeginScene(device
);
2370 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2372 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2373 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2374 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2375 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2376 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2377 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2378 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 0);
2379 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2380 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture2
);
2381 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2382 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2383 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2385 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
2386 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2387 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2388 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2390 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 1);
2391 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2392 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 5 * sizeof(float));
2393 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2395 hr
= IDirect3DDevice8_EndScene(device
);
2396 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2398 color
= getPixelColor(device
, 32, 32);
2399 ok(color_match(color
, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color
);
2400 color
= getPixelColor(device
, 32, 320);
2401 ok(color_match(color
, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color
);
2403 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2404 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
2406 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 0.0, 0);
2407 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2409 hr
= IDirect3DDevice8_BeginScene(device
);
2410 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2411 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture2
);
2412 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2413 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2414 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2415 hr
= IDirect3DDevice8_EndScene(device
);
2416 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2418 color
= getPixelColor(device
, 32, 32);
2419 ok(color_match(color
, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color
);
2421 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2422 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
2424 /* Test palettes with alpha */
2425 IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2426 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_ALPHAPALETTE
)) {
2427 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2429 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 0.0, 0);
2430 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2432 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2433 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2435 for (i
= 0; i
< 256; i
++) {
2436 table
[i
].peRed
= table
[i
].peGreen
= table
[i
].peBlue
= 0;
2437 table
[i
].peFlags
= 0xff;
2439 table
[1].peRed
= 0xff;
2440 table
[1].peFlags
= 0x80;
2441 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, table
);
2442 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2445 table
[1].peBlue
= 0xff;
2446 table
[1].peFlags
= 0x80;
2447 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 1, table
);
2448 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2450 hr
= IDirect3DDevice8_BeginScene(device
);
2451 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2453 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2454 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2455 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2456 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2457 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2458 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2460 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 0);
2461 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2462 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2463 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2465 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 1);
2466 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2467 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 5 * sizeof(float));
2468 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2470 hr
= IDirect3DDevice8_EndScene(device
);
2471 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2473 color
= getPixelColor(device
, 32, 32);
2474 ok(color_match(color
, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color
);
2475 color
= getPixelColor(device
, 32, 320);
2476 ok(color_match(color
, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color
);
2478 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2479 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
2482 IDirect3DTexture8_Release(texture
);
2483 IDirect3DTexture8_Release(texture2
);
2484 refcount
= IDirect3DDevice8_Release(device
);
2485 ok(!refcount
, "Device has %u references left.\n", refcount
);
2487 IDirect3D8_Release(d3d
);
2488 DestroyWindow(window
);
2491 static void texop_test(void)
2493 IDirect3DTexture8
*texture
;
2494 D3DLOCKED_RECT locked_rect
;
2495 IDirect3DDevice8
*device
;
2504 static const struct {
2509 {-1.0f
, -1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f
, -1.0f
},
2510 {-1.0f
, 1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f
, 1.0f
},
2511 { 1.0f
, -1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f
, -1.0f
},
2512 { 1.0f
, 1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f
, 1.0f
}
2515 static const struct {
2521 {D3DTOP_SELECTARG1
, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2522 {D3DTOP_SELECTARG2
, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2
, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2523 {D3DTOP_MODULATE
, "MODULATE", D3DTEXOPCAPS_MODULATE
, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2524 {D3DTOP_MODULATE2X
, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X
, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2525 {D3DTOP_MODULATE4X
, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X
, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2526 {D3DTOP_ADD
, "ADD", D3DTEXOPCAPS_ADD
, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2528 {D3DTOP_ADDSIGNED
, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED
, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2529 {D3DTOP_ADDSIGNED2X
, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2531 {D3DTOP_SUBTRACT
, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT
, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2532 {D3DTOP_ADDSMOOTH
, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH
, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2533 {D3DTOP_BLENDDIFFUSEALPHA
, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA
, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2534 {D3DTOP_BLENDTEXTUREALPHA
, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA
, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2535 {D3DTOP_BLENDFACTORALPHA
, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA
, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2536 {D3DTOP_BLENDTEXTUREALPHAPM
, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2537 {D3DTOP_BLENDCURRENTALPHA
, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA
, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2538 {D3DTOP_MODULATEALPHA_ADDCOLOR
, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2539 {D3DTOP_MODULATECOLOR_ADDALPHA
, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2540 {D3DTOP_MODULATEINVALPHA_ADDCOLOR
, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2541 {D3DTOP_MODULATEINVCOLOR_ADDALPHA
, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2542 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2543 {D3DTOP_DOTPRODUCT3
, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3
, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2544 {D3DTOP_MULTIPLYADD
, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD
, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2545 {D3DTOP_LERP
, "LERP", D3DTEXOPCAPS_LERP
, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2548 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2549 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2550 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2551 ok(!!d3d
, "Failed to create a D3D object.\n");
2552 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2554 skip("Failed to create a D3D device, skipping tests.\n");
2558 memset(&caps
, 0, sizeof(caps
));
2559 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2560 ok(SUCCEEDED(hr
), "GetDeviceCaps failed with 0x%08x\n", hr
);
2562 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_TEX0
);
2563 ok(SUCCEEDED(hr
), "SetVertexShader failed with 0x%08x\n", hr
);
2565 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
2566 ok(SUCCEEDED(hr
), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr
);
2567 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, NULL
, 0);
2568 ok(SUCCEEDED(hr
), "LockRect failed with 0x%08x\n", hr
);
2569 *((DWORD
*)locked_rect
.pBits
) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
2570 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
2571 ok(SUCCEEDED(hr
), "LockRect failed with 0x%08x\n", hr
);
2572 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
2573 ok(SUCCEEDED(hr
), "SetTexture failed with 0x%08x\n", hr
);
2575 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG0
, D3DTA_DIFFUSE
);
2576 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2577 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2578 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2579 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
2580 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2582 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
2583 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2585 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2586 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
2587 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_TEXTUREFACTOR
, 0xdd333333);
2588 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
2589 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
| D3DCOLORWRITEENABLE_ALPHA
);
2590 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
2592 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00000000, 1.0f
, 0);
2593 ok(SUCCEEDED(hr
), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr
);
2595 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
2597 if (!(caps
.TextureOpCaps
& test_data
[i
].caps_flag
))
2599 skip("tex operation %s not supported\n", test_data
[i
].name
);
2603 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, test_data
[i
].op
);
2604 ok(SUCCEEDED(hr
), "SetTextureStageState (%s) failed with 0x%08x\n", test_data
[i
].name
, hr
);
2606 hr
= IDirect3DDevice8_BeginScene(device
);
2607 ok(SUCCEEDED(hr
), "BeginScene failed with 0x%08x\n", hr
);
2609 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
2610 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed with 0x%08x\n", hr
);
2612 hr
= IDirect3DDevice8_EndScene(device
);
2613 ok(SUCCEEDED(hr
), "EndScene failed with 0x%08x\n", hr
);
2615 color
= getPixelColor(device
, 320, 240);
2616 ok(color_match(color
, test_data
[i
].result
, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
2617 test_data
[i
].name
, color
, test_data
[i
].result
);
2619 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2620 ok(SUCCEEDED(hr
), "Present failed with 0x%08x\n", hr
);
2622 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00000000, 1.0f
, 0);
2623 ok(SUCCEEDED(hr
), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr
);
2626 IDirect3DTexture8_Release(texture
);
2627 refcount
= IDirect3DDevice8_Release(device
);
2628 ok(!refcount
, "Device has %u references left.\n", refcount
);
2630 IDirect3D8_Release(d3d
);
2631 DestroyWindow(window
);
2634 /* This test tests depth clamping / clipping behaviour:
2635 * - With software vertex processing, depth values are clamped to the
2636 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2637 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2638 * same as regular vertices here.
2639 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2640 * Normal vertices are always clipped. Pretransformed vertices are
2641 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2642 * - The viewport's MinZ/MaxZ is irrelevant for this.
2644 static void depth_clamp_test(void)
2646 IDirect3DDevice8
*device
;
2657 struct vec4 position
;
2662 {{ 0.0f
, 0.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2663 {{640.0f
, 0.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2664 {{ 0.0f
, 480.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2665 {{640.0f
, 480.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2669 {{ 0.0f
, 300.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2670 {{640.0f
, 300.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2671 {{ 0.0f
, 360.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2672 {{640.0f
, 360.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2676 {{112.0f
, 108.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2677 {{208.0f
, 108.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2678 {{112.0f
, 204.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2679 {{208.0f
, 204.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2683 {{ 42.0f
, 41.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2684 {{112.0f
, 41.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2685 {{ 42.0f
, 108.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2686 {{112.0f
, 108.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2690 struct vec3 position
;
2695 {{-0.5f
, 0.5f
, 10.0f
}, 0xff14f914},
2696 {{ 0.5f
, 0.5f
, 10.0f
}, 0xff14f914},
2697 {{-0.5f
, -0.5f
, 10.0f
}, 0xff14f914},
2698 {{ 0.5f
, -0.5f
, 10.0f
}, 0xff14f914},
2702 {{-1.0f
, 0.5f
, 10.0f
}, 0xfff91414},
2703 {{ 1.0f
, 0.5f
, 10.0f
}, 0xfff91414},
2704 {{-1.0f
, 0.25f
, 10.0f
}, 0xfff91414},
2705 {{ 1.0f
, 0.25f
, 10.0f
}, 0xfff91414},
2708 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2709 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2710 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2711 ok(!!d3d
, "Failed to create a D3D object.\n");
2712 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2714 skip("Failed to create a D3D device, skipping tests.\n");
2718 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2719 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
2728 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
2729 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
2731 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0, 0);
2732 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2734 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
2735 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2736 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2737 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2738 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
2739 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2740 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
2741 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2743 hr
= IDirect3DDevice8_BeginScene(device
);
2744 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
2746 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
2747 ok(SUCCEEDED(hr
), "SetVertexSahder failed, hr %#x.\n", hr
);
2749 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(*quad1
));
2750 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2751 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(*quad2
));
2752 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2754 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
2755 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2757 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(*quad3
));
2758 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2759 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(*quad4
));
2760 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2762 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
2763 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2764 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2765 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
2767 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad5
, sizeof(*quad5
));
2768 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2770 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
2771 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2773 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad6
, sizeof(*quad6
));
2774 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2776 hr
= IDirect3DDevice8_EndScene(device
);
2777 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
2779 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
2781 color
= getPixelColor(device
, 75, 75);
2782 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2783 color
= getPixelColor(device
, 150, 150);
2784 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2785 color
= getPixelColor(device
, 320, 240);
2786 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2787 color
= getPixelColor(device
, 320, 330);
2788 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2789 color
= getPixelColor(device
, 320, 330);
2790 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2794 color
= getPixelColor(device
, 75, 75);
2795 ok(color_match(color
, 0x00ffffff, 1), "color 0x%08x.\n", color
);
2796 color
= getPixelColor(device
, 150, 150);
2797 ok(color_match(color
, 0x00ffffff, 1), "color 0x%08x.\n", color
);
2798 color
= getPixelColor(device
, 320, 240);
2799 ok(color_match(color
, 0x00002b7f, 1), "color 0x%08x.\n", color
);
2800 color
= getPixelColor(device
, 320, 330);
2801 ok(color_match(color
, 0x00f9e814, 1), "color 0x%08x.\n", color
);
2802 color
= getPixelColor(device
, 320, 330);
2803 ok(color_match(color
, 0x00f9e814, 1), "color 0x%08x.\n", color
);
2806 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2807 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
2809 refcount
= IDirect3DDevice8_Release(device
);
2810 ok(!refcount
, "Device has %u references left.\n", refcount
);
2812 IDirect3D8_Release(d3d
);
2813 DestroyWindow(window
);
2816 static void depth_buffer_test(void)
2818 IDirect3DSurface8
*backbuffer
, *rt1
, *rt2
, *rt3
;
2819 IDirect3DSurface8
*depth_stencil
;
2820 IDirect3DDevice8
*device
;
2831 struct vec3 position
;
2836 {{-1.0f
, 1.0f
, 0.33f
}, 0xff00ff00},
2837 {{ 1.0f
, 1.0f
, 0.33f
}, 0xff00ff00},
2838 {{-1.0f
, -1.0f
, 0.33f
}, 0xff00ff00},
2839 {{ 1.0f
, -1.0f
, 0.33f
}, 0xff00ff00},
2843 {{-1.0f
, 1.0f
, 0.50f
}, 0xffff00ff},
2844 {{ 1.0f
, 1.0f
, 0.50f
}, 0xffff00ff},
2845 {{-1.0f
, -1.0f
, 0.50f
}, 0xffff00ff},
2846 {{ 1.0f
, -1.0f
, 0.50f
}, 0xffff00ff},
2850 {{-1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2851 {{ 1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2852 {{-1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
2853 {{ 1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
2855 static const DWORD expected_colors
[4][4] =
2857 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
2858 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
2859 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
2860 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
2863 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2864 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2865 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2866 ok(!!d3d
, "Failed to create a D3D object.\n");
2867 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2869 skip("Failed to create a D3D device, skipping tests.\n");
2880 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
2881 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
2883 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2884 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2885 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
2886 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2887 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
2888 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2889 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
2890 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2891 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2892 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
2894 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
2895 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
2896 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
2897 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
2898 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 320, 240, D3DFMT_A8R8G8B8
,
2899 D3DMULTISAMPLE_NONE
, FALSE
, &rt1
);
2900 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
2901 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 480, 360, D3DFMT_A8R8G8B8
,
2902 D3DMULTISAMPLE_NONE
, FALSE
, &rt2
);
2903 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
2904 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
2905 D3DMULTISAMPLE_NONE
, FALSE
, &rt3
);
2906 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
2908 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt3
, depth_stencil
);
2909 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2910 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 0.0f
, 0);
2911 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2913 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
2914 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2915 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
2916 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2918 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt1
, depth_stencil
);
2919 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2920 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.0f
, 0);
2921 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2923 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt2
, depth_stencil
);
2924 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2925 hr
= IDirect3DDevice8_BeginScene(device
);
2926 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
2927 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(*quad2
));
2928 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2929 hr
= IDirect3DDevice8_EndScene(device
);
2930 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
2932 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
2933 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2935 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
2936 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2938 hr
= IDirect3DDevice8_BeginScene(device
);
2939 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
2940 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(*quad1
));
2941 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2942 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(*quad3
));
2943 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2944 hr
= IDirect3DDevice8_EndScene(device
);
2945 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
2947 for (i
= 0; i
< 4; ++i
)
2949 for (j
= 0; j
< 4; ++j
)
2951 unsigned int x
= 80 * ((2 * j
) + 1);
2952 unsigned int y
= 60 * ((2 * i
) + 1);
2953 color
= getPixelColor(device
, x
, y
);
2954 ok(color_match(color
, expected_colors
[i
][j
], 0),
2955 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
2959 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2960 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
2962 IDirect3DSurface8_Release(depth_stencil
);
2963 IDirect3DSurface8_Release(backbuffer
);
2964 IDirect3DSurface8_Release(rt3
);
2965 IDirect3DSurface8_Release(rt2
);
2966 IDirect3DSurface8_Release(rt1
);
2967 refcount
= IDirect3DDevice8_Release(device
);
2968 ok(!refcount
, "Device has %u references left.\n", refcount
);
2970 IDirect3D8_Release(d3d
);
2971 DestroyWindow(window
);
2974 /* Test that partial depth copies work the way they're supposed to. The clear
2975 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2976 * the following draw should only copy back the part that was modified. */
2977 static void depth_buffer2_test(void)
2979 IDirect3DSurface8
*backbuffer
, *rt1
, *rt2
;
2980 IDirect3DSurface8
*depth_stencil
;
2981 IDirect3DDevice8
*device
;
2992 struct vec3 position
;
2997 {{-1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2998 {{ 1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2999 {{-1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3000 {{ 1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3003 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3004 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3005 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3006 ok(!!d3d
, "Failed to create a D3D object.\n");
3007 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3009 skip("Failed to create a D3D device, skipping tests.\n");
3020 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
3021 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
3023 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3024 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3025 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3026 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3027 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3028 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3029 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
3030 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3031 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
3032 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3034 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3035 D3DMULTISAMPLE_NONE
, FALSE
, &rt1
);
3036 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3037 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 480, 360, D3DFMT_A8R8G8B8
,
3038 D3DMULTISAMPLE_NONE
, FALSE
, &rt2
);
3039 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3040 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
3041 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
3042 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
3043 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3045 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt1
, depth_stencil
);
3046 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3047 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
3048 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3050 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3051 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3052 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 0.5f
, 0);
3053 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3055 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt2
, depth_stencil
);
3056 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3057 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.0f
, 0);
3058 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3060 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3061 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3063 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
3064 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3066 hr
= IDirect3DDevice8_BeginScene(device
);
3067 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3068 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3069 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3070 hr
= IDirect3DDevice8_EndScene(device
);
3071 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3073 for (i
= 0; i
< 4; ++i
)
3075 for (j
= 0; j
< 4; ++j
)
3077 unsigned int x
= 80 * ((2 * j
) + 1);
3078 unsigned int y
= 60 * ((2 * i
) + 1);
3079 color
= getPixelColor(device
, x
, y
);
3080 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3081 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x
, y
, color
);
3085 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3086 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3088 IDirect3DSurface8_Release(depth_stencil
);
3089 IDirect3DSurface8_Release(backbuffer
);
3090 IDirect3DSurface8_Release(rt2
);
3091 IDirect3DSurface8_Release(rt1
);
3092 refcount
= IDirect3DDevice8_Release(device
);
3093 ok(!refcount
, "Device has %u references left.\n", refcount
);
3095 IDirect3D8_Release(d3d
);
3096 DestroyWindow(window
);
3099 static void intz_test(void)
3101 IDirect3DSurface8
*original_rt
, *rt
;
3102 IDirect3DTexture8
*texture
;
3103 IDirect3DDevice8
*device
;
3104 IDirect3DSurface8
*ds
;
3113 static const DWORD ps_code
[] =
3115 0xffff0101, /* ps_1_1 */
3116 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3117 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3118 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3119 0x00000042, 0xb00f0000, /* tex t0 */
3120 0x00000042, 0xb00f0001, /* tex t1 */
3121 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3122 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3123 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3124 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3125 0x0000ffff, /* end */
3131 float s1
, t1
, p1
, q1
;
3135 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3136 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3137 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3138 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3142 { -1.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3143 { 1.0f
, 0.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3144 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3145 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3149 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3150 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3151 { -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3152 { 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3161 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3162 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3163 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3164 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3165 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3166 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3167 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3168 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3171 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3172 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3173 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3174 ok(!!d3d
, "Failed to create a D3D object.\n");
3175 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3177 skip("Failed to create a D3D device, skipping tests.\n");
3181 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3182 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3183 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
3185 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3186 IDirect3DDevice8_Release(device
);
3189 if (caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
)
3191 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3192 IDirect3DDevice8_Release(device
);
3196 if (FAILED(hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3197 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, MAKEFOURCC('I','N','T','Z'))))
3199 skip("No INTZ support, skipping INTZ test.\n");
3200 IDirect3DDevice8_Release(device
);
3204 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3205 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3207 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3208 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3209 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3210 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3211 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
3212 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3213 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3214 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3216 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3217 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3218 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3219 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3220 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3221 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3222 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3223 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3224 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3225 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3226 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3228 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3229 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3230 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3231 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3232 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3233 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3234 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3235 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3237 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3238 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3239 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3240 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3241 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3242 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3243 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3244 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3245 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3246 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3247 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3248 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3249 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3251 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3252 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3254 /* Render offscreen, using the INTZ texture as depth buffer */
3255 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3256 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3257 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3258 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3260 /* Setup the depth/stencil surface. */
3261 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3262 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3264 hr
= IDirect3DDevice8_BeginScene(device
);
3265 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3266 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3267 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3268 hr
= IDirect3DDevice8_EndScene(device
);
3269 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3271 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3272 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3273 IDirect3DSurface8_Release(ds
);
3274 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3275 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3276 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3277 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3278 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3279 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3281 /* Read the depth values back. */
3282 hr
= IDirect3DDevice8_BeginScene(device
);
3283 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3284 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3285 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3286 hr
= IDirect3DDevice8_EndScene(device
);
3287 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3289 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3291 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3292 ok(color_match(color
, expected_colors
[i
].color
, 1),
3293 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3294 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3297 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3298 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3300 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3301 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3302 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3303 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3304 IDirect3DTexture8_Release(texture
);
3306 /* Render onscreen while using the INTZ texture as depth buffer */
3307 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3308 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3309 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3310 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3311 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3312 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3313 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3314 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3315 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3317 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3318 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3320 hr
= IDirect3DDevice8_BeginScene(device
);
3321 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3322 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3323 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3324 hr
= IDirect3DDevice8_EndScene(device
);
3325 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3327 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3328 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3329 IDirect3DSurface8_Release(ds
);
3330 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3331 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3332 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3333 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3334 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3335 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3337 /* Read the depth values back. */
3338 hr
= IDirect3DDevice8_BeginScene(device
);
3339 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3340 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3341 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3342 hr
= IDirect3DDevice8_EndScene(device
);
3343 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3345 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3347 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3348 ok(color_match(color
, expected_colors
[i
].color
, 1),
3349 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3350 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3353 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3354 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3356 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3357 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3358 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3359 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3360 IDirect3DTexture8_Release(texture
);
3362 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3363 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3364 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3365 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3366 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3367 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3368 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3369 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3370 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3371 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3373 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3374 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3376 hr
= IDirect3DDevice8_BeginScene(device
);
3377 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3378 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, half_quad_1
, sizeof(*half_quad_1
));
3379 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3380 hr
= IDirect3DDevice8_EndScene(device
);
3381 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3383 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3384 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3386 hr
= IDirect3DDevice8_BeginScene(device
);
3387 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3388 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, half_quad_2
, sizeof(*half_quad_2
));
3389 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3390 hr
= IDirect3DDevice8_EndScene(device
);
3391 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3393 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3394 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3395 IDirect3DSurface8_Release(ds
);
3396 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3397 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3398 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3399 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3400 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3401 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3403 /* Read the depth values back. */
3404 hr
= IDirect3DDevice8_BeginScene(device
);
3405 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3406 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3407 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3408 hr
= IDirect3DDevice8_EndScene(device
);
3409 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3411 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3413 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3414 ok(color_match(color
, expected_colors
[i
].color
, 1),
3415 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3416 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3419 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3420 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3422 IDirect3DTexture8_Release(texture
);
3423 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
3424 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
3425 IDirect3DSurface8_Release(original_rt
);
3426 IDirect3DSurface8_Release(rt
);
3427 refcount
= IDirect3DDevice8_Release(device
);
3428 ok(!refcount
, "Device has %u references left.\n", refcount
);
3430 IDirect3D8_Release(d3d
);
3431 DestroyWindow(window
);
3434 static void shadow_test(void)
3436 IDirect3DSurface8
*original_rt
, *rt
;
3437 IDirect3DDevice8
*device
;
3446 static const DWORD ps_code
[] =
3448 0xffff0101, /* ps_1_1 */
3449 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3450 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3451 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3452 0x00000042, 0xb00f0000, /* tex t0 */
3453 0x00000042, 0xb00f0001, /* tex t1 */
3454 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3455 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3456 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3457 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3458 0x0000ffff, /* end */
3467 {D3DFMT_D16_LOCKABLE
, "D3DFMT_D16_LOCKABLE"},
3468 {D3DFMT_D32
, "D3DFMT_D32"},
3469 {D3DFMT_D15S1
, "D3DFMT_D15S1"},
3470 {D3DFMT_D24S8
, "D3DFMT_D24S8"},
3471 {D3DFMT_D24X8
, "D3DFMT_D24X8"},
3472 {D3DFMT_D24X4S4
, "D3DFMT_D24X4S4"},
3473 {D3DFMT_D16
, "D3DFMT_D16"},
3479 float s1
, t1
, p1
, q1
;
3483 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
},
3484 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.0f
},
3485 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
},
3486 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
},
3495 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3496 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3497 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3498 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3499 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3500 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3501 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3502 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3505 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3506 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3507 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3508 ok(!!d3d
, "Failed to create a D3D object.\n");
3509 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3511 skip("Failed to create a D3D device, skipping tests.\n");
3515 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3516 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3517 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
3519 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3520 IDirect3DDevice8_Release(device
);
3524 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3525 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3527 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 1024, 1024, D3DFMT_A8R8G8B8
,
3528 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
3529 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3530 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3531 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3533 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3534 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3535 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3536 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3537 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3538 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3539 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3540 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3541 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3542 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3543 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3545 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3546 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3547 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3548 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3549 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3550 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3551 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3552 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3554 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3555 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3556 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3557 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3558 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3559 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3560 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3561 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3562 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3563 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3564 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3565 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3566 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3568 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); ++i
)
3570 D3DFORMAT format
= formats
[i
].format
;
3571 IDirect3DTexture8
*texture
;
3572 IDirect3DSurface8
*ds
;
3575 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3576 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, format
)))
3579 hr
= IDirect3DDevice8_CreateTexture(device
, 1024, 1024, 1,
3580 D3DUSAGE_DEPTHSTENCIL
, format
, D3DPOOL_DEFAULT
, &texture
);
3581 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3583 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3584 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3586 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3587 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3589 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3590 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3592 /* Setup the depth/stencil surface. */
3593 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3594 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3596 hr
= IDirect3DDevice8_BeginScene(device
);
3597 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3598 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3599 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3600 hr
= IDirect3DDevice8_EndScene(device
);
3601 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3603 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3604 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3605 IDirect3DSurface8_Release(ds
);
3607 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3608 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3609 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3610 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3612 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3613 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3615 /* Do the actual shadow mapping. */
3616 hr
= IDirect3DDevice8_BeginScene(device
);
3617 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3618 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3619 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3620 hr
= IDirect3DDevice8_EndScene(device
);
3621 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3623 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3624 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3625 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3626 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3627 IDirect3DTexture8_Release(texture
);
3629 for (j
= 0; j
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++j
)
3631 D3DCOLOR color
= getPixelColor(device
, expected_colors
[j
].x
, expected_colors
[j
].y
);
3632 ok(color_match(color
, expected_colors
[j
].color
, 0),
3633 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
3634 expected_colors
[j
].color
, expected_colors
[j
].x
, expected_colors
[j
].y
,
3635 formats
[i
].name
, color
);
3638 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3639 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3642 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
3643 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
3644 IDirect3DSurface8_Release(original_rt
);
3645 IDirect3DSurface8_Release(rt
);
3646 refcount
= IDirect3DDevice8_Release(device
);
3647 ok(!refcount
, "Device has %u references left.\n", refcount
);
3649 IDirect3D8_Release(d3d
);
3650 DestroyWindow(window
);
3653 static void multisample_copy_rects_test(void)
3655 IDirect3DSurface8
*ds
, *ds_plain
, *rt
, *readback
;
3656 RECT src_rect
= {64, 64, 128, 128};
3657 POINT dst_point
= {96, 96};
3658 D3DLOCKED_RECT locked_rect
;
3659 IDirect3DDevice8
*device
;
3666 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3667 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3668 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3669 ok(!!d3d
, "Failed to create a D3D object.\n");
3670 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3672 skip("Failed to create a D3D device, skipping tests.\n");
3676 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
3677 D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
3679 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
3680 IDirect3DDevice8_Release(device
);
3684 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 256, 256, D3DFMT_A8R8G8B8
,
3685 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
3686 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
3687 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 256, 256, D3DFMT_D24S8
,
3688 D3DMULTISAMPLE_2_SAMPLES
, &ds
);
3689 ok(SUCCEEDED(hr
), "Failed to create depth stencil surface, hr %#x.\n", hr
);
3690 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 256, 256, D3DFMT_D24S8
,
3691 D3DMULTISAMPLE_NONE
, &ds_plain
);
3692 ok(SUCCEEDED(hr
), "Failed to create depth stencil surface, hr %#x.\n", hr
);
3693 hr
= IDirect3DDevice8_CreateImageSurface(device
, 256, 256, D3DFMT_A8R8G8B8
, &readback
);
3694 ok(SUCCEEDED(hr
), "Failed to create readback surface, hr %#x.\n", hr
);
3696 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3697 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3699 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
3700 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3702 hr
= IDirect3DDevice8_CopyRects(device
, rt
, NULL
, 0, readback
, NULL
);
3703 ok(SUCCEEDED(hr
), "Failed to read render target back, hr %#x.\n", hr
);
3705 hr
= IDirect3DDevice8_CopyRects(device
, ds
, NULL
, 0, ds_plain
, NULL
);
3706 ok(hr
== D3DERR_INVALIDCALL
, "Depth buffer copy, hr %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3708 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
3709 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3711 hr
= IDirect3DDevice8_CopyRects(device
, rt
, &src_rect
, 1, readback
, &dst_point
);
3712 ok(SUCCEEDED(hr
), "Failed to read render target back, hr %#x.\n", hr
);
3714 hr
= IDirect3DSurface8_LockRect(readback
, &locked_rect
, NULL
, D3DLOCK_READONLY
);
3715 ok(SUCCEEDED(hr
), "Failed to lock readback surface, hr %#x.\n", hr
);
3717 color
= *(DWORD
*)((BYTE
*)locked_rect
.pBits
+ 31 * locked_rect
.Pitch
+ 31 * 4);
3718 ok(color
== 0xff00ff00, "Got unexpected color 0x%08x.\n", color
);
3720 color
= *(DWORD
*)((BYTE
*)locked_rect
.pBits
+ 127 * locked_rect
.Pitch
+ 127 * 4);
3721 ok(color
== 0xffff0000, "Got unexpected color 0x%08x.\n", color
);
3723 hr
= IDirect3DSurface8_UnlockRect(readback
);
3724 ok(SUCCEEDED(hr
), "Failed to unlock readback surface, hr %#x.\n", hr
);
3726 IDirect3DSurface8_Release(readback
);
3727 IDirect3DSurface8_Release(ds_plain
);
3728 IDirect3DSurface8_Release(ds
);
3729 IDirect3DSurface8_Release(rt
);
3730 refcount
= IDirect3DDevice8_Release(device
);
3731 ok(!refcount
, "Device has %u references left.\n", refcount
);
3733 IDirect3D8_Release(d3d
);
3734 DestroyWindow(window
);
3737 static void resz_test(void)
3739 IDirect3DSurface8
*rt
, *original_rt
, *ds
, *original_ds
, *intz_ds
;
3740 IDirect3DTexture8
*texture
;
3741 IDirect3DDevice8
*device
;
3750 static const DWORD ps_code
[] =
3752 0xffff0101, /* ps_1_1 */
3753 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3754 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3755 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3756 0x00000042, 0xb00f0000, /* tex t0 */
3757 0x00000042, 0xb00f0001, /* tex t1 */
3758 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3759 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3760 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3761 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3762 0x0000ffff, /* end */
3768 float s1
, t1
, p1
, q1
;
3772 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3773 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3774 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3775 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3784 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3785 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3786 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3787 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3788 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3789 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3790 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3791 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3794 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3795 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3796 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3797 ok(!!d3d
, "Failed to create a D3D object.\n");
3798 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3800 skip("Failed to create a D3D device, skipping tests.\n");
3804 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
3805 D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
3807 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
3808 IDirect3DDevice8_Release(device
);
3811 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
3812 D3DDEVTYPE_HAL
, D3DFMT_D24S8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
3814 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
3815 IDirect3DDevice8_Release(device
);
3818 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3819 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, MAKEFOURCC('I','N','T','Z'))))
3821 skip("No INTZ support, skipping RESZ test.\n");
3822 IDirect3DDevice8_Release(device
);
3825 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3826 D3DFMT_X8R8G8B8
, D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, MAKEFOURCC('R','E','S','Z'))))
3828 skip("No RESZ support, skipping RESZ test.\n");
3829 IDirect3DDevice8_Release(device
);
3833 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3834 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3835 if (caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
)
3837 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3838 IDirect3DDevice8_Release(device
);
3842 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3843 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3844 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &original_ds
);
3845 ok(SUCCEEDED(hr
), "Failed to get depth/stencil, hr %#x.\n", hr
);
3847 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3848 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
3849 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
3850 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
,
3851 D3DMULTISAMPLE_2_SAMPLES
, &ds
);
3853 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3854 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3855 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3856 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &intz_ds
);
3857 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3859 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, intz_ds
);
3860 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3861 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
3862 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3864 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3865 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3866 IDirect3DSurface8_Release(intz_ds
);
3867 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3868 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3870 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3871 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3872 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3873 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3874 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3875 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3876 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3877 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3878 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3879 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3880 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3882 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3883 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3884 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3885 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3886 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3887 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3888 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3889 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3891 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3892 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3893 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3894 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3895 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3896 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3897 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3898 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3899 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3900 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3901 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3902 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3903 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3905 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
3906 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
3907 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3909 hr
= IDirect3DDevice8_BeginScene(device
);
3910 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3911 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3912 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3914 /* The destination depth texture has to be bound to sampler 0 */
3915 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3916 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3918 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
3919 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
3920 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3921 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
3922 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3923 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0);
3924 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3925 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3926 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3927 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
3928 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3929 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3930 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3931 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0xf);
3932 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3934 /* The actual multisampled depth buffer resolve happens here */
3935 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
3936 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
3937 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_POINTSIZE
, &value
);
3938 ok(SUCCEEDED(hr
) && value
== 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr
, value
);
3940 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3941 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3942 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3943 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3944 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3945 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3947 /* Read the depth values back. */
3948 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3949 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3950 hr
= IDirect3DDevice8_EndScene(device
);
3951 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3953 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3955 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3956 ok(color_match(color
, expected_colors
[i
].color
, 1),
3957 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3958 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3961 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3962 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3964 /* Test edge cases - try with no texture at all */
3965 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3966 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3967 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3968 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3969 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3970 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3972 hr
= IDirect3DDevice8_BeginScene(device
);
3973 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3974 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3975 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3976 hr
= IDirect3DDevice8_EndScene(device
);
3977 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3979 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
3980 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
3982 /* With a non-multisampled depth buffer */
3983 IDirect3DSurface8_Release(ds
);
3984 IDirect3DSurface8_Release(rt
);
3985 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
,
3986 D3DMULTISAMPLE_NONE
, &ds
);
3988 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3989 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3990 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3991 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3993 hr
= IDirect3DDevice8_BeginScene(device
);
3994 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3995 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3996 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3997 hr
= IDirect3DDevice8_EndScene(device
);
3998 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4000 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4001 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4003 hr
= IDirect3DDevice8_BeginScene(device
);
4004 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4005 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
4006 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4007 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
4008 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4009 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0);
4010 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4011 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4012 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4013 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
4014 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4015 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
4016 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4017 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0xf);
4018 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4019 hr
= IDirect3DDevice8_EndScene(device
);
4020 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4022 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
4023 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
4025 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
4026 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4027 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4028 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4030 /* Read the depth values back. */
4031 hr
= IDirect3DDevice8_BeginScene(device
);
4032 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4033 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4034 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4035 hr
= IDirect3DDevice8_EndScene(device
);
4036 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4038 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
4040 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
4041 ok(color_match(color
, expected_colors
[i
].color
, 1),
4042 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4043 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
4046 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4047 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
4049 IDirect3DSurface8_Release(ds
);
4050 IDirect3DTexture8_Release(texture
);
4051 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4052 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
4053 IDirect3DSurface8_Release(original_ds
);
4054 IDirect3DSurface8_Release(original_rt
);
4056 refcount
= IDirect3DDevice8_Release(device
);
4057 ok(!refcount
, "Device has %u references left.\n", refcount
);
4059 IDirect3D8_Release(d3d
);
4060 DestroyWindow(window
);
4063 static void zenable_test(void)
4065 IDirect3DDevice8
*device
;
4077 struct vec4 position
;
4082 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
4083 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
4084 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
4085 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
4088 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4089 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4090 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4091 ok(!!d3d
, "Failed to create a D3D object.\n");
4092 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4094 skip("Failed to create a D3D device, skipping tests.\n");
4098 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_FALSE
);
4099 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
4100 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
4101 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4103 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
4104 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4105 hr
= IDirect3DDevice8_BeginScene(device
);
4106 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4107 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, tquad
, sizeof(*tquad
));
4108 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4109 hr
= IDirect3DDevice8_EndScene(device
);
4110 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4112 for (i
= 0; i
< 4; ++i
)
4114 for (j
= 0; j
< 4; ++j
)
4116 x
= 80 * ((2 * j
) + 1);
4117 y
= 60 * ((2 * i
) + 1);
4118 color
= getPixelColor(device
, x
, y
);
4119 ok(color_match(color
, 0x0000ff00, 1),
4120 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
4124 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4125 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4127 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4128 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4130 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1)
4131 && caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1))
4133 static const DWORD vs_code
[] =
4135 0xfffe0101, /* vs_1_1 */
4136 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4137 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4140 static const DWORD ps_code
[] =
4142 0xffff0101, /* ps_1_1 */
4143 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4144 0x0000ffff /* end */
4146 static const struct vec3 quad
[] =
4148 {-1.0f
, -1.0f
, -0.5f
},
4149 {-1.0f
, 1.0f
, -0.5f
},
4150 { 1.0f
, -1.0f
, 1.5f
},
4151 { 1.0f
, 1.0f
, 1.5f
},
4153 static const D3DCOLOR expected
[] =
4155 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4156 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4157 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4158 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4160 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4161 * vertices either. */
4162 static const D3DCOLOR expected_broken
[] =
4164 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4165 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4166 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4167 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4169 static const DWORD decl
[] =
4172 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
4177 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_code
, &vs
, 0);
4178 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
4179 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
4180 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4181 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
4182 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
4183 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4184 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4186 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
4187 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4188 hr
= IDirect3DDevice8_BeginScene(device
);
4189 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4190 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4191 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4192 hr
= IDirect3DDevice8_EndScene(device
);
4193 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4195 for (i
= 0; i
< 4; ++i
)
4197 for (j
= 0; j
< 4; ++j
)
4199 x
= 80 * ((2 * j
) + 1);
4200 y
= 60 * ((2 * i
) + 1);
4201 color
= getPixelColor(device
, x
, y
);
4202 ok(color_match(color
, expected
[i
* 4 + j
], 1)
4203 || broken(color_match(color
, expected_broken
[i
* 4 + j
], 1)),
4204 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected
[i
* 4 + j
], x
, y
, color
);
4208 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4209 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4211 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4212 ok(SUCCEEDED(hr
), "Failed to delete pixel shader, hr %#x.\n", hr
);
4213 hr
= IDirect3DDevice8_DeleteVertexShader(device
, vs
);
4214 ok(SUCCEEDED(hr
), "Failed to delete vertex shader, hr %#x.\n", hr
);
4217 refcount
= IDirect3DDevice8_Release(device
);
4218 ok(!refcount
, "Device has %u references left.\n", refcount
);
4220 IDirect3D8_Release(d3d
);
4221 DestroyWindow(window
);
4224 static void fog_special_test(void)
4226 IDirect3DDevice8
*device
;
4243 struct vec3 position
;
4248 {{ -1.0f
, -1.0f
, 0.0f
}, 0xff00ff00},
4249 {{ -1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
4250 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
4251 {{ 1.0f
, 1.0f
, 1.0f
}, 0xff00ff00}
4255 DWORD vertexmode
, tablemode
;
4257 D3DCOLOR color_left
, color_right
;
4261 {D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, FALSE
, 0x00ff0000, 0x00ff0000},
4262 {D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, TRUE
, 0x00ff0000, 0x00ff0000},
4263 {D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000},
4264 {D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000},
4266 {D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, FALSE
, 0x0000ff00, 0x00ff0000},
4267 {D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, TRUE
, 0x0000ff00, 0x00ff0000},
4268 {D3DFOG_NONE
, D3DFOG_LINEAR
, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000},
4269 {D3DFOG_NONE
, D3DFOG_LINEAR
, TRUE
, TRUE
, 0x0000ff00, 0x00ff0000},
4271 static const DWORD pixel_shader_code
[] =
4273 0xffff0101, /* ps.1.1 */
4274 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4277 static const DWORD vertex_decl
[] =
4280 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
4281 D3DVSD_REG(1, D3DVSDT_D3DCOLOR
), /* diffuse color, v1 */
4284 static const DWORD vertex_shader_code
[] =
4286 0xfffe0101, /* vs.1.1 */
4287 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4288 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4291 static const D3DMATRIX identity
=
4293 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4294 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4295 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4296 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4299 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4300 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4301 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4302 ok(!!d3d
, "Failed to create a D3D object.\n");
4303 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4305 skip("Failed to create a D3D device, skipping tests.\n");
4309 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4310 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4311 if (caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1))
4313 hr
= IDirect3DDevice8_CreateVertexShader(device
, vertex_decl
, vertex_shader_code
, &vs
, 0);
4314 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
4318 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4321 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1))
4323 hr
= IDirect3DDevice8_CreatePixelShader(device
, pixel_shader_code
, &ps
);
4324 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4328 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4332 /* The table fog tests seem to depend on the projection matrix explicitly
4333 * being set to an identity matrix, even though that's the default.
4334 * (AMD Radeon HD 6310, Windows 7) */
4335 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
4336 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
4338 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
4339 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4340 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
4341 ok(SUCCEEDED(hr
), "Failed to enable fog, hr %#x.\n", hr
);
4342 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xffff0000);
4343 ok(SUCCEEDED(hr
), "Failed to set fog color, hr %#x.\n", hr
);
4346 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, conv
.d
);
4347 ok(SUCCEEDED(hr
), "Failed to set fog start, hr %#x.\n", hr
);
4348 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, conv
.d
);
4349 ok(SUCCEEDED(hr
), "Failed to set fog end, hr %#x.\n", hr
);
4351 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4353 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
4354 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4358 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
4359 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
4363 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
4364 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
4373 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
4374 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4378 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4379 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4386 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, tests
[i
].vertexmode
);
4387 ok(SUCCEEDED(hr
), "Failed to set fogvertexmode, hr %#x.\n", hr
);
4388 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, tests
[i
].tablemode
);
4389 ok(SUCCEEDED(hr
), "Failed to set fogtablemode, hr %#x.\n", hr
);
4391 hr
= IDirect3DDevice8_BeginScene(device
);
4392 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4393 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4394 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4395 hr
= IDirect3DDevice8_EndScene(device
);
4396 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4398 color
= getPixelColor(device
, 310, 240);
4399 ok(color_match(color
, tests
[i
].color_left
, 1),
4400 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_left
, color
, i
);
4401 color
= getPixelColor(device
, 330, 240);
4402 ok(color_match(color
, tests
[i
].color_right
, 1),
4403 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_right
, color
, i
);
4405 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4406 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4410 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
4412 IDirect3DDevice8_DeletePixelShader(device
, ps
);
4413 refcount
= IDirect3DDevice8_Release(device
);
4414 ok(!refcount
, "Device has %u references left.\n", refcount
);
4416 IDirect3D8_Release(d3d
);
4417 DestroyWindow(window
);
4420 static void volume_dxt5_test(void)
4422 IDirect3DVolumeTexture8
*texture
;
4423 IDirect3DDevice8
*device
;
4432 static const char texture_data
[] =
4434 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4435 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4436 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4437 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4438 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4442 struct vec3 position
;
4447 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.25f
}},
4448 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.25f
}},
4449 {{ 0.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.25f
}},
4450 {{ 0.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.25f
}},
4452 {{ 0.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.75f
}},
4453 {{ 0.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.75f
}},
4454 {{ 1.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.75f
}},
4455 {{ 1.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.75f
}},
4457 static const DWORD expected_colors
[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4459 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4460 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4461 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4462 ok(!!d3d
, "Failed to create a D3D object.\n");
4463 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4465 skip("Failed to create a D3D device, skipping tests.\n");
4469 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4470 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, D3DFMT_DXT5
)))
4472 skip("Volume DXT5 textures are not supported, skipping test.\n");
4473 IDirect3DDevice8_Release(device
);
4477 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 8, 4, 2, 1, 0, D3DFMT_DXT5
,
4478 D3DPOOL_MANAGED
, &texture
);
4479 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
4481 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &box
, NULL
, 0);
4482 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
4483 memcpy(box
.pBits
, texture_data
, sizeof(texture_data
));
4484 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
4485 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
4487 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0));
4488 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4489 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4490 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4491 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
4492 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
4493 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
4494 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
4495 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
4496 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
4497 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4498 ok(SUCCEEDED(hr
), "Failed to set mag filter, hr %#x.\n", hr
);
4500 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
4501 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
4502 hr
= IDirect3DDevice8_BeginScene(device
);
4503 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4504 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
4505 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4506 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
4507 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4508 hr
= IDirect3DDevice8_EndScene(device
);
4509 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4511 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4512 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4513 for (i
= 0; i
< 4; i
++)
4515 color
= getPixelColor(device
, 80 + 160 * i
, 240);
4516 ok (color_match(color
, expected_colors
[i
], 1),
4517 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors
[i
], color
, i
);
4520 IDirect3DVolumeTexture8_Release(texture
);
4521 refcount
= IDirect3DDevice8_Release(device
);
4522 ok(!refcount
, "Device has %u references left.\n", refcount
);
4524 IDirect3D8_Release(d3d
);
4525 DestroyWindow(window
);
4528 static void volume_v16u16_test(void)
4530 IDirect3DVolumeTexture8
*texture
;
4531 IDirect3DDevice8
*device
;
4545 struct vec3 position
;
4550 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.25f
}},
4551 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.25f
}},
4552 {{ 0.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.25f
}},
4553 {{ 0.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.25f
}},
4555 {{ 0.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.75f
}},
4556 {{ 0.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.75f
}},
4557 {{ 1.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.75f
}},
4558 {{ 1.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.75f
}},
4560 static const DWORD shader_code
[] =
4562 0xffff0101, /* ps_1_1 */
4563 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
4564 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
4565 0x00000042, 0xb00f0000, /* tex t0 */
4566 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
4567 0x0000ffff /* end */
4570 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4571 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4572 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4573 ok(!!d3d
, "Failed to create a D3D object.\n");
4574 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4576 skip("Failed to create a D3D device, skipping tests.\n");
4580 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4581 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, D3DFMT_V16U16
)))
4583 skip("Volume V16U16 textures are not supported, skipping test.\n");
4584 IDirect3DDevice8_Release(device
);
4587 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4588 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
4589 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
4591 skip("No pixel shader 1.1 support, skipping test.\n");
4592 IDirect3DDevice8_Release(device
);
4596 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0));
4597 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4598 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code
, &shader
);
4599 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4600 hr
= IDirect3DDevice8_SetPixelShader(device
, shader
);
4601 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4602 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4603 ok(SUCCEEDED(hr
), "Failed to set filter, hr %#x.\n", hr
);
4605 for (i
= 0; i
< 2; i
++)
4610 pool
= D3DPOOL_SYSTEMMEM
;
4612 pool
= D3DPOOL_MANAGED
;
4614 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 2, 2, 1, 0, D3DFMT_V16U16
,
4616 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
4618 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &box
, NULL
, 0);
4619 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
4621 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 0 * box
.RowPitch
+ 0 * box
.SlicePitch
);
4624 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 1 * box
.RowPitch
+ 0 * box
.SlicePitch
);
4627 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 0 * box
.RowPitch
+ 1 * box
.SlicePitch
);
4630 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 1 * box
.RowPitch
+ 1 * box
.SlicePitch
);
4634 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
4635 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
4639 IDirect3DVolumeTexture8
*texture2
;
4641 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 2, 2, 1, 0, D3DFMT_V16U16
,
4642 D3DPOOL_DEFAULT
, &texture2
);
4643 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
4645 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)texture
,
4646 (IDirect3DBaseTexture8
*)texture2
);
4647 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4649 IDirect3DVolumeTexture8_Release(texture
);
4653 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) texture
);
4654 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4656 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
4657 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
4658 hr
= IDirect3DDevice8_BeginScene(device
);
4659 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4660 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
4661 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4662 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
4663 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4664 hr
= IDirect3DDevice8_EndScene(device
);
4665 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4667 color
= getPixelColor(device
, 120, 160);
4668 ok (color_match(color
, 0x000080ff, 2),
4669 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color
);
4670 color
= getPixelColor(device
, 120, 400);
4671 ok (color_match(color
, 0x00ffffff, 2),
4672 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color
);
4673 color
= getPixelColor(device
, 360, 160);
4674 ok (color_match(color
, 0x007f7fff, 2),
4675 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color
);
4676 color
= getPixelColor(device
, 360, 400);
4677 ok (color_match(color
, 0x0040c0ff, 2),
4678 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color
);
4680 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4681 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4683 IDirect3DVolumeTexture8_Release(texture
);
4686 hr
= IDirect3DDevice8_DeletePixelShader(device
, shader
);
4687 ok(SUCCEEDED(hr
), "Failed delete pixel shader, hr %#x.\n", hr
);
4688 refcount
= IDirect3DDevice8_Release(device
);
4689 ok(!refcount
, "Device has %u references left.\n", refcount
);
4691 IDirect3D8_Release(d3d
);
4692 DestroyWindow(window
);
4695 static void fill_surface(IDirect3DSurface8
*surface
, DWORD color
, DWORD flags
)
4697 D3DSURFACE_DESC desc
;
4703 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
4704 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4705 hr
= IDirect3DSurface8_LockRect(surface
, &l
, NULL
, flags
);
4706 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4710 for (y
= 0; y
< desc
.Height
; y
++)
4712 mem
= (DWORD
*)((BYTE
*)l
.pBits
+ y
* l
.Pitch
);
4713 for (x
= 0; x
< l
.Pitch
/ sizeof(DWORD
); x
++)
4718 hr
= IDirect3DSurface8_UnlockRect(surface
);
4719 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4722 static void add_dirty_rect_test_draw(IDirect3DDevice8
*device
)
4727 struct vec3 position
;
4728 struct vec2 texcoord
;
4732 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
4733 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
4734 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
4735 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
4738 hr
= IDirect3DDevice8_BeginScene(device
);
4739 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4740 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
, sizeof(*quad
));
4741 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4742 hr
= IDirect3DDevice8_EndScene(device
);
4743 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4746 static void add_dirty_rect_test(void)
4748 IDirect3DSurface8
*surface_dst2
, *surface_src_green
, *surface_src_red
, *surface_managed
;
4749 IDirect3DTexture8
*tex_dst1
, *tex_dst2
, *tex_src_red
, *tex_src_green
, *tex_managed
;
4750 D3DLOCKED_RECT locked_rect
;
4751 IDirect3DDevice8
*device
;
4760 static const RECT part_rect
= {96, 96, 160, 160};
4762 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4763 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4764 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4765 ok(!!d3d
, "Failed to create a D3D object.\n");
4766 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4768 skip("Failed to create a D3D device, skipping tests.\n");
4772 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4773 D3DPOOL_DEFAULT
, &tex_dst1
);
4774 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4775 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4776 D3DPOOL_DEFAULT
, &tex_dst2
);
4777 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4778 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4779 D3DPOOL_SYSTEMMEM
, &tex_src_red
);
4780 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4781 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4782 D3DPOOL_SYSTEMMEM
, &tex_src_green
);
4783 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4784 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4785 D3DPOOL_MANAGED
, &tex_managed
);
4786 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4788 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_dst2
, 0, &surface_dst2
);
4789 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4790 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_src_green
, 0, &surface_src_green
);
4791 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4792 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_src_red
, 0, &surface_src_red
);
4793 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4794 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_managed
, 0, &surface_managed
);
4795 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4797 fill_surface(surface_src_red
, 0x00ff0000, 0);
4798 fill_surface(surface_src_green
, 0x0000ff00, 0);
4800 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
4801 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
4802 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
4803 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
4804 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
4805 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
4807 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4808 (IDirect3DBaseTexture8
*)tex_dst1
);
4809 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4811 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
4812 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_red
,
4813 (IDirect3DBaseTexture8
*)tex_dst2
);
4814 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4815 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4816 (IDirect3DBaseTexture8
*)tex_dst2
);
4817 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4819 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst1
);
4820 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4821 add_dirty_rect_test_draw(device
);
4822 color
= getPixelColor(device
, 320, 240);
4823 ok(color_match(color
, 0x0000ff00, 1),
4824 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4825 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4826 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4828 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst2
);
4829 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4830 add_dirty_rect_test_draw(device
);
4831 color
= getPixelColor(device
, 320, 240);
4832 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4833 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4834 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4835 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4837 /* AddDirtyRect on the destination is ignored. */
4838 hr
= IDirect3DTexture8_AddDirtyRect(tex_dst2
, &part_rect
);
4839 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4840 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4841 (IDirect3DBaseTexture8
*)tex_dst2
);
4842 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4843 add_dirty_rect_test_draw(device
);
4844 color
= getPixelColor(device
, 320, 240);
4845 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4846 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4847 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4848 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4850 hr
= IDirect3DTexture8_AddDirtyRect(tex_dst2
, NULL
);
4851 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4852 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4853 (IDirect3DBaseTexture8
*)tex_dst2
);
4854 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4855 add_dirty_rect_test_draw(device
);
4856 color
= getPixelColor(device
, 320, 240);
4857 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4858 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4859 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4860 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4862 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
4863 * tracking is supported. */
4864 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, &part_rect
);
4865 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4866 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4867 (IDirect3DBaseTexture8
*)tex_dst2
);
4868 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4869 add_dirty_rect_test_draw(device
);
4870 color
= getPixelColor(device
, 320, 240);
4871 ok(color_match(color
, 0x0000ff00, 1),
4872 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4873 color
= getPixelColor(device
, 1, 1);
4874 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4875 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4876 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4877 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4879 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, NULL
);
4880 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4881 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4882 (IDirect3DBaseTexture8
*)tex_dst2
);
4883 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4884 add_dirty_rect_test_draw(device
);
4885 color
= getPixelColor(device
, 1, 1);
4886 ok(color_match(color
, 0x0000ff00, 1),
4887 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4889 /* Locks with NO_DIRTY_UPDATE are ignored. */
4890 fill_surface(surface_src_green
, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE
);
4891 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4892 (IDirect3DBaseTexture8
*)tex_dst2
);
4893 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4894 add_dirty_rect_test_draw(device
);
4895 color
= getPixelColor(device
, 320, 240);
4896 todo_wine
ok(color_match(color
, 0x0000ff00, 1),
4897 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4898 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4899 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4901 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
4902 fill_surface(surface_src_green
, 0x000000ff, D3DLOCK_READONLY
);
4903 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4904 (IDirect3DBaseTexture8
*)tex_dst2
);
4905 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4906 add_dirty_rect_test_draw(device
);
4907 color
= getPixelColor(device
, 320, 240);
4908 todo_wine
ok(color_match(color
, 0x0000ff00, 1),
4909 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4910 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4911 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4913 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, NULL
);
4914 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4915 (IDirect3DBaseTexture8
*)tex_dst2
);
4916 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4917 add_dirty_rect_test_draw(device
);
4918 color
= getPixelColor(device
, 320, 240);
4919 ok(color_match(color
, 0x000000ff, 1),
4920 "Expected color 0x000000ff, got 0x%08x.\n", color
);
4921 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4922 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4924 /* Maps without either of these flags record a dirty rectangle. */
4925 fill_surface(surface_src_green
, 0x00ffffff, 0);
4926 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4927 (IDirect3DBaseTexture8
*)tex_dst2
);
4928 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4929 add_dirty_rect_test_draw(device
);
4930 color
= getPixelColor(device
, 320, 240);
4931 ok(color_match(color
, 0x00ffffff, 1),
4932 "Expected color 0x00ffffff, got 0x%08x.\n", color
);
4933 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4934 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4936 /* Partial LockRect works just like a partial AddDirtyRect call. */
4937 hr
= IDirect3DTexture8_LockRect(tex_src_green
, 0, &locked_rect
, &part_rect
, 0);
4938 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
4939 texel
= locked_rect
.pBits
;
4940 for (i
= 0; i
< 64; i
++)
4941 texel
[i
] = 0x00ff00ff;
4942 for (i
= 1; i
< 64; i
++)
4943 memcpy((BYTE
*)locked_rect
.pBits
+ i
* locked_rect
.Pitch
, locked_rect
.pBits
, locked_rect
.Pitch
);
4944 hr
= IDirect3DTexture8_UnlockRect(tex_src_green
, 0);
4945 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
4946 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4947 (IDirect3DBaseTexture8
*)tex_dst2
);
4948 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4949 add_dirty_rect_test_draw(device
);
4950 color
= getPixelColor(device
, 320, 240);
4951 ok(color_match(color
, 0x00ff00ff, 1),
4952 "Expected color 0x00ff00ff, got 0x%08x.\n", color
);
4953 color
= getPixelColor(device
, 1, 1);
4954 ok(color_match(color
, 0x00ffffff, 1),
4955 "Expected color 0x00ffffff, got 0x%08x.\n", color
);
4956 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4957 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4959 fill_surface(surface_src_red
, 0x00ff0000, 0);
4960 fill_surface(surface_src_green
, 0x0000ff00, 0);
4962 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4963 (IDirect3DBaseTexture8
*)tex_dst1
);
4964 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4965 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst1
);
4966 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4967 add_dirty_rect_test_draw(device
);
4968 color
= getPixelColor(device
, 320, 240);
4969 ok(color_match(color
, 0x0000ff00, 1),
4970 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4971 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4972 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4974 /* UpdateSurface ignores the missing dirty marker. */
4975 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_red
,
4976 (IDirect3DBaseTexture8
*)tex_dst2
);
4977 hr
= IDirect3DDevice8_CopyRects(device
, surface_src_green
, NULL
, 0, surface_dst2
, NULL
);
4978 ok(SUCCEEDED(hr
), "Failed to update surface, hr %#x.\n", hr
);
4979 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst2
);
4980 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4981 add_dirty_rect_test_draw(device
);
4982 color
= getPixelColor(device
, 320, 240);
4983 ok(color_match(color
, 0x0000ff00, 1),
4984 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4985 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4986 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4988 fill_surface(surface_managed
, 0x00ff0000, 0);
4989 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_managed
);
4990 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4991 add_dirty_rect_test_draw(device
);
4992 color
= getPixelColor(device
, 320, 240);
4993 ok(color_match(color
, 0x00ff0000, 1),
4994 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4995 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4996 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4998 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
4999 fill_surface(surface_managed
, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE
);
5000 add_dirty_rect_test_draw(device
);
5001 color
= getPixelColor(device
, 320, 240);
5002 ok(color_match(color
, 0x00ff0000, 1),
5003 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5004 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5005 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5007 /* AddDirtyRect uploads the new contents.
5008 * Side note, not tested in the test: Partial surface updates work, and two separate
5009 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5011 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5012 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5013 add_dirty_rect_test_draw(device
);
5014 color
= getPixelColor(device
, 320, 240);
5015 ok(color_match(color
, 0x0000ff00, 1),
5016 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5017 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5018 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5020 /* So does ResourceManagerDiscardBytes. */
5021 fill_surface(surface_managed
, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE
);
5022 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5023 hr
= IDirect3DDevice8_ResourceManagerDiscardBytes(device
, 0);
5024 ok(SUCCEEDED(hr
), "Failed to evict managed resources, hr %#x.\n", hr
);
5025 add_dirty_rect_test_draw(device
);
5026 color
= getPixelColor(device
, 320, 240);
5027 ok(color_match(color
, 0x000000ff, 1),
5028 "Expected color 0x000000ff, got 0x%08x.\n", color
);
5029 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5030 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5032 /* AddDirtyRect on a locked texture is allowed. */
5033 hr
= IDirect3DTexture8_LockRect(tex_src_red
, 0, &locked_rect
, NULL
, 0);
5034 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5035 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_red
, NULL
);
5036 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5037 hr
= IDirect3DTexture8_UnlockRect(tex_src_red
, 0);
5038 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5040 /* Redundant AddDirtyRect calls are ok. */
5041 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5042 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5043 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5044 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5046 IDirect3DSurface8_Release(surface_dst2
);
5047 IDirect3DSurface8_Release(surface_managed
);
5048 IDirect3DSurface8_Release(surface_src_red
);
5049 IDirect3DSurface8_Release(surface_src_green
);
5050 IDirect3DTexture8_Release(tex_src_red
);
5051 IDirect3DTexture8_Release(tex_src_green
);
5052 IDirect3DTexture8_Release(tex_dst1
);
5053 IDirect3DTexture8_Release(tex_dst2
);
5054 IDirect3DTexture8_Release(tex_managed
);
5055 refcount
= IDirect3DDevice8_Release(device
);
5056 ok(!refcount
, "Device has %u references left.\n", refcount
);
5058 IDirect3D8_Release(d3d
);
5059 DestroyWindow(window
);
5064 D3DADAPTER_IDENTIFIER8 identifier
;
5068 if (!(d3d
= Direct3DCreate8(D3D_SDK_VERSION
)))
5070 skip("Failed to create D3D8 object.\n");
5074 memset(&identifier
, 0, sizeof(identifier
));
5075 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
5076 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#x.\n", hr
);
5077 trace("Driver string: \"%s\"\n", identifier
.Driver
);
5078 trace("Description string: \"%s\"\n", identifier
.Description
);
5079 /* Only Windows XP's default VGA driver should have an empty description */
5080 ok(identifier
.Description
[0] || broken(!strcmp(identifier
.Driver
, "vga.dll")), "Empty driver description.\n");
5081 trace("Driver version %d.%d.%d.%d\n",
5082 HIWORD(U(identifier
.DriverVersion
).HighPart
), LOWORD(U(identifier
.DriverVersion
).HighPart
),
5083 HIWORD(U(identifier
.DriverVersion
).LowPart
), LOWORD(U(identifier
.DriverVersion
).LowPart
));
5085 IDirect3D8_Release(d3d
);
5095 test_scalar_instructions();
5096 fog_with_shader_test();
5100 depth_buffer_test();
5101 depth_buffer2_test();
5104 multisample_copy_rects_test();
5109 volume_v16u16_test();
5110 add_dirty_rect_test();