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
)))
136 static void test_sanity(void)
138 IDirect3DDevice8
*device
;
145 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
146 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
147 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
148 ok(!!d3d
, "Failed to create a D3D object.\n");
149 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
151 skip("Failed to create a D3D device, skipping tests.\n");
155 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
156 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
157 color
= getPixelColor(device
, 1, 1);
158 ok(color
== 0x00ff0000, "Got unexpected color 0x%08x.\n", color
);
160 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
161 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
163 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ddee, 1.0f
, 0);
164 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
165 color
= getPixelColor(device
, 639, 479);
166 ok(color
== 0x0000ddee, "Got unexpected color 0x%08x.\n", color
);
168 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
169 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
171 refcount
= IDirect3DDevice8_Release(device
);
172 ok(!refcount
, "Device has %u references left.\n", refcount
);
174 IDirect3D8_Release(d3d
);
175 DestroyWindow(window
);
178 static void lighting_test(void)
180 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
181 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
182 IDirect3DDevice8
*device
;
191 struct vec3 position
;
196 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
197 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
198 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
199 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
203 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
204 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
205 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
206 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
210 struct vec3 position
;
216 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
217 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
218 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
219 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
223 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
224 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
225 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
226 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
228 static const WORD Indices
[] = {0, 1, 2, 2, 3, 0};
229 static const D3DMATRIX mat
=
231 1.0f
, 0.0f
, 0.0f
, 0.0f
,
232 0.0f
, 1.0f
, 0.0f
, 0.0f
,
233 0.0f
, 0.0f
, 1.0f
, 0.0f
,
234 0.0f
, 0.0f
, 0.0f
, 1.0f
,
237 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
238 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
239 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
240 ok(!!d3d
, "Failed to create a D3D object.\n");
241 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
243 skip("Failed to create a D3D device, skipping tests.\n");
247 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
248 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
250 /* Setup some states that may cause issues */
251 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &mat
);
252 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
253 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_VIEW
, &mat
);
254 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
255 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &mat
);
256 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
257 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
258 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
259 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
260 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
261 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, FALSE
);
262 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
263 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_STENCILENABLE
, FALSE
);
264 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
265 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHATESTENABLE
, FALSE
);
266 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
267 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, FALSE
);
268 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr
);
269 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CULLMODE
, D3DCULL_NONE
);
270 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr
);
271 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
);
272 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr
);
274 hr
= IDirect3DDevice8_SetVertexShader(device
, fvf
);
275 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
277 hr
= IDirect3DDevice8_BeginScene(device
);
278 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
280 /* No lights are defined... That means, lit vertices should be entirely black. */
281 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
282 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
283 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
284 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, unlitquad
, sizeof(unlitquad
[0]));
285 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
287 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
288 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
289 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
290 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, litquad
, sizeof(litquad
[0]));
291 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
293 hr
= IDirect3DDevice8_SetVertexShader(device
, nfvf
);
294 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
296 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
297 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
298 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
299 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, unlitnquad
, sizeof(unlitnquad
[0]));
300 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
302 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, TRUE
);
303 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
304 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
305 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, litnquad
, sizeof(litnquad
[0]));
306 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
308 hr
= IDirect3DDevice8_EndScene(device
);
309 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
311 color
= getPixelColor(device
, 160, 360); /* Lower left quad - unlit without normals */
312 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color
);
313 color
= getPixelColor(device
, 160, 120); /* Upper left quad - lit without normals */
314 ok(color
== 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color
);
315 color
= getPixelColor(device
, 480, 360); /* Lower right quad - unlit with normals */
316 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color
);
317 color
= getPixelColor(device
, 480, 120); /* Upper right quad - lit with normals */
318 ok(color
== 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color
);
320 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
322 refcount
= IDirect3DDevice8_Release(device
);
323 ok(!refcount
, "Device has %u references left.\n", refcount
);
325 IDirect3D8_Release(d3d
);
326 DestroyWindow(window
);
329 static void clear_test(void)
331 /* Tests the correctness of clearing parameters */
332 D3DRECT rect_negneg
, rect
[2];
333 IDirect3DDevice8
*device
;
340 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
341 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
342 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
343 ok(!!d3d
, "Failed to create a D3D object.\n");
344 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
346 skip("Failed to create a D3D device, skipping tests.\n");
350 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
351 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
353 /* Positive x, negative y */
359 /* Positive x, positive y */
364 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
365 * is ignored, the positive is still cleared afterwards
367 hr
= IDirect3DDevice8_Clear(device
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
368 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
370 /* negative x, negative y */
371 rect_negneg
.x1
= 640;
372 rect_negneg
.y1
= 240;
373 rect_negneg
.x2
= 320;
375 hr
= IDirect3DDevice8_Clear(device
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
376 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
378 color
= getPixelColor(device
, 160, 360); /* lower left quad */
379 ok(color
== 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color
);
380 color
= getPixelColor(device
, 160, 120); /* upper left quad */
381 ok(color
== 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color
);
382 color
= getPixelColor(device
, 480, 360); /* lower right quad */
383 ok(color
== 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color
);
384 color
= getPixelColor(device
, 480, 120); /* upper right quad */
385 ok(color
== 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color
);
387 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
389 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
390 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
396 hr
= IDirect3DDevice8_Clear(device
, 0, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
397 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
399 color
= getPixelColor(device
, 320, 240);
400 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
401 "Clear with count = 0, rect != NULL has color %#08x\n", color
);
403 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
405 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
406 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
407 hr
= IDirect3DDevice8_Clear(device
, 1, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0, 0);
408 ok(SUCCEEDED(hr
), "IDirect3DDevice8_Clear failed with %#08x\n", hr
);
410 color
= getPixelColor(device
, 320, 240);
411 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
412 "Clear with count = 1, rect = NULL has color %#08x\n", color
);
414 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
416 refcount
= IDirect3DDevice8_Release(device
);
417 ok(!refcount
, "Device has %u references left.\n", refcount
);
419 IDirect3D8_Release(d3d
);
420 DestroyWindow(window
);
423 static void fog_test(void)
425 float start
= 0.0f
, end
= 1.0f
;
426 IDirect3DDevice8
*device
;
434 /* Gets full z based fog with linear fog, no fog with specular color. */
443 {-1.0f
, -1.0f
, 0.1f
, 0xffff0000, 0xff000000},
444 {-1.0f
, 0.0f
, 0.1f
, 0xffff0000, 0xff000000},
445 { 0.0f
, 0.0f
, 0.1f
, 0xffff0000, 0xff000000},
446 { 0.0f
, -1.0f
, 0.1f
, 0xffff0000, 0xff000000},
448 /* Ok, I am too lazy to deal with transform matrices. */
451 {-1.0f
, 0.0f
, 1.0f
, 0xffff0000, 0xff000000},
452 {-1.0f
, 1.0f
, 1.0f
, 0xffff0000, 0xff000000},
453 { 0.0f
, 1.0f
, 1.0f
, 0xffff0000, 0xff000000},
454 { 0.0f
, 0.0f
, 1.0f
, 0xffff0000, 0xff000000},
458 {-1.0f
, -1.0f
, 0.5f
, 0xffff0000, 0xff000000},
459 {-1.0f
, 0.0f
, 0.5f
, 0xffff0000, 0xff000000},
460 { 0.0f
, 0.0f
, 0.5f
, 0xffff0000, 0xff000000},
461 { 0.0f
, -1.0f
, 0.5f
, 0xffff0000, 0xff000000},
465 {-1.0f
, 0.0f
, 1.5f
, 0xffff0000, 0xff000000},
466 {-1.0f
, 1.0f
, 1.5f
, 0xffff0000, 0xff000000},
467 { 0.0f
, 1.0f
, 1.5f
, 0xffff0000, 0xff000000},
468 { 0.0f
, 0.0f
, 1.5f
, 0xffff0000, 0xff000000},
471 /* Untransformed ones. Give them a different diffuse color to make the
472 * test look nicer. It also makes making sure that they are drawn
473 * correctly easier. */
482 {320.0f
, 0.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
483 {640.0f
, 0.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
484 {640.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
485 {320.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
489 {320.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
490 {640.0f
, 240.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
491 {640.0f
, 480.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
492 {320.0f
, 480.0f
, 1.0f
, 1.0f
, 0xffffff00, 0xff000000},
494 static const D3DMATRIX ident_mat
=
496 1.0f
, 0.0f
, 0.0f
, 0.0f
,
497 0.0f
, 1.0f
, 0.0f
, 0.0f
,
498 0.0f
, 0.0f
, 1.0f
, 0.0f
,
499 0.0f
, 0.0f
, 0.0f
, 1.0f
,
501 static const D3DMATRIX world_mat1
=
503 1.0f
, 0.0f
, 0.0f
, 0.0f
,
504 0.0f
, 1.0f
, 0.0f
, 0.0f
,
505 0.0f
, 0.0f
, 1.0f
, 0.0f
,
506 0.0f
, 0.0f
, -0.5f
, 1.0f
,
508 static const D3DMATRIX world_mat2
=
510 1.0f
, 0.0f
, 0.0f
, 0.0f
,
511 0.0f
, 1.0f
, 0.0f
, 0.0f
,
512 0.0f
, 0.0f
, 1.0f
, 0.0f
,
513 0.0f
, 0.0f
, 1.0f
, 1.0f
,
515 static const D3DMATRIX proj_mat
=
517 1.0f
, 0.0f
, 0.0f
, 0.0f
,
518 0.0f
, 1.0f
, 0.0f
, 0.0f
,
519 0.0f
, 0.0f
, 1.0f
, 0.0f
,
520 0.0f
, 0.0f
, -1.0f
, 1.0f
,
522 static const WORD Indices
[] = {0, 1, 2, 2, 3, 0};
524 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
525 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
526 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
527 ok(!!d3d
, "Failed to create a D3D object.\n");
528 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
530 skip("Failed to create a D3D device, skipping tests.\n");
534 memset(&caps
, 0, sizeof(caps
));
535 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
536 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr
);
537 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
538 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %#08x\n", hr
);
540 /* Setup initial states: No lighting, fog on, fog color */
541 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
542 ok(SUCCEEDED(hr
), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr
);
543 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
544 ok(hr
== D3D_OK
, "Turning off lighting returned %#08x\n", hr
);
545 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
546 ok(hr
== D3D_OK
, "Turning on fog calculations returned %#08x\n", hr
);
547 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xFF00FF00 /* A nice green */);
548 ok(hr
== D3D_OK
, "Setting fog color returned %#08x\n", hr
);
549 /* Some of the tests seem to depend on the projection matrix explicitly
550 * being set to an identity matrix, even though that's the default.
551 * (AMD Radeon HD 6310, Windows 7) */
552 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &ident_mat
);
553 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
555 /* First test: Both table fog and vertex fog off */
556 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
557 ok(hr
== D3D_OK
, "Turning off table fog returned %#08x\n", hr
);
558 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
559 ok(hr
== D3D_OK
, "Turning off vertex fog returned %#08x\n", hr
);
561 /* Start = 0, end = 1. Should be default, but set them */
562 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, *((DWORD
*) &start
));
563 ok(hr
== D3D_OK
, "Setting fog start returned %#08x\n", hr
);
564 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, *((DWORD
*) &end
));
565 ok(hr
== D3D_OK
, "Setting fog start returned %#08x\n", hr
);
567 hr
= IDirect3DDevice8_BeginScene(device
);
568 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
570 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
571 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
572 /* Untransformed, vertex fog = NONE, table fog = NONE:
573 * Read the fog weighting from the specular color. */
574 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
575 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, untransformed_1
, sizeof(untransformed_1
[0]));
576 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
578 /* This makes it use the Z value. */
579 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_LINEAR
);
580 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
581 /* Untransformed, vertex fog != none (or table fog != none):
582 * Use the Z value as input into the equation. */
583 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
584 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, untransformed_2
, sizeof(untransformed_2
[0]));
585 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
587 /* Transformed vertices. */
588 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
589 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
590 /* Transformed, vertex fog != NONE, pixel fog == NONE:
591 * Use specular color alpha component. */
592 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
593 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, transformed_1
, sizeof(transformed_1
[0]));
594 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
596 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
597 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
598 /* Transformed, table fog != none, vertex anything:
599 * Use Z value as input to the fog equation. */
600 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 4 /* NumVerts */,
601 2 /* PrimCount */, Indices
, D3DFMT_INDEX16
, transformed_2
, sizeof(transformed_2
[0]));
602 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
604 hr
= IDirect3DDevice8_EndScene(device
);
605 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
607 color
= getPixelColor(device
, 160, 360);
608 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
609 "Untransformed vertex with no table or vertex fog has color %08x\n", color
);
610 color
= getPixelColor(device
, 160, 120);
611 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
612 "Untransformed vertex with linear vertex fog has color %08x\n", color
);
613 color
= getPixelColor(device
, 480, 120);
614 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
615 "Transformed vertex with linear vertex fog has color %08x\n", color
);
616 color
= getPixelColor(device
, 480, 360);
617 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
618 "Transformed vertex with linear table fog has color %08x\n", color
);
620 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
622 if (caps
.RasterCaps
& D3DPRASTERCAPS_FOGTABLE
)
624 /* A simple fog + non-identity world matrix test */
625 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &world_mat1
);
626 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTransform returned %#08x\n", hr
);
628 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_LINEAR
);
629 ok(hr
== D3D_OK
, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr
);
630 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
631 ok(hr
== D3D_OK
, "Turning off vertex fog returned %#08x\n", hr
);
633 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
634 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %#08x\n", hr
);
636 hr
= IDirect3DDevice8_BeginScene(device
);
637 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
638 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
639 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
640 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
641 2, Indices
, D3DFMT_INDEX16
, far_quad1
, sizeof(far_quad1
[0]));
642 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
643 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
644 2, Indices
, D3DFMT_INDEX16
, far_quad2
, sizeof(far_quad2
[0]));
645 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
646 hr
= IDirect3DDevice8_EndScene(device
);
647 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
649 color
= getPixelColor(device
, 160, 360);
650 ok(color_match(color
, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color
);
651 color
= getPixelColor(device
, 160, 120);
652 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
653 "Fogged out quad has color %08x\n", color
);
655 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
657 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
658 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_WORLDMATRIX(0), &world_mat2
);
659 ok(hr
== D3D_OK
, "SetTransform returned %#08x\n", hr
);
660 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &proj_mat
);
661 ok(hr
== D3D_OK
, "SetTransform returned %#08x\n", hr
);
663 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 0.0, 0);
664 ok(hr
== D3D_OK
, "Clear returned %#08x\n", hr
);
666 hr
= IDirect3DDevice8_BeginScene(device
);
667 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
668 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
);
669 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
670 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
671 2, Indices
, D3DFMT_INDEX16
, untransformed_1
, sizeof(untransformed_1
[0]));
672 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
673 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4,
674 2, Indices
, D3DFMT_INDEX16
, untransformed_2
, sizeof(untransformed_2
[0]));
675 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
676 hr
= IDirect3DDevice8_EndScene(device
);
677 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
679 color
= getPixelColor(device
, 160, 360);
680 ok(color_match(color
, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color
);
681 color
= getPixelColor(device
, 160, 120);
682 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
683 "Fogged out quad has color %08x\n", color
);
685 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
689 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
692 refcount
= IDirect3DDevice8_Release(device
);
693 ok(!refcount
, "Device has %u references left.\n", refcount
);
695 IDirect3D8_Release(d3d
);
696 DestroyWindow(window
);
699 /* This tests fog in combination with shaders.
700 * What's tested: linear fog (vertex and table) with pixel shader
701 * linear table fog with non foggy vertex shader
702 * vertex fog with foggy vertex shader, non-linear
703 * fog with shader, non-linear fog with foggy shader,
704 * linear table fog with foggy shader */
705 static void fog_with_shader_test(void)
707 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
708 DWORD vertex_shader
[3] = {D3DFVF_XYZ
| D3DFVF_DIFFUSE
, 0, 0};
709 DWORD pixel_shader
[2] = {0, 0};
710 IDirect3DDevice8
*device
;
724 /* Basic vertex shader without fog computation ("non foggy") */
725 static const DWORD vertex_shader_code1
[] =
727 0xfffe0100, /* vs.1.0 */
728 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
729 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
732 /* Basic vertex shader with reversed fog computation ("foggy") */
733 static const DWORD vertex_shader_code2
[] =
735 0xfffe0100, /* vs.1.0 */
736 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
737 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
738 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
739 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
742 /* Basic pixel shader */
743 static const DWORD pixel_shader_code
[] =
745 0xffff0101, /* ps_1_1 */
746 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
751 struct vec3 position
;
756 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
757 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
758 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
759 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
761 static const DWORD decl
[] =
764 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
765 D3DVSD_REG(1, D3DVSDT_D3DCOLOR
), /* diffuse color, v1 */
768 static const float vs_constant
[4] = {-1.25f
, 0.0f
, -0.9f
, 0.0f
};
769 /* This reference data was collected on a nVidia GeForce 7600GS
770 * driver version 84.19 DirectX version 9.0c on Windows XP */
771 static const struct test_data_t
777 unsigned int color
[11];
781 /* Only pixel shader */
782 {0, 1, D3DFOG_NONE
, D3DFOG_LINEAR
,
783 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
784 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
785 {0, 1, D3DFOG_EXP
, D3DFOG_LINEAR
,
786 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
787 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
788 {0, 1, D3DFOG_EXP2
, D3DFOG_LINEAR
,
789 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
790 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
791 {0, 1, D3DFOG_LINEAR
, D3DFOG_NONE
,
792 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
793 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
794 {0, 1, D3DFOG_LINEAR
, D3DFOG_LINEAR
,
795 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
796 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
799 {1, 0, D3DFOG_NONE
, D3DFOG_NONE
,
800 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
801 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
802 {1, 0, D3DFOG_NONE
, D3DFOG_LINEAR
,
803 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
804 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
805 {1, 0, D3DFOG_EXP
, D3DFOG_LINEAR
,
806 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
807 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
809 {1, 0, D3DFOG_EXP2
, D3DFOG_LINEAR
,
810 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
811 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
812 {1, 0, D3DFOG_LINEAR
, D3DFOG_LINEAR
,
813 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
814 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
816 /* Vertex shader and pixel shader */
817 /* The next 4 tests would read the fog coord output, but it isn't available.
818 * The result is a fully fogged quad, no matter what the Z coord is. */
819 {1, 1, D3DFOG_NONE
, D3DFOG_NONE
,
820 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
821 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
822 {1, 1, D3DFOG_LINEAR
, D3DFOG_NONE
,
823 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
824 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
825 {1, 1, D3DFOG_EXP
, D3DFOG_NONE
,
826 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
827 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
828 {1, 1, D3DFOG_EXP2
, D3DFOG_NONE
,
829 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
830 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
832 /* These use the Z coordinate with linear table fog */
833 {1, 1, D3DFOG_NONE
, D3DFOG_LINEAR
,
834 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
835 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
836 {1, 1, D3DFOG_EXP
, D3DFOG_LINEAR
,
837 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
838 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
839 {1, 1, D3DFOG_EXP2
, D3DFOG_LINEAR
,
840 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
841 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
842 {1, 1, D3DFOG_LINEAR
, D3DFOG_LINEAR
,
843 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
844 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
846 /* Non-linear table fog without fog coord */
847 {1, 1, D3DFOG_NONE
, D3DFOG_EXP
,
848 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
849 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
850 {1, 1, D3DFOG_NONE
, D3DFOG_EXP2
,
851 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
852 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
854 /* These tests fail on older Nvidia drivers */
855 /* Foggy vertex shader */
856 {2, 0, D3DFOG_NONE
, D3DFOG_NONE
,
857 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
858 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
859 {2, 0, D3DFOG_EXP
, D3DFOG_NONE
,
860 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
861 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
862 {2, 0, D3DFOG_EXP2
, D3DFOG_NONE
,
863 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
864 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
865 {2, 0, D3DFOG_LINEAR
, D3DFOG_NONE
,
866 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
867 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
869 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
870 * all using the fixed fog-coord linear fog */
871 {2, 1, D3DFOG_NONE
, D3DFOG_NONE
,
872 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
873 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
874 {2, 1, D3DFOG_EXP
, D3DFOG_NONE
,
875 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
876 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
877 {2, 1, D3DFOG_EXP2
, D3DFOG_NONE
,
878 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
879 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
880 {2, 1, D3DFOG_LINEAR
, D3DFOG_NONE
,
881 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
882 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
884 /* These use table fog. Here the shader-provided fog coordinate is
885 * ignored and the z coordinate used instead */
886 {2, 1, D3DFOG_NONE
, D3DFOG_EXP
,
887 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
888 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
889 {2, 1, D3DFOG_NONE
, D3DFOG_EXP2
,
890 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
891 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
892 {2, 1, D3DFOG_NONE
, D3DFOG_LINEAR
,
893 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
894 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
896 static const D3DMATRIX identity
=
898 1.0f
, 0.0f
, 0.0f
, 0.0f
,
899 0.0f
, 1.0f
, 0.0f
, 0.0f
,
900 0.0f
, 0.0f
, 1.0f
, 0.0f
,
901 0.0f
, 0.0f
, 0.0f
, 1.0f
,
904 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
905 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
906 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
907 ok(!!d3d
, "Failed to create a D3D object.\n");
908 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
910 skip("Failed to create a D3D device, skipping tests.\n");
914 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
915 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
916 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1) || caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
918 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
919 IDirect3DDevice8_Release(device
);
923 /* NOTE: changing these values will not affect the tests with foggy vertex
924 * shader, as the values are hardcoded in the shader constant. */
928 /* Some of the tests seem to depend on the projection matrix explicitly
929 * being set to an identity matrix, even though that's the default.
930 * (AMD Radeon HD 6310, Windows 7) */
931 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
932 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
934 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vertex_shader_code1
, &vertex_shader
[1], 0);
935 ok(SUCCEEDED(hr
), "CreateVertexShader failed (%08x)\n", hr
);
936 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vertex_shader_code2
, &vertex_shader
[2], 0);
937 ok(SUCCEEDED(hr
), "CreateVertexShader failed (%08x)\n", hr
);
938 hr
= IDirect3DDevice8_CreatePixelShader(device
, pixel_shader_code
, &pixel_shader
[1]);
939 ok(SUCCEEDED(hr
), "CreatePixelShader failed (%08x)\n", hr
);
941 /* Set shader constant value */
942 hr
= IDirect3DDevice8_SetVertexShader(device
, vertex_shader
[2]);
943 ok(SUCCEEDED(hr
), "SetVertexShader failed (%08x)\n", hr
);
944 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, vs_constant
, 1);
945 ok(hr
== D3D_OK
, "Setting vertex shader constant failed (%08x)\n", hr
);
947 /* Setup initial states: No lighting, fog on, fog color */
948 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
949 ok(hr
== D3D_OK
, "Turning off lighting failed (%08x)\n", hr
);
950 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
951 ok(hr
== D3D_OK
, "Turning on fog calculations failed (%08x)\n", hr
);
952 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xFF00FF00 /* A nice green */);
953 ok(hr
== D3D_OK
, "Setting fog color failed (%08x)\n", hr
);
955 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
956 ok(hr
== D3D_OK
, "Turning off table fog failed (%08x)\n", hr
);
957 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
958 ok(hr
== D3D_OK
, "Turning off vertex fog failed (%08x)\n", hr
);
960 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
961 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, start
.i
);
962 ok(hr
== D3D_OK
, "Setting fog start failed (%08x)\n", hr
);
963 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, end
.i
);
964 ok(hr
== D3D_OK
, "Setting fog end failed (%08x)\n", hr
);
966 for (i
= 0; i
< sizeof(test_data
)/sizeof(test_data
[0]); ++i
)
968 hr
= IDirect3DDevice8_SetVertexShader(device
, vertex_shader
[test_data
[i
].vshader
]);
969 ok(SUCCEEDED(hr
), "SetVertexShader failed (%08x)\n", hr
);
970 hr
= IDirect3DDevice8_SetPixelShader(device
, pixel_shader
[test_data
[i
].pshader
]);
971 ok(SUCCEEDED(hr
), "SetPixelShader failed (%08x)\n", hr
);
972 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, test_data
[i
].vfog
);
973 ok( hr
== D3D_OK
, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr
);
974 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, test_data
[i
].tfog
);
975 ok( hr
== D3D_OK
, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr
);
977 for(j
= 0; j
< 11; ++j
)
979 /* Don't use the whole zrange to prevent rounding errors */
980 quad
[0].position
.z
= 0.001f
+ j
/ 10.02f
;
981 quad
[1].position
.z
= 0.001f
+ j
/ 10.02f
;
982 quad
[2].position
.z
= 0.001f
+ j
/ 10.02f
;
983 quad
[3].position
.z
= 0.001f
+ j
/ 10.02f
;
985 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff00ff, 1.0f
, 0);
986 ok(hr
== D3D_OK
, "IDirect3DDevice9_Clear failed (%08x)\n", hr
);
988 hr
= IDirect3DDevice8_BeginScene(device
);
989 ok( hr
== D3D_OK
, "BeginScene returned failed (%08x)\n", hr
);
991 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(quad
[0]));
992 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed (%08x)\n", hr
);
994 hr
= IDirect3DDevice8_EndScene(device
);
995 ok(hr
== D3D_OK
, "EndScene failed (%08x)\n", hr
);
997 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
998 color
= getPixelColor(device
, 128, 240);
999 ok(color_match(color
, test_data
[i
].color
[j
], 13),
1000 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1001 test_data
[i
].vshader
, test_data
[i
].pshader
,
1002 test_data
[i
].vfog
, test_data
[i
].tfog
, j
, color
, test_data
[i
].color
[j
]);
1004 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1008 IDirect3DDevice8_DeleteVertexShader(device
, vertex_shader
[1]);
1009 IDirect3DDevice8_DeleteVertexShader(device
, vertex_shader
[2]);
1010 IDirect3DDevice8_DeleteVertexShader(device
, pixel_shader
[1]);
1011 refcount
= IDirect3DDevice8_Release(device
);
1012 ok(!refcount
, "Device has %u references left.\n", refcount
);
1014 IDirect3D8_Release(d3d
);
1015 DestroyWindow(window
);
1018 static void cnd_test(void)
1020 DWORD shader_11_coissue_2
, shader_12_coissue_2
, shader_13_coissue_2
, shader_14_coissue_2
;
1021 DWORD shader_11_coissue
, shader_12_coissue
, shader_13_coissue
, shader_14_coissue
;
1022 DWORD shader_11
, shader_12
, shader_13
, shader_14
;
1023 IDirect3DDevice8
*device
;
1031 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1032 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1033 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1034 * in 1.x pixel shaders. */
1035 static const DWORD shader_code_11
[] =
1037 0xffff0101, /* ps_1_1 */
1038 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1039 0x00000040, 0xb00f0000, /* texcoord t0 */
1040 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1041 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1042 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1043 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1044 0x0000ffff /* end */
1046 static const DWORD shader_code_12
[] =
1048 0xffff0102, /* ps_1_2 */
1049 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1050 0x00000040, 0xb00f0000, /* texcoord t0 */
1051 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1052 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1053 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1054 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1055 0x0000ffff /* end */
1057 static const DWORD shader_code_13
[] =
1059 0xffff0103, /* ps_1_3 */
1060 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1061 0x00000040, 0xb00f0000, /* texcoord t0 */
1062 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1063 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1064 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1065 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1066 0x0000ffff /* end */
1068 static const DWORD shader_code_14
[] =
1070 0xffff0104, /* ps_1_3 */
1071 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1072 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1073 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1074 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1075 0x0000ffff /* end */
1078 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1079 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1080 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1081 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1082 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1085 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1086 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1087 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1088 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1090 static const DWORD shader_code_11_coissue
[] =
1092 0xffff0101, /* ps_1_1 */
1093 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1094 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1095 0x00000040, 0xb00f0000, /* texcoord t0 */
1096 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1097 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1098 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1099 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1100 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1101 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1102 0x0000ffff /* end */
1104 static const DWORD shader_code_11_coissue_2
[] =
1106 0xffff0101, /* ps_1_1 */
1107 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1108 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1109 0x00000040, 0xb00f0000, /* texcoord t0 */
1110 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1111 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1112 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1113 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1114 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1115 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1116 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1117 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1118 0x0000ffff /* end */
1120 static const DWORD shader_code_12_coissue
[] =
1122 0xffff0102, /* ps_1_2 */
1123 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1124 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1125 0x00000040, 0xb00f0000, /* texcoord t0 */
1126 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1127 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1128 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1129 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1130 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1131 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1132 0x0000ffff /* end */
1134 static const DWORD shader_code_12_coissue_2
[] =
1136 0xffff0102, /* ps_1_2 */
1137 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1138 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1139 0x00000040, 0xb00f0000, /* texcoord t0 */
1140 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1141 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1142 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1143 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1144 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1145 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1146 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1147 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1148 0x0000ffff /* end */
1150 static const DWORD shader_code_13_coissue
[] =
1152 0xffff0103, /* ps_1_3 */
1153 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1154 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1155 0x00000040, 0xb00f0000, /* texcoord t0 */
1156 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1157 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1158 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1159 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1160 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1161 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1162 0x0000ffff /* end */
1164 static const DWORD shader_code_13_coissue_2
[] =
1166 0xffff0103, /* ps_1_3 */
1167 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1168 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1169 0x00000040, 0xb00f0000, /* texcoord t0 */
1170 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1171 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1172 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1173 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1174 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1175 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1176 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1177 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1178 0x0000ffff /* end */
1180 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1181 * texcrd result to cnd, it will compare against 0.5. */
1182 static const DWORD shader_code_14_coissue
[] =
1184 0xffff0104, /* ps_1_4 */
1185 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1186 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1187 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1188 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1189 0x0000ffff /* end */
1191 static const DWORD shader_code_14_coissue_2
[] =
1193 0xffff0104, /* ps_1_4 */
1194 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1195 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1196 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1197 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1198 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1199 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1200 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1201 0x0000ffff /* end */
1203 static const float quad1
[] =
1205 -1.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1206 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1207 0.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1208 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1210 static const float quad2
[] =
1212 0.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1213 0.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1214 1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1215 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1217 static const float quad3
[] =
1219 0.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1220 0.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1221 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1222 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1224 static const float quad4
[] =
1226 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
, 1.0f
,
1227 -1.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
, 0.0f
,
1228 0.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
, 1.0f
,
1229 0.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
, 0.0f
1231 static const float test_data_c1
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
1232 static const float test_data_c2
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
1233 static const float test_data_c1_coi
[4] = {0.0f
, 1.0f
, 0.0f
, 0.0f
};
1234 static const float test_data_c2_coi
[4] = {1.0f
, 0.0f
, 1.0f
, 1.0f
};
1236 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1237 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
1238 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1239 ok(!!d3d
, "Failed to create a D3D object.\n");
1240 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1242 skip("Failed to create a D3D device, skipping tests.\n");
1246 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1247 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1248 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 4))
1250 skip("No ps_1_4 support, skipping tests.\n");
1251 IDirect3DDevice8_Release(device
);
1255 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
1256 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1258 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11
, &shader_11
);
1259 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1260 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12
, &shader_12
);
1261 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1262 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13
, &shader_13
);
1263 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1264 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14
, &shader_14
);
1265 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1266 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11_coissue
, &shader_11_coissue
);
1267 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1268 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12_coissue
, &shader_12_coissue
);
1269 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1270 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13_coissue
, &shader_13_coissue
);
1271 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1272 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14_coissue
, &shader_14_coissue
);
1273 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1274 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_11_coissue_2
, &shader_11_coissue_2
);
1275 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1276 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_12_coissue_2
, &shader_12_coissue_2
);
1277 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1278 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_13_coissue_2
, &shader_13_coissue_2
);
1279 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1280 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code_14_coissue_2
, &shader_14_coissue_2
);
1281 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr
);
1283 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, test_data_c1
, 1);
1284 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1285 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 2, test_data_c2
, 1);
1286 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1287 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
1288 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1290 hr
= IDirect3DDevice8_BeginScene(device
);
1291 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1293 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11
);
1294 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1295 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1296 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1298 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12
);
1299 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1300 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1301 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1303 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13
);
1304 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1305 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1306 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1308 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14
);
1309 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1310 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1311 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1313 hr
= IDirect3DDevice8_EndScene(device
);
1314 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1316 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
1317 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1319 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1320 color
= getPixelColor(device
, 158, 118);
1321 ok(color
== 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color
);
1322 color
= getPixelColor(device
, 162, 118);
1323 ok(color
== 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color
);
1324 color
= getPixelColor(device
, 158, 122);
1325 ok(color
== 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color
);
1326 color
= getPixelColor(device
, 162, 122);
1327 ok(color
== 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color
);
1329 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1330 color
= getPixelColor(device
, 158, 358);
1331 ok(color
== 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color
);
1332 color
= getPixelColor(device
, 162, 358);
1333 ok(color_match(color
, 0x00000000, 1),
1334 "pixel 162, 358 has color %08x, expected 0x00000000\n", color
);
1335 color
= getPixelColor(device
, 158, 362);
1336 ok(color
== 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color
);
1337 color
= getPixelColor(device
, 162, 362);
1338 ok(color_match(color
, 0x00000000, 1),
1339 "pixel 162, 362 has color %08x, expected 0x00000000\n", color
);
1342 color
= getPixelColor(device
, 478, 358);
1343 ok(color
== 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color
);
1344 color
= getPixelColor(device
, 482, 358);
1345 ok(color_match(color
, 0x00000000, 1),
1346 "pixel 482, 358 has color %08x, expected 0x00000000\n", color
);
1347 color
= getPixelColor(device
, 478, 362);
1348 ok(color
== 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color
);
1349 color
= getPixelColor(device
, 482, 362);
1350 ok(color_match(color
, 0x00000000, 1),
1351 "pixel 482, 362 has color %08x, expected 0x00000000\n", color
);
1354 color
= getPixelColor(device
, 478, 118);
1355 ok(color
== 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color
);
1356 color
= getPixelColor(device
, 482, 118);
1357 ok(color_match(color
, 0x00000000, 1),
1358 "pixel 482, 118 has color %08x, expected 0x00000000\n", color
);
1359 color
= getPixelColor(device
, 478, 122);
1360 ok(color
== 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color
);
1361 color
= getPixelColor(device
, 482, 122);
1362 ok(color_match(color
, 0x00000000, 1),
1363 "pixel 482, 122 has color %08x, expected 0x00000000\n", color
);
1365 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1366 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1368 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ffff, 0.0f
, 0);
1369 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1370 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, test_data_c1_coi
, 1);
1371 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1372 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 2, test_data_c2_coi
, 1);
1373 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr
);
1375 hr
= IDirect3DDevice8_BeginScene(device
);
1376 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1378 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11_coissue
);
1379 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1380 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1381 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1383 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12_coissue
);
1384 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1385 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1386 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1388 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13_coissue
);
1389 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1390 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1391 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1393 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14_coissue
);
1394 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1395 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1396 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1398 hr
= IDirect3DDevice8_EndScene(device
);
1399 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1401 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
1402 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1404 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1405 * that we swapped the values in c1 and c2 to make the other tests return some color
1407 color
= getPixelColor(device
, 158, 118);
1408 ok(color
== 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color
);
1409 color
= getPixelColor(device
, 162, 118);
1410 ok(color
== 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color
);
1411 color
= getPixelColor(device
, 158, 122);
1412 ok(color
== 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color
);
1413 color
= getPixelColor(device
, 162, 122);
1414 ok(color
== 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color
);
1416 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1417 * (The Win7 nvidia driver always selects c2)
1419 color
= getPixelColor(device
, 158, 358);
1420 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1421 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color
);
1422 color
= getPixelColor(device
, 162, 358);
1423 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1424 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color
);
1425 color
= getPixelColor(device
, 158, 362);
1426 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1427 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color
);
1428 color
= getPixelColor(device
, 162, 362);
1429 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1430 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color
);
1433 color
= getPixelColor(device
, 478, 358);
1434 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1435 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color
);
1436 color
= getPixelColor(device
, 482, 358);
1437 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1438 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color
);
1439 color
= getPixelColor(device
, 478, 362);
1440 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1441 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color
);
1442 color
= getPixelColor(device
, 482, 362);
1443 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1444 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color
);
1447 color
= getPixelColor(device
, 478, 118);
1448 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1449 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color
);
1450 color
= getPixelColor(device
, 482, 118);
1451 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1452 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color
);
1453 color
= getPixelColor(device
, 478, 122);
1454 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1455 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color
);
1456 color
= getPixelColor(device
, 482, 122);
1457 ok(color_match(color
, 0x0000ff00, 1) || broken(color_match(color
, 0x00ff00ff, 1)),
1458 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color
);
1460 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1461 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1463 /* Retest with the coissue flag on the alpha instruction instead. This
1464 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1465 * the same as coissue on .rgb. */
1466 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ffff, 0.0f
, 0);
1467 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear returned %08x\n", hr
);
1469 hr
= IDirect3DDevice8_BeginScene(device
);
1470 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene returned %08x\n", hr
);
1472 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_11_coissue_2
);
1473 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1474 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, 6 * sizeof(float));
1475 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1477 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_12_coissue_2
);
1478 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1479 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 6 * sizeof(float));
1480 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1482 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_13_coissue_2
);
1483 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1484 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, 6 * sizeof(float));
1485 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1487 hr
= IDirect3DDevice8_SetPixelShader(device
, shader_14_coissue_2
);
1488 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr
);
1489 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, 6 * sizeof(float));
1490 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed (%08x)\n", hr
);
1492 hr
= IDirect3DDevice8_EndScene(device
);
1493 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene returned %08x\n", hr
);
1496 color
= getPixelColor(device
, 158, 118);
1497 ok(color
== 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color
);
1498 color
= getPixelColor(device
, 162, 118);
1499 ok(color
== 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color
);
1500 color
= getPixelColor(device
, 158, 122);
1501 ok(color
== 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color
);
1502 color
= getPixelColor(device
, 162, 122);
1503 ok(color
== 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color
);
1506 color
= getPixelColor(device
, 238, 358);
1507 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1508 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color
);
1509 color
= getPixelColor(device
, 242, 358);
1510 ok(color_match(color
, 0x00000000, 1),
1511 "pixel 242, 358 has color %08x, expected 0x00000000\n", color
);
1512 color
= getPixelColor(device
, 238, 362);
1513 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1514 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color
);
1515 color
= getPixelColor(device
, 242, 362);
1516 ok(color_match(color
, 0x00000000, 1),
1517 "pixel 242, 362 has color %08x, expected 0x00000000\n", color
);
1520 color
= getPixelColor(device
, 558, 358);
1521 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1522 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color
);
1523 color
= getPixelColor(device
, 562, 358);
1524 ok(color_match(color
, 0x00000000, 1),
1525 "pixel 562, 358 has color %08x, expected 0x00000000\n", color
);
1526 color
= getPixelColor(device
, 558, 362);
1527 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1528 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color
);
1529 color
= getPixelColor(device
, 562, 362);
1530 ok(color_match(color
, 0x00000000, 1),
1531 "pixel 562, 362 has color %08x, expected 0x00000000\n", color
);
1534 color
= getPixelColor(device
, 558, 118);
1535 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1536 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color
);
1537 color
= getPixelColor(device
, 562, 118);
1538 ok(color_match(color
, 0x00000000, 1),
1539 "pixel 562, 118 has color %08x, expected 0x00000000\n", color
);
1540 color
= getPixelColor(device
, 558, 122);
1541 ok(color_match(color
, 0x00ffffff, 1) || broken(color_match(color
, 0x00000000, 1)),
1542 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color
);
1543 color
= getPixelColor(device
, 562, 122);
1544 ok(color_match(color
, 0x00000000, 1),
1545 "pixel 562, 122 has color %08x, expected 0x00000000\n", color
);
1547 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1548 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed with %08x\n", hr
);
1550 IDirect3DDevice8_DeletePixelShader(device
, shader_14_coissue_2
);
1551 IDirect3DDevice8_DeletePixelShader(device
, shader_13_coissue_2
);
1552 IDirect3DDevice8_DeletePixelShader(device
, shader_12_coissue_2
);
1553 IDirect3DDevice8_DeletePixelShader(device
, shader_11_coissue_2
);
1554 IDirect3DDevice8_DeletePixelShader(device
, shader_14_coissue
);
1555 IDirect3DDevice8_DeletePixelShader(device
, shader_13_coissue
);
1556 IDirect3DDevice8_DeletePixelShader(device
, shader_12_coissue
);
1557 IDirect3DDevice8_DeletePixelShader(device
, shader_11_coissue
);
1558 IDirect3DDevice8_DeletePixelShader(device
, shader_14
);
1559 IDirect3DDevice8_DeletePixelShader(device
, shader_13
);
1560 IDirect3DDevice8_DeletePixelShader(device
, shader_12
);
1561 IDirect3DDevice8_DeletePixelShader(device
, shader_11
);
1562 refcount
= IDirect3DDevice8_Release(device
);
1563 ok(!refcount
, "Device has %u references left.\n", refcount
);
1565 IDirect3D8_Release(d3d
);
1566 DestroyWindow(window
);
1569 static void z_range_test(void)
1571 IDirect3DDevice8
*device
;
1582 struct vec3 position
;
1587 {{-1.0f
, 0.0f
, 1.1f
}, 0xffff0000},
1588 {{-1.0f
, 1.0f
, 1.1f
}, 0xffff0000},
1589 {{ 1.0f
, 0.0f
, -1.1f
}, 0xffff0000},
1590 {{ 1.0f
, 1.0f
, -1.1f
}, 0xffff0000},
1594 {{-1.0f
, 0.0f
, 1.1f
}, 0xff0000ff},
1595 {{-1.0f
, 1.0f
, 1.1f
}, 0xff0000ff},
1596 {{ 1.0f
, 0.0f
, -1.1f
}, 0xff0000ff},
1597 {{ 1.0f
, 1.0f
, -1.1f
}, 0xff0000ff},
1601 struct vec4 position
;
1606 {{640.0f
, 240.0f
, -1.1f
, 1.0f
}, 0xffffff00},
1607 {{640.0f
, 480.0f
, -1.1f
, 1.0f
}, 0xffffff00},
1608 {{ 0.0f
, 240.0f
, 1.1f
, 1.0f
}, 0xffffff00},
1609 {{ 0.0f
, 480.0f
, 1.1f
, 1.0f
}, 0xffffff00},
1613 {{640.0f
, 240.0f
, -1.1f
, 1.0f
}, 0xff00ff00},
1614 {{640.0f
, 480.0f
, -1.1f
, 1.0f
}, 0xff00ff00},
1615 {{ 0.0f
, 240.0f
, 1.1f
, 1.0f
}, 0xff00ff00},
1616 {{ 0.0f
, 480.0f
, 1.1f
, 1.0f
}, 0xff00ff00},
1618 static const DWORD shader_code
[] =
1620 0xfffe0101, /* vs_1_1 */
1621 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1622 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1623 0x0000ffff /* end */
1625 static const float color_const_1
[] = {1.0f
, 0.0f
, 0.0f
, 1.0f
};
1626 static const float color_const_2
[] = {0.0f
, 0.0f
, 1.0f
, 1.0f
};
1627 static const DWORD vertex_declaration
[] =
1630 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
1634 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1635 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
1636 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1637 ok(!!d3d
, "Failed to create a D3D object.\n");
1638 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1640 skip("Failed to create a D3D device, skipping tests.\n");
1644 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1645 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1647 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1648 * then call Present. Then clear the color buffer to make sure it has some defined content
1649 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1650 * by the depth value. */
1651 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.75f
, 0);
1652 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
1653 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1654 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
1655 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
1656 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
1658 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
1659 ok(SUCCEEDED(hr
), "Failed to disabled lighting, hr %#x.\n", hr
);
1660 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
1661 ok(SUCCEEDED(hr
), "Failed to enable clipping, hr %#x.\n", hr
);
1662 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
1663 ok(SUCCEEDED(hr
), "Failed to enable z test, hr %#x.\n", hr
);
1664 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
1665 ok(SUCCEEDED(hr
), "Failed to disable z writes, hr %#x.\n", hr
);
1666 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_GREATER
);
1667 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1668 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
1669 ok(SUCCEEDED(hr
), "Failed set FVF, hr %#x.\n", hr
);
1671 hr
= IDirect3DDevice8_BeginScene(device
);
1672 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1674 /* Test the untransformed vertex path */
1675 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
1676 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1677 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESS
);
1678 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1679 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
1680 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1682 /* Test the transformed vertex path */
1683 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
1684 ok(SUCCEEDED(hr
), "Failed set FVF, hr %#x.\n", hr
);
1686 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(quad4
[0]));
1687 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1688 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_GREATER
);
1689 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1690 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(quad3
[0]));
1691 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1693 hr
= IDirect3DDevice8_EndScene(device
);
1694 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1696 /* Do not test the exact corner pixels, but go pretty close to them */
1698 /* Clipped because z > 1.0 */
1699 color
= getPixelColor(device
, 28, 238);
1700 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1701 color
= getPixelColor(device
, 28, 241);
1702 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
1703 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1705 ok(color_match(color
, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
1707 /* Not clipped, > z buffer clear value(0.75).
1709 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
1710 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
1711 * equal to a stored depth buffer value of 0.5. */
1712 color
= getPixelColor(device
, 31, 238);
1713 ok(color_match(color
, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1714 color
= getPixelColor(device
, 31, 241);
1715 ok(color_match(color
, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
1716 color
= getPixelColor(device
, 100, 238);
1717 ok(color_match(color
, 0x00ff0000, 0) || broken(color_match(color
, 0x00ffffff, 0)),
1718 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1719 color
= getPixelColor(device
, 100, 241);
1720 ok(color_match(color
, 0x00ffff00, 0) || broken(color_match(color
, 0x00ffffff, 0)),
1721 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color
);
1723 /* Not clipped, < z buffer clear value */
1724 color
= getPixelColor(device
, 104, 238);
1725 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1726 color
= getPixelColor(device
, 104, 241);
1727 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color
);
1728 color
= getPixelColor(device
, 318, 238);
1729 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1730 color
= getPixelColor(device
, 318, 241);
1731 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color
);
1733 /* Clipped because z < 0.0 */
1734 color
= getPixelColor(device
, 321, 238);
1735 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1736 color
= getPixelColor(device
, 321, 241);
1737 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
1738 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1740 ok(color_match(color
, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1742 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1743 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
1745 /* Test the shader path */
1746 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
1748 skip("Vertex shaders not supported\n");
1749 IDirect3DDevice8_Release(device
);
1752 hr
= IDirect3DDevice8_CreateVertexShader(device
, vertex_declaration
, shader_code
, &shader
, 0);
1753 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
1755 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
1756 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
1758 hr
= IDirect3DDevice8_SetVertexShader(device
, shader
);
1759 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1761 hr
= IDirect3DDevice8_BeginScene(device
);
1762 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1764 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, color_const_1
, 1);
1765 ok(SUCCEEDED(hr
), "Failed to set vs constant 0, hr %#x.\n", hr
);
1766 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
1767 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1769 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESS
);
1770 ok(SUCCEEDED(hr
), "Failed to set z function, hr %#x.\n", hr
);
1771 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, color_const_2
, 1);
1772 ok(SUCCEEDED(hr
), "Failed to set vs constant 0, hr %#x.\n", hr
);
1773 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
1774 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1776 hr
= IDirect3DDevice8_EndScene(device
);
1777 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1779 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
1780 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
1782 hr
= IDirect3DDevice8_DeleteVertexShader(device
, shader
);
1783 ok(SUCCEEDED(hr
), "Failed to delete vertex shader, hr %#x.\n", hr
);
1786 color
= getPixelColor(device
, 28, 238);
1787 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1789 /* 1.0 < z < 0.75 */
1790 color
= getPixelColor(device
, 31, 238);
1791 ok(color_match(color
, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1792 color
= getPixelColor(device
, 100, 238);
1793 ok(color_match(color
, 0x00ff0000, 0) || broken(color_match(color
, 0x00ffffff, 0)),
1794 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
1796 /* 0.75 < z < 0.0 */
1797 color
= getPixelColor(device
, 104, 238);
1798 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1799 color
= getPixelColor(device
, 318, 238);
1800 ok(color_match(color
, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color
);
1803 color
= getPixelColor(device
, 321, 238);
1804 ok(color_match(color
, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
1806 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1807 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
1809 refcount
= IDirect3DDevice8_Release(device
);
1810 ok(!refcount
, "Device has %u references left.\n", refcount
);
1812 IDirect3D8_Release(d3d
);
1813 DestroyWindow(window
);
1816 static void test_scalar_instructions(void)
1818 IDirect3DDevice8
*device
;
1828 static const struct vec3 quad
[] =
1830 {-1.0f
, -1.0f
, 0.0f
},
1831 {-1.0f
, 1.0f
, 0.0f
},
1832 { 1.0f
, -1.0f
, 0.0f
},
1833 { 1.0f
, 1.0f
, 0.0f
},
1835 static const DWORD decl
[] =
1838 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* dcl_position v0 */
1839 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
1842 static const DWORD rcp_test
[] =
1844 0xfffe0101, /* vs_1_1 */
1845 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1846 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1847 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1848 0x00303030, /* enough to make Windows happy. */
1849 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1850 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
1851 0x0000ffff /* END */
1853 static const DWORD rsq_test
[] =
1855 0xfffe0101, /* vs_1_1 */
1856 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1857 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1858 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1859 0x00303030, /* enough to make Windows happy. */
1860 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1861 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
1862 0x0000ffff /* END */
1864 static const DWORD exp_test
[] =
1866 0xfffe0101, /* vs_1_1 */
1867 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1868 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1869 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1870 0x00303030, /* enough to make Windows happy. */
1871 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1872 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
1873 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
1874 0x0000ffff, /* END */
1876 static const DWORD expp_test
[] =
1878 0xfffe0101, /* vs_1_1 */
1879 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1880 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1881 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1882 0x00303030, /* enough to make Windows happy. */
1883 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1884 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
1885 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
1886 0x0000ffff, /* END */
1888 static const DWORD log_test
[] =
1890 0xfffe0101, /* vs_1_1 */
1891 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1892 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1893 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1894 0x00303030, /* enough to make Windows happy. */
1895 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1896 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
1897 0x0000ffff, /* END */
1899 static const DWORD logp_test
[] =
1901 0xfffe0101, /* vs_1_1 */
1902 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1903 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1904 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1905 0x00303030, /* enough to make Windows happy. */
1906 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1907 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
1908 0x0000ffff, /* END */
1913 const DWORD
*byte_code
;
1915 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
1916 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
1917 D3DCOLOR broken_color
;
1921 {"rcp_test", rcp_test
, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1922 {"rsq_test", rsq_test
, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1923 {"exp_test", exp_test
, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
1924 {"expp_test", expp_test
, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1925 {"log_test", log_test
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
1926 {"logp_test", logp_test
, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1929 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1930 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
1931 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1932 ok(!!d3d
, "Failed to create a D3D object.\n");
1933 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
1935 skip("Failed to create a D3D device, skipping tests.\n");
1939 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1940 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1941 if (caps
.VertexShaderVersion
< D3DVS_VERSION(1, 1))
1943 skip("No vs_1_1 support, skipping tests.\n");
1944 IDirect3DDevice8_Release(device
);
1948 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
1950 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff336699, 0.0f
, 0);
1951 ok(SUCCEEDED(hr
), "%s: Failed to clear, hr %#x.\n", test_data
[i
].name
, hr
);
1953 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, test_data
[i
].byte_code
, &shader
, 0);
1954 ok(SUCCEEDED(hr
), "%s: Failed to create vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1955 hr
= IDirect3DDevice8_SetVertexShader(device
, shader
);
1956 ok(SUCCEEDED(hr
), "%s: Failed to set vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1958 hr
= IDirect3DDevice8_BeginScene(device
);
1959 ok(SUCCEEDED(hr
), "%s: Failed to begin scene, hr %#x.\n", test_data
[i
].name
, hr
);
1960 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], 3 * sizeof(float));
1961 ok(SUCCEEDED(hr
), "%s: Failed to draw primitive, hr %#x.\n", test_data
[i
].name
, hr
);
1962 hr
= IDirect3DDevice8_EndScene(device
);
1963 ok(SUCCEEDED(hr
), "%s: Failed to end scene, hr %#x.\n", test_data
[i
].name
, hr
);
1965 color
= getPixelColor(device
, 320, 240);
1966 ok(color_match(color
, test_data
[i
].color
, 4) || broken(color_match(color
, test_data
[i
].broken_color
, 4)),
1967 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
1968 test_data
[i
].name
, color
, test_data
[i
].color
);
1970 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1971 ok(SUCCEEDED(hr
), "%s: Failed to present, hr %#x.\n", test_data
[i
].name
, hr
);
1973 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
1974 ok(SUCCEEDED(hr
), "%s: Failed to set vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1975 hr
= IDirect3DDevice8_DeleteVertexShader(device
, shader
);
1976 ok(SUCCEEDED(hr
), "%s: Failed to delete vertex shader, hr %#x.\n", test_data
[i
].name
, hr
);
1979 refcount
= IDirect3DDevice8_Release(device
);
1980 ok(!refcount
, "Device has %u references left.\n", refcount
);
1982 IDirect3D8_Release(d3d
);
1983 DestroyWindow(window
);
1986 static void offscreen_test(void)
1988 IDirect3DSurface8
*backbuffer
, *offscreen
, *depthstencil
;
1989 IDirect3DTexture8
*offscreenTexture
;
1990 IDirect3DDevice8
*device
;
1997 static const float quad
[][5] =
1999 {-0.5f
, -0.5f
, 0.1f
, 0.0f
, 0.0f
},
2000 {-0.5f
, 0.5f
, 0.1f
, 0.0f
, 1.0f
},
2001 { 0.5f
, -0.5f
, 0.1f
, 1.0f
, 0.0f
},
2002 { 0.5f
, 0.5f
, 0.1f
, 1.0f
, 1.0f
},
2005 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2006 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2007 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2008 ok(!!d3d
, "Failed to create a D3D object.\n");
2009 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2011 skip("Failed to create a D3D device, skipping tests.\n");
2015 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
2016 ok(hr
== D3D_OK
, "Clear failed, hr = %#08x\n", hr
);
2018 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2019 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2020 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
, "Creating the offscreen render target failed, hr = %#08x\n", hr
);
2021 if (!offscreenTexture
)
2023 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2024 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2025 D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2026 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
, "Creating the offscreen render target failed, hr = %#08x\n", hr
);
2027 if (!offscreenTexture
)
2029 skip("Cannot create an offscreen render target.\n");
2030 IDirect3DDevice8_Release(device
);
2035 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
2036 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr
);
2038 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2039 ok(hr
== D3D_OK
, "Can't get back buffer, hr = %#08x\n", hr
);
2041 hr
= IDirect3DTexture8_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
2042 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %#08x\n", hr
);
2044 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2045 ok(hr
== D3D_OK
, "SetVertexShader failed, hr = %#08x\n", hr
);
2047 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
2048 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2049 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2050 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2051 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_NONE
);
2052 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr
);
2053 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_NONE
);
2054 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr
);
2055 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2056 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %08x\n", hr
);
2058 hr
= IDirect3DDevice8_BeginScene(device
);
2059 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2061 hr
= IDirect3DDevice8_SetRenderTarget(device
, offscreen
, depthstencil
);
2062 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2063 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff00ff, 1.0f
, 0);
2064 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2066 /* Draw without textures - Should result in a white quad. */
2067 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2068 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2070 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
2071 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2072 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)offscreenTexture
);
2073 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2075 /* This time with the texture .*/
2076 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(quad
[0]));
2077 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2079 hr
= IDirect3DDevice8_EndScene(device
);
2080 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2082 /* Center quad - should be white */
2083 color
= getPixelColor(device
, 320, 240);
2084 ok(color
== 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color
);
2085 /* Some quad in the cleared part of the texture */
2086 color
= getPixelColor(device
, 170, 240);
2087 ok(color
== 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color
);
2088 /* Part of the originally cleared back buffer */
2089 color
= getPixelColor(device
, 10, 10);
2090 ok(color
== 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2091 color
= getPixelColor(device
, 10, 470);
2092 ok(color
== 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color
);
2094 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2096 IDirect3DSurface8_Release(backbuffer
);
2097 IDirect3DTexture8_Release(offscreenTexture
);
2098 IDirect3DSurface8_Release(offscreen
);
2099 IDirect3DSurface8_Release(depthstencil
);
2100 refcount
= IDirect3DDevice8_Release(device
);
2101 ok(!refcount
, "Device has %u references left.\n", refcount
);
2103 IDirect3D8_Release(d3d
);
2104 DestroyWindow(window
);
2107 static void alpha_test(void)
2109 IDirect3DSurface8
*backbuffer
, *offscreen
, *depthstencil
;
2110 IDirect3DTexture8
*offscreenTexture
;
2111 IDirect3DDevice8
*device
;
2120 struct vec3 position
;
2125 {{-1.0f
, -1.0f
, 0.1f
}, 0x4000ff00},
2126 {{-1.0f
, 0.0f
, 0.1f
}, 0x4000ff00},
2127 {{ 1.0f
, -1.0f
, 0.1f
}, 0x4000ff00},
2128 {{ 1.0f
, 0.0f
, 0.1f
}, 0x4000ff00},
2132 {{-1.0f
, 0.0f
, 0.1f
}, 0xc00000ff},
2133 {{-1.0f
, 1.0f
, 0.1f
}, 0xc00000ff},
2134 {{ 1.0f
, 0.0f
, 0.1f
}, 0xc00000ff},
2135 {{ 1.0f
, 1.0f
, 0.1f
}, 0xc00000ff},
2137 static const float composite_quad
[][5] =
2139 { 0.0f
, -1.0f
, 0.1f
, 0.0f
, 1.0f
},
2140 { 0.0f
, 1.0f
, 0.1f
, 0.0f
, 0.0f
},
2141 { 1.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
},
2142 { 1.0f
, 1.0f
, 0.1f
, 1.0f
, 0.0f
},
2145 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2146 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2147 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2148 ok(!!d3d
, "Failed to create a D3D object.\n");
2149 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2151 skip("Failed to create a D3D device, skipping tests.\n");
2155 /* Clear the render target with alpha = 0.5 */
2156 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x80ff0000, 1.0f
, 0);
2157 ok(hr
== D3D_OK
, "Clear failed, hr = %08x\n", hr
);
2159 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
2160 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &offscreenTexture
);
2161 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2163 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depthstencil
);
2164 ok(SUCCEEDED(hr
), "Failed to get depth/stencil buffer, hr %#x.\n", hr
);
2165 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2166 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
2168 hr
= IDirect3DTexture8_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
2169 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %#08x\n", hr
);
2171 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2172 ok(hr
== D3D_OK
, "SetVertexShader failed, hr = %#08x\n", hr
);
2174 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
2175 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2176 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2177 ok(hr
== D3D_OK
, "SetTextureStageState failed, hr = %#08x\n", hr
);
2178 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_NONE
);
2179 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr
);
2180 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_NONE
);
2181 ok(SUCCEEDED(hr
), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr
);
2182 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2183 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState returned %08x\n", hr
);
2185 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2186 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2187 hr
= IDirect3DDevice8_BeginScene(device
);
2188 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2190 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2191 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2192 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2193 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2194 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2195 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
2196 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2198 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_DESTALPHA
);
2199 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2200 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVDESTALPHA
);
2201 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2202 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2203 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2205 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2206 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2207 * "don't work" on render targets without alpha channel, they give
2208 * essentially ZERO and ONE blend factors. */
2209 hr
= IDirect3DDevice8_SetRenderTarget(device
, offscreen
, 0);
2210 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2211 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x80ff0000, 0.0, 0);
2212 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
2214 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2215 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2216 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2217 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2218 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(quad1
[0]));
2219 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2221 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_DESTALPHA
);
2222 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2223 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVDESTALPHA
);
2224 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2225 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(quad2
[0]));
2226 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2228 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depthstencil
);
2229 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
2231 /* Render the offscreen texture onto the frame buffer to be able to
2232 * compare it regularly. Disable alpha blending for the final
2234 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, FALSE
);
2235 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2236 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2237 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2239 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) offscreenTexture
);
2240 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2241 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, composite_quad
, sizeof(float) * 5);
2242 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2244 hr
= IDirect3DDevice8_EndScene(device
);
2245 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2247 color
= getPixelColor(device
, 160, 360);
2248 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2249 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color
);
2251 color
= getPixelColor(device
, 160, 120);
2252 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2253 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color
);
2255 color
= getPixelColor(device
, 480, 360);
2256 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2257 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color
);
2259 color
= getPixelColor(device
, 480, 120);
2260 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2261 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color
);
2263 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2265 IDirect3DSurface8_Release(backbuffer
);
2266 IDirect3DTexture8_Release(offscreenTexture
);
2267 IDirect3DSurface8_Release(offscreen
);
2268 IDirect3DSurface8_Release(depthstencil
);
2269 refcount
= IDirect3DDevice8_Release(device
);
2270 ok(!refcount
, "Device has %u references left.\n", refcount
);
2272 IDirect3D8_Release(d3d
);
2273 DestroyWindow(window
);
2276 static void p8_texture_test(void)
2278 IDirect3DTexture8
*texture
, *texture2
;
2279 IDirect3DDevice8
*device
;
2280 PALETTEENTRY table
[256];
2281 unsigned char *data
;
2291 static const float quad
[] =
2293 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 0.0f
,
2294 -1.0f
, 1.0f
, 0.1f
, 0.0f
, 1.0f
,
2295 1.0f
, 0.0f
, 0.1f
, 1.0f
, 0.0f
,
2296 1.0f
, 1.0f
, 0.1f
, 1.0f
, 1.0f
,
2298 static const float quad2
[] =
2300 -1.0f
, -1.0f
, 0.1f
, 0.0f
, 0.0f
,
2301 -1.0f
, 0.0f
, 0.1f
, 0.0f
, 1.0f
,
2302 1.0f
, -1.0f
, 0.1f
, 1.0f
, 0.0f
,
2303 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
,
2306 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2307 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2308 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2309 ok(!!d3d
, "Failed to create a D3D object.\n");
2310 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2312 skip("Failed to create a D3D device, skipping tests.\n");
2316 if (IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
,
2317 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, D3DFMT_P8
) != D3D_OK
)
2319 skip("D3DFMT_P8 textures not supported.\n");
2320 IDirect3DDevice8_Release(device
);
2324 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_P8
, D3DPOOL_MANAGED
, &texture2
);
2325 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2326 memset(&lr
, 0, sizeof(lr
));
2327 hr
= IDirect3DTexture8_LockRect(texture2
, 0, &lr
, NULL
, 0);
2328 ok(hr
== D3D_OK
, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr
);
2331 hr
= IDirect3DTexture8_UnlockRect(texture2
, 0);
2332 ok(hr
== D3D_OK
, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr
);
2334 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_P8
, D3DPOOL_MANAGED
, &texture
);
2335 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
2336 memset(&lr
, 0, sizeof(lr
));
2337 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lr
, NULL
, 0);
2338 ok(hr
== D3D_OK
, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr
);
2341 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
2342 ok(hr
== D3D_OK
, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr
);
2344 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000, 1.0f
, 0);
2345 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2347 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2348 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2349 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2350 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2352 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2353 alpha of every entry is set to 1.0, which MS says is required when there's no
2354 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2355 for (i
= 0; i
< 256; i
++) {
2356 table
[i
].peRed
= table
[i
].peGreen
= table
[i
].peBlue
= 0;
2357 table
[i
].peFlags
= 0xff;
2359 table
[1].peRed
= 0xff;
2360 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, table
);
2361 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2364 table
[1].peBlue
= 0xff;
2365 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 1, table
);
2366 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2368 hr
= IDirect3DDevice8_BeginScene(device
);
2369 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2371 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2372 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2373 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2374 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2375 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2376 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2377 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 0);
2378 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2379 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture2
);
2380 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2381 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2382 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2384 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
2385 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2386 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2387 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2389 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 1);
2390 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2391 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 5 * sizeof(float));
2392 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2394 hr
= IDirect3DDevice8_EndScene(device
);
2395 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2397 color
= getPixelColor(device
, 32, 32);
2398 ok(color_match(color
, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color
);
2399 color
= getPixelColor(device
, 32, 320);
2400 ok(color_match(color
, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color
);
2402 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2403 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
2405 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 0.0, 0);
2406 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2408 hr
= IDirect3DDevice8_BeginScene(device
);
2409 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2410 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture2
);
2411 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2412 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2413 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2414 hr
= IDirect3DDevice8_EndScene(device
);
2415 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2417 color
= getPixelColor(device
, 32, 32);
2418 ok(color_match(color
, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color
);
2420 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2421 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
2423 /* Test palettes with alpha */
2424 IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2425 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_ALPHAPALETTE
)) {
2426 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2428 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff000000, 0.0, 0);
2429 ok(hr
== D3D_OK
, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr
);
2431 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ALPHABLENDENABLE
, TRUE
);
2432 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr
);
2434 for (i
= 0; i
< 256; i
++) {
2435 table
[i
].peRed
= table
[i
].peGreen
= table
[i
].peBlue
= 0;
2436 table
[i
].peFlags
= 0xff;
2438 table
[1].peRed
= 0xff;
2439 table
[1].peFlags
= 0x80;
2440 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, table
);
2441 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2444 table
[1].peBlue
= 0xff;
2445 table
[1].peFlags
= 0x80;
2446 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 1, table
);
2447 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr
);
2449 hr
= IDirect3DDevice8_BeginScene(device
);
2450 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2452 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
);
2453 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2454 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2455 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
2456 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
2457 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
2459 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 0);
2460 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2461 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, 5 * sizeof(float));
2462 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2464 hr
= IDirect3DDevice8_SetCurrentTexturePalette(device
, 1);
2465 ok(SUCCEEDED(hr
), "Failed to set texture palette, hr %#x.\n", hr
);
2466 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, 5 * sizeof(float));
2467 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2469 hr
= IDirect3DDevice8_EndScene(device
);
2470 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2472 color
= getPixelColor(device
, 32, 32);
2473 ok(color_match(color
, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color
);
2474 color
= getPixelColor(device
, 32, 320);
2475 ok(color_match(color
, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color
);
2477 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2478 ok(hr
== D3D_OK
, "IDirect3DDevice8_Present failed, hr = %08x\n", hr
);
2481 IDirect3DTexture8_Release(texture
);
2482 IDirect3DTexture8_Release(texture2
);
2483 refcount
= IDirect3DDevice8_Release(device
);
2484 ok(!refcount
, "Device has %u references left.\n", refcount
);
2486 IDirect3D8_Release(d3d
);
2487 DestroyWindow(window
);
2490 static void texop_test(void)
2492 IDirect3DTexture8
*texture
;
2493 D3DLOCKED_RECT locked_rect
;
2494 IDirect3DDevice8
*device
;
2503 static const struct {
2508 {-1.0f
, -1.0f
, 0.1f
, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f
, -1.0f
},
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
}
2514 static const struct {
2520 {D3DTOP_SELECTARG1
, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2521 {D3DTOP_SELECTARG2
, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2
, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2522 {D3DTOP_MODULATE
, "MODULATE", D3DTEXOPCAPS_MODULATE
, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2523 {D3DTOP_MODULATE2X
, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X
, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2524 {D3DTOP_MODULATE4X
, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X
, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2525 {D3DTOP_ADD
, "ADD", D3DTEXOPCAPS_ADD
, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2527 {D3DTOP_ADDSIGNED
, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED
, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2528 {D3DTOP_ADDSIGNED2X
, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2530 {D3DTOP_SUBTRACT
, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT
, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2531 {D3DTOP_ADDSMOOTH
, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH
, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2532 {D3DTOP_BLENDDIFFUSEALPHA
, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA
, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2533 {D3DTOP_BLENDTEXTUREALPHA
, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA
, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2534 {D3DTOP_BLENDFACTORALPHA
, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA
, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2535 {D3DTOP_BLENDTEXTUREALPHAPM
, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2536 {D3DTOP_BLENDCURRENTALPHA
, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA
, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2537 {D3DTOP_MODULATEALPHA_ADDCOLOR
, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2538 {D3DTOP_MODULATECOLOR_ADDALPHA
, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2539 {D3DTOP_MODULATEINVALPHA_ADDCOLOR
, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2540 {D3DTOP_MODULATEINVCOLOR_ADDALPHA
, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2541 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2542 {D3DTOP_DOTPRODUCT3
, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3
, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2543 {D3DTOP_MULTIPLYADD
, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD
, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2544 {D3DTOP_LERP
, "LERP", D3DTEXOPCAPS_LERP
, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2547 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2548 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2549 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2550 ok(!!d3d
, "Failed to create a D3D object.\n");
2551 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2553 skip("Failed to create a D3D device, skipping tests.\n");
2557 memset(&caps
, 0, sizeof(caps
));
2558 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2559 ok(SUCCEEDED(hr
), "GetDeviceCaps failed with 0x%08x\n", hr
);
2561 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_TEX0
);
2562 ok(SUCCEEDED(hr
), "SetVertexShader failed with 0x%08x\n", hr
);
2564 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
2565 ok(SUCCEEDED(hr
), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr
);
2566 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, NULL
, 0);
2567 ok(SUCCEEDED(hr
), "LockRect failed with 0x%08x\n", hr
);
2568 *((DWORD
*)locked_rect
.pBits
) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
2569 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
2570 ok(SUCCEEDED(hr
), "LockRect failed with 0x%08x\n", hr
);
2571 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
2572 ok(SUCCEEDED(hr
), "SetTexture failed with 0x%08x\n", hr
);
2574 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG0
, D3DTA_DIFFUSE
);
2575 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2576 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
2577 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2578 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
2579 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2581 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
2582 ok(SUCCEEDED(hr
), "SetTextureStageState failed with 0x%08x\n", hr
);
2584 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2585 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
2586 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_TEXTUREFACTOR
, 0xdd333333);
2587 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
2588 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
| D3DCOLORWRITEENABLE_ALPHA
);
2589 ok(SUCCEEDED(hr
), "SetRenderState failed with 0x%08x\n", hr
);
2591 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00000000, 1.0f
, 0);
2592 ok(SUCCEEDED(hr
), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr
);
2594 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
2596 if (!(caps
.TextureOpCaps
& test_data
[i
].caps_flag
))
2598 skip("tex operation %s not supported\n", test_data
[i
].name
);
2602 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, test_data
[i
].op
);
2603 ok(SUCCEEDED(hr
), "SetTextureStageState (%s) failed with 0x%08x\n", test_data
[i
].name
, hr
);
2605 hr
= IDirect3DDevice8_BeginScene(device
);
2606 ok(SUCCEEDED(hr
), "BeginScene failed with 0x%08x\n", hr
);
2608 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
2609 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed with 0x%08x\n", hr
);
2611 hr
= IDirect3DDevice8_EndScene(device
);
2612 ok(SUCCEEDED(hr
), "EndScene failed with 0x%08x\n", hr
);
2614 color
= getPixelColor(device
, 320, 240);
2615 ok(color_match(color
, test_data
[i
].result
, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
2616 test_data
[i
].name
, color
, test_data
[i
].result
);
2618 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2619 ok(SUCCEEDED(hr
), "Present failed with 0x%08x\n", hr
);
2621 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00000000, 1.0f
, 0);
2622 ok(SUCCEEDED(hr
), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr
);
2625 IDirect3DTexture8_Release(texture
);
2626 refcount
= IDirect3DDevice8_Release(device
);
2627 ok(!refcount
, "Device has %u references left.\n", refcount
);
2629 IDirect3D8_Release(d3d
);
2630 DestroyWindow(window
);
2633 /* This test tests depth clamping / clipping behaviour:
2634 * - With software vertex processing, depth values are clamped to the
2635 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2636 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2637 * same as regular vertices here.
2638 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2639 * Normal vertices are always clipped. Pretransformed vertices are
2640 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2641 * - The viewport's MinZ/MaxZ is irrelevant for this.
2643 static void depth_clamp_test(void)
2645 IDirect3DDevice8
*device
;
2656 struct vec4 position
;
2661 {{ 0.0f
, 0.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2662 {{640.0f
, 0.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2663 {{ 0.0f
, 480.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2664 {{640.0f
, 480.0f
, 5.0f
, 1.0f
}, 0xff002b7f},
2668 {{ 0.0f
, 300.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2669 {{640.0f
, 300.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2670 {{ 0.0f
, 360.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2671 {{640.0f
, 360.0f
, 10.0f
, 1.0f
}, 0xfff9e814},
2675 {{112.0f
, 108.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2676 {{208.0f
, 108.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2677 {{112.0f
, 204.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2678 {{208.0f
, 204.0f
, 5.0f
, 1.0f
}, 0xffffffff},
2682 {{ 42.0f
, 41.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2683 {{112.0f
, 41.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2684 {{ 42.0f
, 108.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2685 {{112.0f
, 108.0f
, 10.0f
, 1.0f
}, 0xffffffff},
2689 struct vec3 position
;
2694 {{-0.5f
, 0.5f
, 10.0f
}, 0xff14f914},
2695 {{ 0.5f
, 0.5f
, 10.0f
}, 0xff14f914},
2696 {{-0.5f
, -0.5f
, 10.0f
}, 0xff14f914},
2697 {{ 0.5f
, -0.5f
, 10.0f
}, 0xff14f914},
2701 {{-1.0f
, 0.5f
, 10.0f
}, 0xfff91414},
2702 {{ 1.0f
, 0.5f
, 10.0f
}, 0xfff91414},
2703 {{-1.0f
, 0.25f
, 10.0f
}, 0xfff91414},
2704 {{ 1.0f
, 0.25f
, 10.0f
}, 0xfff91414},
2707 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2708 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2709 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2710 ok(!!d3d
, "Failed to create a D3D object.\n");
2711 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2713 skip("Failed to create a D3D device, skipping tests.\n");
2717 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2718 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
2727 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
2728 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
2730 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0, 0);
2731 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2733 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
2734 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2735 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2736 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2737 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
2738 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2739 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
2740 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2742 hr
= IDirect3DDevice8_BeginScene(device
);
2743 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
2745 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
2746 ok(SUCCEEDED(hr
), "SetVertexSahder failed, hr %#x.\n", hr
);
2748 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(*quad1
));
2749 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2750 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(*quad2
));
2751 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2753 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
2754 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2756 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(*quad3
));
2757 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2758 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad4
, sizeof(*quad4
));
2759 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2761 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, FALSE
);
2762 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2763 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2764 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
2766 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad5
, sizeof(*quad5
));
2767 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2769 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPING
, TRUE
);
2770 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2772 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad6
, sizeof(*quad6
));
2773 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2775 hr
= IDirect3DDevice8_EndScene(device
);
2776 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
2778 if (caps
.PrimitiveMiscCaps
& D3DPMISCCAPS_CLIPTLVERTS
)
2780 color
= getPixelColor(device
, 75, 75);
2781 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2782 color
= getPixelColor(device
, 150, 150);
2783 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2784 color
= getPixelColor(device
, 320, 240);
2785 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2786 color
= getPixelColor(device
, 320, 330);
2787 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2788 color
= getPixelColor(device
, 320, 330);
2789 ok(color_match(color
, 0x0000ff00, 1), "color 0x%08x.\n", color
);
2793 color
= getPixelColor(device
, 75, 75);
2794 ok(color_match(color
, 0x00ffffff, 1), "color 0x%08x.\n", color
);
2795 color
= getPixelColor(device
, 150, 150);
2796 ok(color_match(color
, 0x00ffffff, 1), "color 0x%08x.\n", color
);
2797 color
= getPixelColor(device
, 320, 240);
2798 ok(color_match(color
, 0x00002b7f, 1), "color 0x%08x.\n", color
);
2799 color
= getPixelColor(device
, 320, 330);
2800 ok(color_match(color
, 0x00f9e814, 1), "color 0x%08x.\n", color
);
2801 color
= getPixelColor(device
, 320, 330);
2802 ok(color_match(color
, 0x00f9e814, 1), "color 0x%08x.\n", color
);
2805 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2806 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
2808 refcount
= IDirect3DDevice8_Release(device
);
2809 ok(!refcount
, "Device has %u references left.\n", refcount
);
2811 IDirect3D8_Release(d3d
);
2812 DestroyWindow(window
);
2815 static void depth_buffer_test(void)
2817 IDirect3DSurface8
*backbuffer
, *rt1
, *rt2
, *rt3
;
2818 IDirect3DSurface8
*depth_stencil
;
2819 IDirect3DDevice8
*device
;
2830 struct vec3 position
;
2835 {{-1.0f
, 1.0f
, 0.33f
}, 0xff00ff00},
2836 {{ 1.0f
, 1.0f
, 0.33f
}, 0xff00ff00},
2837 {{-1.0f
, -1.0f
, 0.33f
}, 0xff00ff00},
2838 {{ 1.0f
, -1.0f
, 0.33f
}, 0xff00ff00},
2842 {{-1.0f
, 1.0f
, 0.50f
}, 0xffff00ff},
2843 {{ 1.0f
, 1.0f
, 0.50f
}, 0xffff00ff},
2844 {{-1.0f
, -1.0f
, 0.50f
}, 0xffff00ff},
2845 {{ 1.0f
, -1.0f
, 0.50f
}, 0xffff00ff},
2849 {{-1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2850 {{ 1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2851 {{-1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
2852 {{ 1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
2854 static const DWORD expected_colors
[4][4] =
2856 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
2857 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
2858 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
2859 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
2862 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2863 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2864 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2865 ok(!!d3d
, "Failed to create a D3D object.\n");
2866 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
2868 skip("Failed to create a D3D device, skipping tests.\n");
2879 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
2880 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
2882 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
2883 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2884 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
2885 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2886 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
2887 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2888 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
2889 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2890 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2891 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
2893 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
2894 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
2895 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
2896 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
2897 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 320, 240, D3DFMT_A8R8G8B8
,
2898 D3DMULTISAMPLE_NONE
, FALSE
, &rt1
);
2899 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
2900 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 480, 360, D3DFMT_A8R8G8B8
,
2901 D3DMULTISAMPLE_NONE
, FALSE
, &rt2
);
2902 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
2903 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
2904 D3DMULTISAMPLE_NONE
, FALSE
, &rt3
);
2905 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
2907 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt3
, depth_stencil
);
2908 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2909 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 0.0f
, 0);
2910 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2912 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
2913 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2914 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
2915 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2917 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt1
, depth_stencil
);
2918 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2919 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.0f
, 0);
2920 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
2922 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt2
, depth_stencil
);
2923 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2924 hr
= IDirect3DDevice8_BeginScene(device
);
2925 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
2926 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad2
, sizeof(*quad2
));
2927 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2928 hr
= IDirect3DDevice8_EndScene(device
);
2929 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
2931 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
2932 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
2934 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
2935 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
2937 hr
= IDirect3DDevice8_BeginScene(device
);
2938 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
2939 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad1
, sizeof(*quad1
));
2940 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2941 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad3
, sizeof(*quad3
));
2942 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
2943 hr
= IDirect3DDevice8_EndScene(device
);
2944 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
2946 for (i
= 0; i
< 4; ++i
)
2948 for (j
= 0; j
< 4; ++j
)
2950 unsigned int x
= 80 * ((2 * j
) + 1);
2951 unsigned int y
= 60 * ((2 * i
) + 1);
2952 color
= getPixelColor(device
, x
, y
);
2953 ok(color_match(color
, expected_colors
[i
][j
], 0),
2954 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
2958 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2959 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
2961 IDirect3DSurface8_Release(depth_stencil
);
2962 IDirect3DSurface8_Release(backbuffer
);
2963 IDirect3DSurface8_Release(rt3
);
2964 IDirect3DSurface8_Release(rt2
);
2965 IDirect3DSurface8_Release(rt1
);
2966 refcount
= IDirect3DDevice8_Release(device
);
2967 ok(!refcount
, "Device has %u references left.\n", refcount
);
2969 IDirect3D8_Release(d3d
);
2970 DestroyWindow(window
);
2973 /* Test that partial depth copies work the way they're supposed to. The clear
2974 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2975 * the following draw should only copy back the part that was modified. */
2976 static void depth_buffer2_test(void)
2978 IDirect3DSurface8
*backbuffer
, *rt1
, *rt2
;
2979 IDirect3DSurface8
*depth_stencil
;
2980 IDirect3DDevice8
*device
;
2991 struct vec3 position
;
2996 {{-1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2997 {{ 1.0f
, 1.0f
, 0.66f
}, 0xffff0000},
2998 {{-1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
2999 {{ 1.0f
, -1.0f
, 0.66f
}, 0xffff0000},
3002 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3003 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3004 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3005 ok(!!d3d
, "Failed to create a D3D object.\n");
3006 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3008 skip("Failed to create a D3D device, skipping tests.\n");
3019 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
3020 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
3022 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3023 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3024 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3025 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3026 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3027 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3028 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
3029 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3030 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
3031 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3033 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3034 D3DMULTISAMPLE_NONE
, FALSE
, &rt1
);
3035 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3036 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 480, 360, D3DFMT_A8R8G8B8
,
3037 D3DMULTISAMPLE_NONE
, FALSE
, &rt2
);
3038 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3039 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
3040 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
3041 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
3042 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3044 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt1
, depth_stencil
);
3045 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3046 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
3047 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3049 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3050 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3051 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 0.5f
, 0);
3052 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3054 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt2
, depth_stencil
);
3055 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3056 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 0.0f
, 0);
3057 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3059 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
3060 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3062 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
3063 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3065 hr
= IDirect3DDevice8_BeginScene(device
);
3066 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3067 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3068 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3069 hr
= IDirect3DDevice8_EndScene(device
);
3070 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3072 for (i
= 0; i
< 4; ++i
)
3074 for (j
= 0; j
< 4; ++j
)
3076 unsigned int x
= 80 * ((2 * j
) + 1);
3077 unsigned int y
= 60 * ((2 * i
) + 1);
3078 color
= getPixelColor(device
, x
, y
);
3079 ok(color_match(color
, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3080 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x
, y
, color
);
3084 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3085 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3087 IDirect3DSurface8_Release(depth_stencil
);
3088 IDirect3DSurface8_Release(backbuffer
);
3089 IDirect3DSurface8_Release(rt2
);
3090 IDirect3DSurface8_Release(rt1
);
3091 refcount
= IDirect3DDevice8_Release(device
);
3092 ok(!refcount
, "Device has %u references left.\n", refcount
);
3094 IDirect3D8_Release(d3d
);
3095 DestroyWindow(window
);
3098 static void intz_test(void)
3100 IDirect3DSurface8
*original_rt
, *rt
;
3101 IDirect3DTexture8
*texture
;
3102 IDirect3DDevice8
*device
;
3103 IDirect3DSurface8
*ds
;
3112 static const DWORD ps_code
[] =
3114 0xffff0101, /* ps_1_1 */
3115 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3116 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3117 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3118 0x00000042, 0xb00f0000, /* tex t0 */
3119 0x00000042, 0xb00f0001, /* tex t1 */
3120 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3121 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3122 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3123 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3124 0x0000ffff, /* end */
3130 float s1
, t1
, p1
, q1
;
3134 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3135 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3136 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3137 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3141 { -1.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3142 { 1.0f
, 0.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3143 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3144 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3148 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3149 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3150 { -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3151 { 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3160 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3161 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3162 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3163 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3164 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3165 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3166 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3167 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3170 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3171 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3172 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3173 ok(!!d3d
, "Failed to create a D3D object.\n");
3174 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3176 skip("Failed to create a D3D device, skipping tests.\n");
3180 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3181 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3182 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
3184 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3185 IDirect3DDevice8_Release(device
);
3188 if (caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
)
3190 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3191 IDirect3DDevice8_Release(device
);
3195 if (FAILED(hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3196 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, MAKEFOURCC('I','N','T','Z'))))
3198 skip("No INTZ support, skipping INTZ test.\n");
3199 IDirect3DDevice8_Release(device
);
3203 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3204 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3206 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3207 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3208 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3209 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3210 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
3211 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3212 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3213 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3215 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3216 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3217 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3218 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3219 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3220 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3221 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3222 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3223 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3224 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3225 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3227 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3228 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3229 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3230 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3231 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3232 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3233 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3234 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3236 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3237 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3238 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3239 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3240 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3241 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3242 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3243 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3244 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3245 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3246 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3247 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3248 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3250 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3251 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3253 /* Render offscreen, using the INTZ texture as depth buffer */
3254 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3255 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3256 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3257 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3259 /* Setup the depth/stencil surface. */
3260 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3261 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3263 hr
= IDirect3DDevice8_BeginScene(device
);
3264 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3265 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3266 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3267 hr
= IDirect3DDevice8_EndScene(device
);
3268 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3270 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3271 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3272 IDirect3DSurface8_Release(ds
);
3273 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3274 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3275 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3276 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3277 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3278 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3280 /* Read the depth values back. */
3281 hr
= IDirect3DDevice8_BeginScene(device
);
3282 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3283 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3284 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3285 hr
= IDirect3DDevice8_EndScene(device
);
3286 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3288 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3290 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3291 ok(color_match(color
, expected_colors
[i
].color
, 1),
3292 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3293 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3296 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3297 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3299 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3300 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3301 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3302 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3303 IDirect3DTexture8_Release(texture
);
3305 /* Render onscreen while using the INTZ texture as depth buffer */
3306 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3307 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3308 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3309 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3310 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3311 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3312 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3313 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3314 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3316 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3317 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3319 hr
= IDirect3DDevice8_BeginScene(device
);
3320 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3321 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3322 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3323 hr
= IDirect3DDevice8_EndScene(device
);
3324 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3326 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3327 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3328 IDirect3DSurface8_Release(ds
);
3329 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3330 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3331 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3332 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3333 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3334 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3336 /* Read the depth values back. */
3337 hr
= IDirect3DDevice8_BeginScene(device
);
3338 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3339 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3340 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3341 hr
= IDirect3DDevice8_EndScene(device
);
3342 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3344 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3346 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3347 ok(color_match(color
, expected_colors
[i
].color
, 1),
3348 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3349 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3352 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3353 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3355 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3356 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3357 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3358 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3359 IDirect3DTexture8_Release(texture
);
3361 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3362 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3363 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3364 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3365 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3366 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3367 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3368 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3369 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3370 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3372 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3373 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3375 hr
= IDirect3DDevice8_BeginScene(device
);
3376 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3377 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, half_quad_1
, sizeof(*half_quad_1
));
3378 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3379 hr
= IDirect3DDevice8_EndScene(device
);
3380 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3382 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3383 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3385 hr
= IDirect3DDevice8_BeginScene(device
);
3386 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3387 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, half_quad_2
, sizeof(*half_quad_2
));
3388 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3389 hr
= IDirect3DDevice8_EndScene(device
);
3390 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3392 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3393 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3394 IDirect3DSurface8_Release(ds
);
3395 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3396 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3397 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3398 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3399 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3400 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3402 /* Read the depth values back. */
3403 hr
= IDirect3DDevice8_BeginScene(device
);
3404 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3405 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3406 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3407 hr
= IDirect3DDevice8_EndScene(device
);
3408 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3410 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3412 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3413 ok(color_match(color
, expected_colors
[i
].color
, 1),
3414 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3415 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3418 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3419 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3421 IDirect3DTexture8_Release(texture
);
3422 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
3423 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
3424 IDirect3DSurface8_Release(original_rt
);
3425 IDirect3DSurface8_Release(rt
);
3426 refcount
= IDirect3DDevice8_Release(device
);
3427 ok(!refcount
, "Device has %u references left.\n", refcount
);
3429 IDirect3D8_Release(d3d
);
3430 DestroyWindow(window
);
3433 static void shadow_test(void)
3435 IDirect3DSurface8
*original_rt
, *rt
;
3436 IDirect3DDevice8
*device
;
3445 static const DWORD ps_code
[] =
3447 0xffff0101, /* ps_1_1 */
3448 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3449 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3450 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3451 0x00000042, 0xb00f0000, /* tex t0 */
3452 0x00000042, 0xb00f0001, /* tex t1 */
3453 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3454 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3455 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3456 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3457 0x0000ffff, /* end */
3466 {D3DFMT_D16_LOCKABLE
, "D3DFMT_D16_LOCKABLE"},
3467 {D3DFMT_D32
, "D3DFMT_D32"},
3468 {D3DFMT_D15S1
, "D3DFMT_D15S1"},
3469 {D3DFMT_D24S8
, "D3DFMT_D24S8"},
3470 {D3DFMT_D24X8
, "D3DFMT_D24X8"},
3471 {D3DFMT_D24X4S4
, "D3DFMT_D24X4S4"},
3472 {D3DFMT_D16
, "D3DFMT_D16"},
3478 float s1
, t1
, p1
, q1
;
3482 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
},
3483 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.0f
},
3484 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
},
3485 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
},
3494 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3495 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3496 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3497 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3498 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3499 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3500 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3501 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3504 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3505 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3506 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3507 ok(!!d3d
, "Failed to create a D3D object.\n");
3508 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3510 skip("Failed to create a D3D device, skipping tests.\n");
3514 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3515 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3516 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
3518 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3519 IDirect3DDevice8_Release(device
);
3523 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3524 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3526 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 1024, 1024, D3DFMT_A8R8G8B8
,
3527 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
3528 ok(SUCCEEDED(hr
), "CreateRenderTarget failed, hr %#x.\n", hr
);
3529 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3530 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3532 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3533 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3534 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3535 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3536 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3537 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3538 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3539 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3540 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3541 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3542 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3544 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3545 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3546 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3547 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3548 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3549 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3550 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3551 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3553 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3554 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3555 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3556 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3557 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3558 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3559 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3560 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3561 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3562 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3563 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3564 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3565 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3567 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); ++i
)
3569 D3DFORMAT format
= formats
[i
].format
;
3570 IDirect3DTexture8
*texture
;
3571 IDirect3DSurface8
*ds
;
3574 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3575 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, format
)))
3578 hr
= IDirect3DDevice8_CreateTexture(device
, 1024, 1024, 1,
3579 D3DUSAGE_DEPTHSTENCIL
, format
, D3DPOOL_DEFAULT
, &texture
);
3580 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3582 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &ds
);
3583 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3585 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3586 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3588 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3589 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3591 /* Setup the depth/stencil surface. */
3592 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3593 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3595 hr
= IDirect3DDevice8_BeginScene(device
);
3596 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3597 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3598 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3599 hr
= IDirect3DDevice8_EndScene(device
);
3600 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3602 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3603 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
3604 IDirect3DSurface8_Release(ds
);
3606 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3607 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3608 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3609 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3611 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3612 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3614 /* Do the actual shadow mapping. */
3615 hr
= IDirect3DDevice8_BeginScene(device
);
3616 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3617 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3618 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3619 hr
= IDirect3DDevice8_EndScene(device
);
3620 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3622 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3623 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3624 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3625 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3626 IDirect3DTexture8_Release(texture
);
3628 for (j
= 0; j
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++j
)
3630 D3DCOLOR color
= getPixelColor(device
, expected_colors
[j
].x
, expected_colors
[j
].y
);
3631 ok(color_match(color
, expected_colors
[j
].color
, 0),
3632 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
3633 expected_colors
[j
].color
, expected_colors
[j
].x
, expected_colors
[j
].y
,
3634 formats
[i
].name
, color
);
3637 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3638 ok(SUCCEEDED(hr
), "Present failed, hr %#x.\n", hr
);
3641 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
3642 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
3643 IDirect3DSurface8_Release(original_rt
);
3644 IDirect3DSurface8_Release(rt
);
3645 refcount
= IDirect3DDevice8_Release(device
);
3646 ok(!refcount
, "Device has %u references left.\n", refcount
);
3648 IDirect3D8_Release(d3d
);
3649 DestroyWindow(window
);
3652 static void multisample_copy_rects_test(void)
3654 IDirect3DSurface8
*ds
, *ds_plain
, *rt
, *readback
;
3655 RECT src_rect
= {64, 64, 128, 128};
3656 POINT dst_point
= {96, 96};
3657 D3DLOCKED_RECT locked_rect
;
3658 IDirect3DDevice8
*device
;
3665 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3666 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3667 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3668 ok(!!d3d
, "Failed to create a D3D object.\n");
3669 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3671 skip("Failed to create a D3D device, skipping tests.\n");
3675 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
3676 D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
3678 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
3679 IDirect3DDevice8_Release(device
);
3683 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 256, 256, D3DFMT_A8R8G8B8
,
3684 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
3685 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
3686 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 256, 256, D3DFMT_D24S8
,
3687 D3DMULTISAMPLE_2_SAMPLES
, &ds
);
3688 ok(SUCCEEDED(hr
), "Failed to create depth stencil surface, hr %#x.\n", hr
);
3689 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 256, 256, D3DFMT_D24S8
,
3690 D3DMULTISAMPLE_NONE
, &ds_plain
);
3691 ok(SUCCEEDED(hr
), "Failed to create depth stencil surface, hr %#x.\n", hr
);
3692 hr
= IDirect3DDevice8_CreateImageSurface(device
, 256, 256, D3DFMT_A8R8G8B8
, &readback
);
3693 ok(SUCCEEDED(hr
), "Failed to create readback surface, hr %#x.\n", hr
);
3695 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3696 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3698 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
3699 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3701 hr
= IDirect3DDevice8_CopyRects(device
, rt
, NULL
, 0, readback
, NULL
);
3702 ok(SUCCEEDED(hr
), "Failed to read render target back, hr %#x.\n", hr
);
3704 hr
= IDirect3DDevice8_CopyRects(device
, ds
, NULL
, 0, ds_plain
, NULL
);
3705 ok(hr
== D3DERR_INVALIDCALL
, "Depth buffer copy, hr %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3707 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
3708 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3710 hr
= IDirect3DDevice8_CopyRects(device
, rt
, &src_rect
, 1, readback
, &dst_point
);
3711 ok(SUCCEEDED(hr
), "Failed to read render target back, hr %#x.\n", hr
);
3713 hr
= IDirect3DSurface8_LockRect(readback
, &locked_rect
, NULL
, D3DLOCK_READONLY
);
3714 ok(SUCCEEDED(hr
), "Failed to lock readback surface, hr %#x.\n", hr
);
3716 color
= *(DWORD
*)((BYTE
*)locked_rect
.pBits
+ 31 * locked_rect
.Pitch
+ 31 * 4);
3717 ok(color
== 0xff00ff00, "Got unexpected color 0x%08x.\n", color
);
3719 color
= *(DWORD
*)((BYTE
*)locked_rect
.pBits
+ 127 * locked_rect
.Pitch
+ 127 * 4);
3720 ok(color
== 0xffff0000, "Got unexpected color 0x%08x.\n", color
);
3722 hr
= IDirect3DSurface8_UnlockRect(readback
);
3723 ok(SUCCEEDED(hr
), "Failed to unlock readback surface, hr %#x.\n", hr
);
3725 IDirect3DSurface8_Release(readback
);
3726 IDirect3DSurface8_Release(ds_plain
);
3727 IDirect3DSurface8_Release(ds
);
3728 IDirect3DSurface8_Release(rt
);
3729 refcount
= IDirect3DDevice8_Release(device
);
3730 ok(!refcount
, "Device has %u references left.\n", refcount
);
3732 IDirect3D8_Release(d3d
);
3733 DestroyWindow(window
);
3736 static void resz_test(void)
3738 IDirect3DSurface8
*rt
, *original_rt
, *ds
, *original_ds
, *intz_ds
;
3739 IDirect3DTexture8
*texture
;
3740 IDirect3DDevice8
*device
;
3749 static const DWORD ps_code
[] =
3751 0xffff0101, /* ps_1_1 */
3752 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3753 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3754 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3755 0x00000042, 0xb00f0000, /* tex t0 */
3756 0x00000042, 0xb00f0001, /* tex t1 */
3757 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3758 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3759 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3760 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3761 0x0000ffff, /* end */
3767 float s1
, t1
, p1
, q1
;
3771 { -1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
, 0.5f
},
3772 { 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 0.5f
},
3773 { -1.0f
, -1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
},
3774 { 1.0f
, -1.0f
, 1.0f
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 0.0f
, 0.5f
},
3783 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3784 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3785 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3786 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3787 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3788 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3789 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3790 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3793 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3794 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
3795 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
3796 ok(!!d3d
, "Failed to create a D3D object.\n");
3797 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
3799 skip("Failed to create a D3D device, skipping tests.\n");
3803 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
3804 D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
3806 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
3807 IDirect3DDevice8_Release(device
);
3810 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
,
3811 D3DDEVTYPE_HAL
, D3DFMT_D24S8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
)))
3813 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
3814 IDirect3DDevice8_Release(device
);
3817 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3818 D3DFMT_X8R8G8B8
, D3DUSAGE_DEPTHSTENCIL
, D3DRTYPE_TEXTURE
, MAKEFOURCC('I','N','T','Z'))))
3820 skip("No INTZ support, skipping RESZ test.\n");
3821 IDirect3DDevice8_Release(device
);
3824 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
3825 D3DFMT_X8R8G8B8
, D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, MAKEFOURCC('R','E','S','Z'))))
3827 skip("No RESZ support, skipping RESZ test.\n");
3828 IDirect3DDevice8_Release(device
);
3832 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
3833 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
3834 if (caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
)
3836 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3837 IDirect3DDevice8_Release(device
);
3841 hr
= IDirect3DDevice8_GetRenderTarget(device
, &original_rt
);
3842 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3843 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &original_ds
);
3844 ok(SUCCEEDED(hr
), "Failed to get depth/stencil, hr %#x.\n", hr
);
3846 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 640, 480, D3DFMT_A8R8G8B8
,
3847 D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
3848 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
3849 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
,
3850 D3DMULTISAMPLE_2_SAMPLES
, &ds
);
3852 hr
= IDirect3DDevice8_CreateTexture(device
, 640, 480, 1,
3853 D3DUSAGE_DEPTHSTENCIL
, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT
, &texture
);
3854 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
3855 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &intz_ds
);
3856 ok(SUCCEEDED(hr
), "GetSurfaceLevel failed, hr %#x.\n", hr
);
3858 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, intz_ds
);
3859 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3860 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ffff, 1.0f
, 0);
3861 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3863 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3864 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3865 IDirect3DSurface8_Release(intz_ds
);
3866 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
3867 ok(SUCCEEDED(hr
), "CreatePixelShader failed, hr %#x.\n", hr
);
3869 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX2
3870 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3871 ok(SUCCEEDED(hr
), "SetVertexShader failed, hr %#x.\n", hr
);
3872 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_TRUE
);
3873 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3874 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZFUNC
, D3DCMP_ALWAYS
);
3875 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3876 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3877 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3878 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
3879 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3881 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3882 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3883 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3884 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3885 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3886 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3887 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT3
);
3888 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3890 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSU
, D3DTADDRESS_WRAP
);
3891 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3892 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_ADDRESSV
, D3DTADDRESS_WRAP
);
3893 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3894 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
3895 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3896 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MINFILTER
, D3DTEXF_POINT
);
3897 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3898 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_MIPFILTER
, D3DTEXF_POINT
);
3899 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3900 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
,
3901 D3DTTFF_COUNT4
| D3DTTFF_PROJECTED
);
3902 ok(SUCCEEDED(hr
), "SetTextureStageState failed, hr %#x.\n", hr
);
3904 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
3905 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
3906 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3908 hr
= IDirect3DDevice8_BeginScene(device
);
3909 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3910 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3911 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3913 /* The destination depth texture has to be bound to sampler 0 */
3914 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
3915 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3917 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
3918 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
3919 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3920 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
3921 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3922 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0);
3923 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3924 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3925 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3926 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
3927 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3928 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
3929 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3930 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0xf);
3931 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
3933 /* The actual multisampled depth buffer resolve happens here */
3934 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
3935 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
3936 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_POINTSIZE
, &value
);
3937 ok(SUCCEEDED(hr
) && value
== 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr
, value
);
3939 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, NULL
);
3940 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3941 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
3942 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3943 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
3944 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3946 /* Read the depth values back. */
3947 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3948 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3949 hr
= IDirect3DDevice8_EndScene(device
);
3950 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3952 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
3954 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
3955 ok(color_match(color
, expected_colors
[i
].color
, 1),
3956 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3957 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
3960 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3961 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
3963 /* Test edge cases - try with no texture at all */
3964 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
3965 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3966 hr
= IDirect3DDevice8_SetTexture(device
, 1, NULL
);
3967 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
3968 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3969 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3971 hr
= IDirect3DDevice8_BeginScene(device
);
3972 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3973 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3974 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3975 hr
= IDirect3DDevice8_EndScene(device
);
3976 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3978 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
3979 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
3981 /* With a non-multisampled depth buffer */
3982 IDirect3DSurface8_Release(ds
);
3983 IDirect3DSurface8_Release(rt
);
3984 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
,
3985 D3DMULTISAMPLE_NONE
, &ds
);
3987 hr
= IDirect3DDevice8_SetRenderTarget(device
, original_rt
, ds
);
3988 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3989 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
3990 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
3992 hr
= IDirect3DDevice8_BeginScene(device
);
3993 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
3994 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
3995 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
3996 hr
= IDirect3DDevice8_EndScene(device
);
3997 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
3999 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4000 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4002 hr
= IDirect3DDevice8_BeginScene(device
);
4003 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4004 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
4005 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4006 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, FALSE
);
4007 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4008 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0);
4009 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4010 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4011 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4012 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
4013 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4014 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZWRITEENABLE
, TRUE
);
4015 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4016 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_COLORWRITEENABLE
, 0xf);
4017 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
4018 hr
= IDirect3DDevice8_EndScene(device
);
4019 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4021 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_POINTSIZE
, 0x7fa05000);
4022 ok(SUCCEEDED(hr
), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr
);
4024 hr
= IDirect3DDevice8_SetTexture(device
, 1, (IDirect3DBaseTexture8
*)texture
);
4025 ok(SUCCEEDED(hr
), "SetTexture failed, hr %#x.\n", hr
);
4026 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4027 ok(SUCCEEDED(hr
), "SetPixelShader failed, hr %#x.\n", hr
);
4029 /* Read the depth values back. */
4030 hr
= IDirect3DDevice8_BeginScene(device
);
4031 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#x.\n", hr
);
4032 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4033 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#x.\n", hr
);
4034 hr
= IDirect3DDevice8_EndScene(device
);
4035 ok(SUCCEEDED(hr
), "EndScene failed, hr %#x.\n", hr
);
4037 for (i
= 0; i
< sizeof(expected_colors
) / sizeof(*expected_colors
); ++i
)
4039 D3DCOLOR color
= getPixelColor(device
, expected_colors
[i
].x
, expected_colors
[i
].y
);
4040 ok(color_match(color
, expected_colors
[i
].color
, 1),
4041 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4042 expected_colors
[i
].color
, expected_colors
[i
].x
, expected_colors
[i
].y
, color
);
4045 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4046 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
4048 IDirect3DSurface8_Release(ds
);
4049 IDirect3DTexture8_Release(texture
);
4050 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4051 ok(SUCCEEDED(hr
), "DeletePixelShader failed, hr %#x.\n", hr
);
4052 IDirect3DSurface8_Release(original_ds
);
4053 IDirect3DSurface8_Release(original_rt
);
4055 refcount
= IDirect3DDevice8_Release(device
);
4056 ok(!refcount
, "Device has %u references left.\n", refcount
);
4058 IDirect3D8_Release(d3d
);
4059 DestroyWindow(window
);
4062 static void zenable_test(void)
4064 IDirect3DDevice8
*device
;
4076 struct vec4 position
;
4081 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
4082 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
4083 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
4084 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
4087 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4088 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4089 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4090 ok(!!d3d
, "Failed to create a D3D object.\n");
4091 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4093 skip("Failed to create a D3D device, skipping tests.\n");
4097 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, D3DZB_FALSE
);
4098 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
4099 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
);
4100 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4102 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
4103 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4104 hr
= IDirect3DDevice8_BeginScene(device
);
4105 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4106 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, tquad
, sizeof(*tquad
));
4107 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4108 hr
= IDirect3DDevice8_EndScene(device
);
4109 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4111 for (i
= 0; i
< 4; ++i
)
4113 for (j
= 0; j
< 4; ++j
)
4115 x
= 80 * ((2 * j
) + 1);
4116 y
= 60 * ((2 * i
) + 1);
4117 color
= getPixelColor(device
, x
, y
);
4118 ok(color_match(color
, 0x0000ff00, 1),
4119 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
4123 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4124 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4126 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4127 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4129 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1)
4130 && caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1))
4132 static const DWORD vs_code
[] =
4134 0xfffe0101, /* vs_1_1 */
4135 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4136 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4139 static const DWORD ps_code
[] =
4141 0xffff0101, /* ps_1_1 */
4142 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4143 0x0000ffff /* end */
4145 static const struct vec3 quad
[] =
4147 {-1.0f
, -1.0f
, -0.5f
},
4148 {-1.0f
, 1.0f
, -0.5f
},
4149 { 1.0f
, -1.0f
, 1.5f
},
4150 { 1.0f
, 1.0f
, 1.5f
},
4152 static const D3DCOLOR expected
[] =
4154 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4155 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4156 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4157 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4159 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4160 * vertices either. */
4161 static const D3DCOLOR expected_broken
[] =
4163 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4164 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4165 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4166 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4168 static const DWORD decl
[] =
4171 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
4176 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_code
, &vs
, 0);
4177 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
4178 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_code
, &ps
);
4179 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4180 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
4181 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
4182 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4183 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4185 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
4186 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4187 hr
= IDirect3DDevice8_BeginScene(device
);
4188 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4189 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4190 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4191 hr
= IDirect3DDevice8_EndScene(device
);
4192 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4194 for (i
= 0; i
< 4; ++i
)
4196 for (j
= 0; j
< 4; ++j
)
4198 x
= 80 * ((2 * j
) + 1);
4199 y
= 60 * ((2 * i
) + 1);
4200 color
= getPixelColor(device
, x
, y
);
4201 ok(color_match(color
, expected
[i
* 4 + j
], 1)
4202 || broken(color_match(color
, expected_broken
[i
* 4 + j
], 1)),
4203 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected
[i
* 4 + j
], x
, y
, color
);
4207 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4208 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4210 hr
= IDirect3DDevice8_DeletePixelShader(device
, ps
);
4211 ok(SUCCEEDED(hr
), "Failed to delete pixel shader, hr %#x.\n", hr
);
4212 hr
= IDirect3DDevice8_DeleteVertexShader(device
, vs
);
4213 ok(SUCCEEDED(hr
), "Failed to delete vertex shader, hr %#x.\n", hr
);
4216 refcount
= IDirect3DDevice8_Release(device
);
4217 ok(!refcount
, "Device has %u references left.\n", refcount
);
4219 IDirect3D8_Release(d3d
);
4220 DestroyWindow(window
);
4223 static void fog_special_test(void)
4225 IDirect3DDevice8
*device
;
4242 struct vec3 position
;
4247 {{ -1.0f
, -1.0f
, 0.0f
}, 0xff00ff00},
4248 {{ -1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
4249 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
4250 {{ 1.0f
, 1.0f
, 1.0f
}, 0xff00ff00}
4254 DWORD vertexmode
, tablemode
;
4256 D3DCOLOR color_left
, color_right
;
4260 {D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, FALSE
, 0x00ff0000, 0x00ff0000},
4261 {D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, TRUE
, 0x00ff0000, 0x00ff0000},
4262 {D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000},
4263 {D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000},
4265 {D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, FALSE
, 0x0000ff00, 0x00ff0000},
4266 {D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, TRUE
, 0x0000ff00, 0x00ff0000},
4267 {D3DFOG_NONE
, D3DFOG_LINEAR
, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000},
4268 {D3DFOG_NONE
, D3DFOG_LINEAR
, TRUE
, TRUE
, 0x0000ff00, 0x00ff0000},
4270 static const DWORD pixel_shader_code
[] =
4272 0xffff0101, /* ps.1.1 */
4273 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4276 static const DWORD vertex_decl
[] =
4279 D3DVSD_REG(0, D3DVSDT_FLOAT3
), /* position, v0 */
4280 D3DVSD_REG(1, D3DVSDT_D3DCOLOR
), /* diffuse color, v1 */
4283 static const DWORD vertex_shader_code
[] =
4285 0xfffe0101, /* vs.1.1 */
4286 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4287 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4290 static const D3DMATRIX identity
=
4292 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4293 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4294 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4295 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4298 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4299 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4300 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4301 ok(!!d3d
, "Failed to create a D3D object.\n");
4302 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4304 skip("Failed to create a D3D device, skipping tests.\n");
4308 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4309 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4310 if (caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1))
4312 hr
= IDirect3DDevice8_CreateVertexShader(device
, vertex_decl
, vertex_shader_code
, &vs
, 0);
4313 ok(SUCCEEDED(hr
), "Failed to create vertex shader, hr %#x.\n", hr
);
4317 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4320 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1))
4322 hr
= IDirect3DDevice8_CreatePixelShader(device
, pixel_shader_code
, &ps
);
4323 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4327 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4331 /* The table fog tests seem to depend on the projection matrix explicitly
4332 * being set to an identity matrix, even though that's the default.
4333 * (AMD Radeon HD 6310, Windows 7) */
4334 hr
= IDirect3DDevice8_SetTransform(device
, D3DTS_PROJECTION
, &identity
);
4335 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
4337 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
4338 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4339 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGENABLE
, TRUE
);
4340 ok(SUCCEEDED(hr
), "Failed to enable fog, hr %#x.\n", hr
);
4341 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGCOLOR
, 0xffff0000);
4342 ok(SUCCEEDED(hr
), "Failed to set fog color, hr %#x.\n", hr
);
4345 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGSTART
, conv
.d
);
4346 ok(SUCCEEDED(hr
), "Failed to set fog start, hr %#x.\n", hr
);
4347 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGEND
, conv
.d
);
4348 ok(SUCCEEDED(hr
), "Failed to set fog end, hr %#x.\n", hr
);
4350 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4352 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
4353 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4357 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
4358 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
4362 hr
= IDirect3DDevice8_SetVertexShader(device
, vs
);
4363 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
4372 hr
= IDirect3DDevice8_SetPixelShader(device
, 0);
4373 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4377 hr
= IDirect3DDevice8_SetPixelShader(device
, ps
);
4378 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4385 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGVERTEXMODE
, tests
[i
].vertexmode
);
4386 ok(SUCCEEDED(hr
), "Failed to set fogvertexmode, hr %#x.\n", hr
);
4387 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_FOGTABLEMODE
, tests
[i
].tablemode
);
4388 ok(SUCCEEDED(hr
), "Failed to set fogtablemode, hr %#x.\n", hr
);
4390 hr
= IDirect3DDevice8_BeginScene(device
);
4391 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4392 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, quad
, sizeof(*quad
));
4393 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4394 hr
= IDirect3DDevice8_EndScene(device
);
4395 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4397 color
= getPixelColor(device
, 310, 240);
4398 ok(color_match(color
, tests
[i
].color_left
, 1),
4399 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_left
, color
, i
);
4400 color
= getPixelColor(device
, 330, 240);
4401 ok(color_match(color
, tests
[i
].color_right
, 1),
4402 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_right
, color
, i
);
4404 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4405 ok(SUCCEEDED(hr
), "Failed to present backbuffer, hr %#x.\n", hr
);
4409 IDirect3DDevice8_DeleteVertexShader(device
, vs
);
4411 IDirect3DDevice8_DeletePixelShader(device
, ps
);
4412 refcount
= IDirect3DDevice8_Release(device
);
4413 ok(!refcount
, "Device has %u references left.\n", refcount
);
4415 IDirect3D8_Release(d3d
);
4416 DestroyWindow(window
);
4419 static void volume_dxt5_test(void)
4421 IDirect3DVolumeTexture8
*texture
;
4422 IDirect3DDevice8
*device
;
4431 static const char texture_data
[] =
4433 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4434 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4435 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4436 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4437 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4441 struct vec3 position
;
4446 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.25f
}},
4447 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.25f
}},
4448 {{ 0.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.25f
}},
4449 {{ 0.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.25f
}},
4451 {{ 0.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.75f
}},
4452 {{ 0.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.75f
}},
4453 {{ 1.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.75f
}},
4454 {{ 1.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.75f
}},
4456 static const DWORD expected_colors
[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4458 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4459 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4460 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4461 ok(!!d3d
, "Failed to create a D3D object.\n");
4462 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4464 skip("Failed to create a D3D device, skipping tests.\n");
4468 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4469 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, D3DFMT_DXT5
)))
4471 skip("Volume DXT5 textures are not supported, skipping test.\n");
4472 IDirect3DDevice8_Release(device
);
4476 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 8, 4, 2, 1, 0, D3DFMT_DXT5
,
4477 D3DPOOL_MANAGED
, &texture
);
4478 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
4480 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &box
, NULL
, 0);
4481 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
4482 memcpy(box
.pBits
, texture_data
, sizeof(texture_data
));
4483 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
4484 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
4486 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0));
4487 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4488 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
4489 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4490 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
4491 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
4492 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
4493 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
4494 hr
= IDirect3DDevice8_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
4495 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
4496 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4497 ok(SUCCEEDED(hr
), "Failed to set mag filter, hr %#x.\n", hr
);
4499 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
4500 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
4501 hr
= IDirect3DDevice8_BeginScene(device
);
4502 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4503 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
4504 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4505 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
4506 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4507 hr
= IDirect3DDevice8_EndScene(device
);
4508 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4510 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4511 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4512 for (i
= 0; i
< 4; i
++)
4514 color
= getPixelColor(device
, 80 + 160 * i
, 240);
4515 ok (color_match(color
, expected_colors
[i
], 1),
4516 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors
[i
], color
, i
);
4519 IDirect3DVolumeTexture8_Release(texture
);
4520 refcount
= IDirect3DDevice8_Release(device
);
4521 ok(!refcount
, "Device has %u references left.\n", refcount
);
4523 IDirect3D8_Release(d3d
);
4524 DestroyWindow(window
);
4527 static void volume_v16u16_test(void)
4529 IDirect3DVolumeTexture8
*texture
;
4530 IDirect3DDevice8
*device
;
4544 struct vec3 position
;
4549 {{ -1.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.25f
}},
4550 {{ -1.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.25f
}},
4551 {{ 0.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.25f
}},
4552 {{ 0.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.25f
}},
4554 {{ 0.0f
, -1.0f
, 0.0f
}, { 0.0f
, 0.0f
, 0.75f
}},
4555 {{ 0.0f
, 1.0f
, 0.0f
}, { 0.0f
, 1.0f
, 0.75f
}},
4556 {{ 1.0f
, -1.0f
, 1.0f
}, { 1.0f
, 0.0f
, 0.75f
}},
4557 {{ 1.0f
, 1.0f
, 1.0f
}, { 1.0f
, 1.0f
, 0.75f
}},
4559 static const DWORD shader_code
[] =
4561 0xffff0101, /* ps_1_1 */
4562 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
4563 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
4564 0x00000042, 0xb00f0000, /* tex t0 */
4565 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
4566 0x0000ffff /* end */
4569 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4570 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4571 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4572 ok(!!d3d
, "Failed to create a D3D object.\n");
4573 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4575 skip("Failed to create a D3D device, skipping tests.\n");
4579 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
4580 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, D3DFMT_V16U16
)))
4582 skip("Volume V16U16 textures are not supported, skipping test.\n");
4583 IDirect3DDevice8_Release(device
);
4586 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4587 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
4588 if (caps
.PixelShaderVersion
< D3DPS_VERSION(1, 1))
4590 skip("No pixel shader 1.1 support, skipping test.\n");
4591 IDirect3DDevice8_Release(device
);
4595 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
| D3DFVF_TEXCOORDSIZE3(0));
4596 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4597 hr
= IDirect3DDevice8_CreatePixelShader(device
, shader_code
, &shader
);
4598 ok(SUCCEEDED(hr
), "Failed to create pixel shader, hr %#x.\n", hr
);
4599 hr
= IDirect3DDevice8_SetPixelShader(device
, shader
);
4600 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4601 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, D3DTEXF_POINT
);
4602 ok(SUCCEEDED(hr
), "Failed to set filter, hr %#x.\n", hr
);
4604 for (i
= 0; i
< 2; i
++)
4609 pool
= D3DPOOL_SYSTEMMEM
;
4611 pool
= D3DPOOL_MANAGED
;
4613 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 2, 2, 1, 0, D3DFMT_V16U16
,
4615 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
4617 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &box
, NULL
, 0);
4618 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
4620 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 0 * box
.RowPitch
+ 0 * box
.SlicePitch
);
4623 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 1 * box
.RowPitch
+ 0 * box
.SlicePitch
);
4626 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 0 * box
.RowPitch
+ 1 * box
.SlicePitch
);
4629 texel
= (SHORT
*)((BYTE
*)box
.pBits
+ 1 * box
.RowPitch
+ 1 * box
.SlicePitch
);
4633 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
4634 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
4638 IDirect3DVolumeTexture8
*texture2
;
4640 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 2, 2, 1, 0, D3DFMT_V16U16
,
4641 D3DPOOL_DEFAULT
, &texture2
);
4642 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
4644 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)texture
,
4645 (IDirect3DBaseTexture8
*)texture2
);
4646 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4648 IDirect3DVolumeTexture8_Release(texture
);
4652 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) texture
);
4653 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4655 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x00ff00ff, 1.0f
, 0);
4656 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
4657 hr
= IDirect3DDevice8_BeginScene(device
);
4658 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4659 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[0], sizeof(*quads
));
4660 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4661 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quads
[4], sizeof(*quads
));
4662 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4663 hr
= IDirect3DDevice8_EndScene(device
);
4664 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4666 color
= getPixelColor(device
, 120, 160);
4667 ok (color_match(color
, 0x000080ff, 2),
4668 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color
);
4669 color
= getPixelColor(device
, 120, 400);
4670 ok (color_match(color
, 0x00ffffff, 2),
4671 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color
);
4672 color
= getPixelColor(device
, 360, 160);
4673 ok (color_match(color
, 0x007f7fff, 2),
4674 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color
);
4675 color
= getPixelColor(device
, 360, 400);
4676 ok (color_match(color
, 0x0040c0ff, 2),
4677 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color
);
4679 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4680 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4682 IDirect3DVolumeTexture8_Release(texture
);
4685 hr
= IDirect3DDevice8_DeletePixelShader(device
, shader
);
4686 ok(SUCCEEDED(hr
), "Failed delete pixel shader, hr %#x.\n", hr
);
4687 refcount
= IDirect3DDevice8_Release(device
);
4688 ok(!refcount
, "Device has %u references left.\n", refcount
);
4690 IDirect3D8_Release(d3d
);
4691 DestroyWindow(window
);
4694 static void fill_surface(IDirect3DSurface8
*surface
, DWORD color
, DWORD flags
)
4696 D3DSURFACE_DESC desc
;
4702 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
4703 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4704 hr
= IDirect3DSurface8_LockRect(surface
, &l
, NULL
, flags
);
4705 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4709 for (y
= 0; y
< desc
.Height
; y
++)
4711 mem
= (DWORD
*)((BYTE
*)l
.pBits
+ y
* l
.Pitch
);
4712 for (x
= 0; x
< l
.Pitch
/ sizeof(DWORD
); x
++)
4717 hr
= IDirect3DSurface8_UnlockRect(surface
);
4718 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4721 static void add_dirty_rect_test_draw(IDirect3DDevice8
*device
)
4726 struct vec3 position
;
4727 struct vec2 texcoord
;
4731 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
4732 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
4733 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
4734 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
4737 hr
= IDirect3DDevice8_BeginScene(device
);
4738 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4739 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
, sizeof(*quad
));
4740 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4741 hr
= IDirect3DDevice8_EndScene(device
);
4742 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4745 static void add_dirty_rect_test(void)
4747 IDirect3DSurface8
*surface_dst2
, *surface_src_green
, *surface_src_red
, *surface_managed
;
4748 IDirect3DTexture8
*tex_dst1
, *tex_dst2
, *tex_src_red
, *tex_src_green
, *tex_managed
;
4749 D3DLOCKED_RECT locked_rect
;
4750 IDirect3DDevice8
*device
;
4759 static const RECT part_rect
= {96, 96, 160, 160};
4761 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4762 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
4763 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4764 ok(!!d3d
, "Failed to create a D3D object.\n");
4765 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4767 skip("Failed to create a D3D device, skipping tests.\n");
4771 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4772 D3DPOOL_DEFAULT
, &tex_dst1
);
4773 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4774 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4775 D3DPOOL_DEFAULT
, &tex_dst2
);
4776 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4777 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4778 D3DPOOL_SYSTEMMEM
, &tex_src_red
);
4779 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4780 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4781 D3DPOOL_SYSTEMMEM
, &tex_src_green
);
4782 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4783 hr
= IDirect3DDevice8_CreateTexture(device
, 256, 256, 1, 0, D3DFMT_X8R8G8B8
,
4784 D3DPOOL_MANAGED
, &tex_managed
);
4785 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4787 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_dst2
, 0, &surface_dst2
);
4788 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4789 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_src_green
, 0, &surface_src_green
);
4790 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4791 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_src_red
, 0, &surface_src_red
);
4792 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4793 hr
= IDirect3DTexture8_GetSurfaceLevel(tex_managed
, 0, &surface_managed
);
4794 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
4796 fill_surface(surface_src_red
, 0x00ff0000, 0);
4797 fill_surface(surface_src_green
, 0x0000ff00, 0);
4799 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
4800 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
4801 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
4802 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
4803 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
4804 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
4806 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4807 (IDirect3DBaseTexture8
*)tex_dst1
);
4808 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4810 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
4811 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_red
,
4812 (IDirect3DBaseTexture8
*)tex_dst2
);
4813 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4814 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4815 (IDirect3DBaseTexture8
*)tex_dst2
);
4816 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4818 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst1
);
4819 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4820 add_dirty_rect_test_draw(device
);
4821 color
= getPixelColor(device
, 320, 240);
4822 ok(color_match(color
, 0x0000ff00, 1),
4823 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4824 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4825 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4827 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst2
);
4828 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4829 add_dirty_rect_test_draw(device
);
4830 color
= getPixelColor(device
, 320, 240);
4831 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4832 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4833 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4834 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4836 /* AddDirtyRect on the destination is ignored. */
4837 hr
= IDirect3DTexture8_AddDirtyRect(tex_dst2
, &part_rect
);
4838 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4839 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4840 (IDirect3DBaseTexture8
*)tex_dst2
);
4841 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4842 add_dirty_rect_test_draw(device
);
4843 color
= getPixelColor(device
, 320, 240);
4844 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4845 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4846 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4847 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4849 hr
= IDirect3DTexture8_AddDirtyRect(tex_dst2
, NULL
);
4850 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4851 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4852 (IDirect3DBaseTexture8
*)tex_dst2
);
4853 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4854 add_dirty_rect_test_draw(device
);
4855 color
= getPixelColor(device
, 320, 240);
4856 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4857 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4858 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4859 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4861 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
4862 * tracking is supported. */
4863 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, &part_rect
);
4864 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4865 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4866 (IDirect3DBaseTexture8
*)tex_dst2
);
4867 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4868 add_dirty_rect_test_draw(device
);
4869 color
= getPixelColor(device
, 320, 240);
4870 ok(color_match(color
, 0x0000ff00, 1),
4871 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4872 color
= getPixelColor(device
, 1, 1);
4873 todo_wine
ok(color_match(color
, 0x00ff0000, 1),
4874 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4875 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4876 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4878 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, NULL
);
4879 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
4880 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4881 (IDirect3DBaseTexture8
*)tex_dst2
);
4882 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4883 add_dirty_rect_test_draw(device
);
4884 color
= getPixelColor(device
, 1, 1);
4885 ok(color_match(color
, 0x0000ff00, 1),
4886 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4888 /* Locks with NO_DIRTY_UPDATE are ignored. */
4889 fill_surface(surface_src_green
, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE
);
4890 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4891 (IDirect3DBaseTexture8
*)tex_dst2
);
4892 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4893 add_dirty_rect_test_draw(device
);
4894 color
= getPixelColor(device
, 320, 240);
4895 todo_wine
ok(color_match(color
, 0x0000ff00, 1),
4896 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4897 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4898 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4900 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
4901 fill_surface(surface_src_green
, 0x000000ff, D3DLOCK_READONLY
);
4902 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4903 (IDirect3DBaseTexture8
*)tex_dst2
);
4904 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4905 add_dirty_rect_test_draw(device
);
4906 color
= getPixelColor(device
, 320, 240);
4907 todo_wine
ok(color_match(color
, 0x0000ff00, 1),
4908 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4909 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4910 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4912 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_green
, NULL
);
4913 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4914 (IDirect3DBaseTexture8
*)tex_dst2
);
4915 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4916 add_dirty_rect_test_draw(device
);
4917 color
= getPixelColor(device
, 320, 240);
4918 ok(color_match(color
, 0x000000ff, 1),
4919 "Expected color 0x000000ff, got 0x%08x.\n", color
);
4920 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4921 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4923 /* Maps without either of these flags record a dirty rectangle. */
4924 fill_surface(surface_src_green
, 0x00ffffff, 0);
4925 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4926 (IDirect3DBaseTexture8
*)tex_dst2
);
4927 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4928 add_dirty_rect_test_draw(device
);
4929 color
= getPixelColor(device
, 320, 240);
4930 ok(color_match(color
, 0x00ffffff, 1),
4931 "Expected color 0x00ffffff, got 0x%08x.\n", color
);
4932 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4933 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4935 /* Partial LockRect works just like a partial AddDirtyRect call. */
4936 hr
= IDirect3DTexture8_LockRect(tex_src_green
, 0, &locked_rect
, &part_rect
, 0);
4937 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
4938 texel
= locked_rect
.pBits
;
4939 for (i
= 0; i
< 64; i
++)
4940 texel
[i
] = 0x00ff00ff;
4941 for (i
= 1; i
< 64; i
++)
4942 memcpy((BYTE
*)locked_rect
.pBits
+ i
* locked_rect
.Pitch
, locked_rect
.pBits
, locked_rect
.Pitch
);
4943 hr
= IDirect3DTexture8_UnlockRect(tex_src_green
, 0);
4944 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
4945 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4946 (IDirect3DBaseTexture8
*)tex_dst2
);
4947 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4948 add_dirty_rect_test_draw(device
);
4949 color
= getPixelColor(device
, 320, 240);
4950 ok(color_match(color
, 0x00ff00ff, 1),
4951 "Expected color 0x00ff00ff, got 0x%08x.\n", color
);
4952 color
= getPixelColor(device
, 1, 1);
4953 ok(color_match(color
, 0x00ffffff, 1),
4954 "Expected color 0x00ffffff, got 0x%08x.\n", color
);
4955 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4956 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4958 fill_surface(surface_src_red
, 0x00ff0000, 0);
4959 fill_surface(surface_src_green
, 0x0000ff00, 0);
4961 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_green
,
4962 (IDirect3DBaseTexture8
*)tex_dst1
);
4963 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x.\n", hr
);
4964 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst1
);
4965 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4966 add_dirty_rect_test_draw(device
);
4967 color
= getPixelColor(device
, 320, 240);
4968 ok(color_match(color
, 0x0000ff00, 1),
4969 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4970 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4971 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4973 /* UpdateSurface ignores the missing dirty marker. */
4974 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)tex_src_red
,
4975 (IDirect3DBaseTexture8
*)tex_dst2
);
4976 hr
= IDirect3DDevice8_CopyRects(device
, surface_src_green
, NULL
, 0, surface_dst2
, NULL
);
4977 ok(SUCCEEDED(hr
), "Failed to update surface, hr %#x.\n", hr
);
4978 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_dst2
);
4979 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4980 add_dirty_rect_test_draw(device
);
4981 color
= getPixelColor(device
, 320, 240);
4982 ok(color_match(color
, 0x0000ff00, 1),
4983 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
4984 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4985 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4987 fill_surface(surface_managed
, 0x00ff0000, 0);
4988 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)tex_managed
);
4989 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4990 add_dirty_rect_test_draw(device
);
4991 color
= getPixelColor(device
, 320, 240);
4992 ok(color_match(color
, 0x00ff0000, 1),
4993 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
4994 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
4995 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
4997 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
4998 fill_surface(surface_managed
, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE
);
4999 add_dirty_rect_test_draw(device
);
5000 color
= getPixelColor(device
, 320, 240);
5001 ok(color_match(color
, 0x00ff0000, 1),
5002 "Expected color 0x00ff0000, got 0x%08x.\n", color
);
5003 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5004 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5006 /* AddDirtyRect uploads the new contents.
5007 * Side note, not tested in the test: Partial surface updates work, and two separate
5008 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5010 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5011 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5012 add_dirty_rect_test_draw(device
);
5013 color
= getPixelColor(device
, 320, 240);
5014 ok(color_match(color
, 0x0000ff00, 1),
5015 "Expected color 0x0000ff00, got 0x%08x.\n", color
);
5016 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5017 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5019 /* So does ResourceManagerDiscardBytes. */
5020 fill_surface(surface_managed
, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE
);
5021 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5022 hr
= IDirect3DDevice8_ResourceManagerDiscardBytes(device
, 0);
5023 ok(SUCCEEDED(hr
), "Failed to evict managed resources, hr %#x.\n", hr
);
5024 add_dirty_rect_test_draw(device
);
5025 color
= getPixelColor(device
, 320, 240);
5026 ok(color_match(color
, 0x000000ff, 1),
5027 "Expected color 0x000000ff, got 0x%08x.\n", color
);
5028 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
5029 ok(SUCCEEDED(hr
), "Failed to present, hr %#x.\n", hr
);
5031 /* AddDirtyRect on a locked texture is allowed. */
5032 hr
= IDirect3DTexture8_LockRect(tex_src_red
, 0, &locked_rect
, NULL
, 0);
5033 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5034 hr
= IDirect3DTexture8_AddDirtyRect(tex_src_red
, NULL
);
5035 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5036 hr
= IDirect3DTexture8_UnlockRect(tex_src_red
, 0);
5037 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5039 /* Redundant AddDirtyRect calls are ok. */
5040 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5041 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5042 hr
= IDirect3DTexture8_AddDirtyRect(tex_managed
, NULL
);
5043 ok(SUCCEEDED(hr
), "Failed to add dirty rect, hr %#x.\n", hr
);
5045 IDirect3DSurface8_Release(surface_dst2
);
5046 IDirect3DSurface8_Release(surface_managed
);
5047 IDirect3DSurface8_Release(surface_src_red
);
5048 IDirect3DSurface8_Release(surface_src_green
);
5049 IDirect3DTexture8_Release(tex_src_red
);
5050 IDirect3DTexture8_Release(tex_src_green
);
5051 IDirect3DTexture8_Release(tex_dst1
);
5052 IDirect3DTexture8_Release(tex_dst2
);
5053 IDirect3DTexture8_Release(tex_managed
);
5054 refcount
= IDirect3DDevice8_Release(device
);
5055 ok(!refcount
, "Device has %u references left.\n", refcount
);
5057 IDirect3D8_Release(d3d
);
5058 DestroyWindow(window
);
5063 D3DADAPTER_IDENTIFIER8 identifier
;
5067 if (!(d3d
= Direct3DCreate8(D3D_SDK_VERSION
)))
5069 skip("Failed to create D3D8 object.\n");
5073 memset(&identifier
, 0, sizeof(identifier
));
5074 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
5075 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#x.\n", hr
);
5076 trace("Driver string: \"%s\"\n", identifier
.Driver
);
5077 trace("Description string: \"%s\"\n", identifier
.Description
);
5078 /* Only Windows XP's default VGA driver should have an empty description */
5079 ok(identifier
.Description
[0] || broken(!strcmp(identifier
.Driver
, "vga.dll")), "Empty driver description.\n");
5080 trace("Driver version %d.%d.%d.%d\n",
5081 HIWORD(U(identifier
.DriverVersion
).HighPart
), LOWORD(U(identifier
.DriverVersion
).HighPart
),
5082 HIWORD(U(identifier
.DriverVersion
).LowPart
), LOWORD(U(identifier
.DriverVersion
).LowPart
));
5084 IDirect3D8_Release(d3d
);
5094 test_scalar_instructions();
5095 fog_with_shader_test();
5099 depth_buffer_test();
5100 depth_buffer2_test();
5103 multisample_copy_rects_test();
5108 volume_v16u16_test();
5109 add_dirty_rect_test();