d3d8/tests: Get rid of struct vertex.
[wine.git] / dlls / d3d8 / tests / visual.c
blob552106609b8f2795751df3911ec289323ad53f1f
1 /*
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 */
22 #define COBJMACROS
23 #include <d3d8.h>
24 #include "wine/test.h"
26 struct vec2
28 float x, y;
31 struct vec3
33 float x, y, z;
36 struct vec4
38 float x, y, z, w;
41 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
43 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
44 c1 >>= 8; c2 >>= 8;
45 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
46 c1 >>= 8; c2 >>= 8;
47 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
48 c1 >>= 8; c2 >>= 8;
49 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50 return TRUE;
53 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
55 DWORD ret;
56 IDirect3DTexture8 *tex = NULL;
57 IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
58 HRESULT hr;
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);
66 return 0xdeadbeef;
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);
72 ret = 0xdeadbeee;
73 goto out;
76 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
77 if(FAILED(hr))
79 trace("Can't get the render target, hr=%#08x\n", hr);
80 ret = 0xdeadbeed;
81 goto out;
83 hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
84 if(FAILED(hr))
86 trace("Can't read the render target, hr=%#08x\n", hr);
87 ret = 0xdeadbeec;
88 goto out;
91 hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
92 if(FAILED(hr))
94 trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
95 ret = 0xdeadbeeb;
96 goto out;
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);
103 if(FAILED(hr))
105 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
108 out:
109 if(backbuf) IDirect3DSurface8_Release(backbuf);
110 if(surf) IDirect3DSurface8_Release(surf);
111 if(tex) IDirect3DTexture8_Release(tex);
112 return ret;
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)))
131 return device;
133 return NULL;
136 struct tvertex
138 float x, y, z, w;
139 DWORD diffuse;
142 struct nvertex
144 float x, y, z;
145 float nx, ny, nz;
146 DWORD diffuse;
149 static void test_sanity(void)
151 IDirect3DDevice8 *device;
152 IDirect3D8 *d3d;
153 D3DCOLOR color;
154 ULONG refcount;
155 HWND window;
156 HRESULT hr;
158 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
159 0, 0, 640, 480, NULL, NULL, NULL, NULL);
160 d3d = Direct3DCreate8(D3D_SDK_VERSION);
161 ok(!!d3d, "Failed to create a D3D object.\n");
162 if (!(device = create_device(d3d, window, window, TRUE)))
164 skip("Failed to create a D3D device, skipping tests.\n");
165 goto done;
168 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
169 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
170 color = getPixelColor(device, 1, 1);
171 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
173 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
174 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
176 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
177 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
178 color = getPixelColor(device, 639, 479);
179 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
181 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
182 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
184 refcount = IDirect3DDevice8_Release(device);
185 ok(!refcount, "Device has %u references left.\n", refcount);
186 done:
187 IDirect3D8_Release(d3d);
188 DestroyWindow(window);
191 static void lighting_test(void)
193 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
194 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
195 IDirect3DDevice8 *device;
196 IDirect3D8 *d3d;
197 D3DCOLOR color;
198 ULONG refcount;
199 HWND window;
200 HRESULT hr;
202 static const struct
204 struct vec3 position;
205 DWORD diffuse;
207 unlitquad[] =
209 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
210 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
211 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
212 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
214 litquad[] =
216 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
217 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
218 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
219 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
221 static const struct nvertex unlitnquad[] =
223 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
224 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
225 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
226 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
228 static const struct nvertex litnquad[] =
230 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
231 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
232 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
233 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
235 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
236 static const D3DMATRIX mat =
238 1.0f, 0.0f, 0.0f, 0.0f,
239 0.0f, 1.0f, 0.0f, 0.0f,
240 0.0f, 0.0f, 1.0f, 0.0f,
241 0.0f, 0.0f, 0.0f, 1.0f,
242 }}};
244 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
245 0, 0, 640, 480, NULL, NULL, NULL, NULL);
246 d3d = Direct3DCreate8(D3D_SDK_VERSION);
247 ok(!!d3d, "Failed to create a D3D object.\n");
248 if (!(device = create_device(d3d, window, window, TRUE)))
250 skip("Failed to create a D3D device, skipping tests.\n");
251 goto done;
254 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
255 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
257 /* Setup some states that may cause issues */
258 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
259 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
260 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
261 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
262 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
263 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
265 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
266 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
267 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
268 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
269 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
270 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
271 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
272 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
273 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
275 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
276 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
277 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
278 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
279 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
281 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
282 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
284 hr = IDirect3DDevice8_BeginScene(device);
285 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
287 /* No lights are defined... That means, lit vertices should be entirely black. */
288 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
289 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
290 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
291 2 /* PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
292 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
294 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
295 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
296 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
297 2 /* PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
298 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
300 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
301 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
303 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
304 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
305 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
306 2 /* PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
309 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
310 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
311 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
312 2 /* PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
313 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
315 hr = IDirect3DDevice8_EndScene(device);
316 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
318 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
319 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
320 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
321 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
322 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
323 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
324 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
325 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
327 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
329 refcount = IDirect3DDevice8_Release(device);
330 ok(!refcount, "Device has %u references left.\n", refcount);
331 done:
332 IDirect3D8_Release(d3d);
333 DestroyWindow(window);
336 static void clear_test(void)
338 /* Tests the correctness of clearing parameters */
339 D3DRECT rect_negneg, rect[2];
340 IDirect3DDevice8 *device;
341 IDirect3D8 *d3d;
342 D3DCOLOR color;
343 ULONG refcount;
344 HWND window;
345 HRESULT hr;
347 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
348 0, 0, 640, 480, NULL, NULL, NULL, NULL);
349 d3d = Direct3DCreate8(D3D_SDK_VERSION);
350 ok(!!d3d, "Failed to create a D3D object.\n");
351 if (!(device = create_device(d3d, window, window, TRUE)))
353 skip("Failed to create a D3D device, skipping tests.\n");
354 goto done;
357 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
358 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
360 /* Positive x, negative y */
361 rect[0].x1 = 0;
362 rect[0].y1 = 480;
363 rect[0].x2 = 320;
364 rect[0].y2 = 240;
366 /* Positive x, positive y */
367 rect[1].x1 = 0;
368 rect[1].y1 = 0;
369 rect[1].x2 = 320;
370 rect[1].y2 = 240;
371 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
372 * is ignored, the positive is still cleared afterwards
374 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
375 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
377 /* negative x, negative y */
378 rect_negneg.x1 = 640;
379 rect_negneg.y1 = 240;
380 rect_negneg.x2 = 320;
381 rect_negneg.y2 = 0;
382 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
383 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
385 color = getPixelColor(device, 160, 360); /* lower left quad */
386 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
387 color = getPixelColor(device, 160, 120); /* upper left quad */
388 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
389 color = getPixelColor(device, 480, 360); /* lower right quad */
390 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
391 color = getPixelColor(device, 480, 120); /* upper right quad */
392 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
394 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
396 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
397 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
399 rect[0].x1 = 0;
400 rect[0].y1 = 0;
401 rect[0].x2 = 640;
402 rect[0].y2 = 480;
403 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
404 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
406 color = getPixelColor(device, 320, 240);
407 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
408 "Clear with count = 0, rect != NULL has color %#08x\n", color);
410 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
412 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
413 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
414 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
415 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
417 color = getPixelColor(device, 320, 240);
418 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
419 "Clear with count = 1, rect = NULL has color %#08x\n", color);
421 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
423 refcount = IDirect3DDevice8_Release(device);
424 ok(!refcount, "Device has %u references left.\n", refcount);
425 done:
426 IDirect3D8_Release(d3d);
427 DestroyWindow(window);
430 static void fog_test(void)
432 float start = 0.0f, end = 1.0f;
433 IDirect3DDevice8 *device;
434 IDirect3D8 *d3d;
435 D3DCOLOR color;
436 ULONG refcount;
437 D3DCAPS8 caps;
438 HWND window;
439 HRESULT hr;
441 /* Gets full z based fog with linear fog, no fog with specular color. */
442 static const struct
444 float x, y, z;
445 D3DCOLOR diffuse;
446 D3DCOLOR specular;
448 untransformed_1[] =
450 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
451 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
452 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
453 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
455 /* Ok, I am too lazy to deal with transform matrices. */
456 untransformed_2[] =
458 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
459 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
460 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
461 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
463 far_quad1[] =
465 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
466 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
467 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
468 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
470 far_quad2[] =
472 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
473 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
474 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
475 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
478 /* Untransformed ones. Give them a different diffuse color to make the
479 * test look nicer. It also makes making sure that they are drawn
480 * correctly easier. */
481 static const struct
483 float x, y, z, rhw;
484 D3DCOLOR diffuse;
485 D3DCOLOR specular;
487 transformed_1[] =
489 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
490 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
491 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
492 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
494 transformed_2[] =
496 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
497 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
498 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
499 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
501 static const D3DMATRIX ident_mat =
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.0f, 1.0f,
507 }}};
508 static const D3DMATRIX world_mat1 =
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, -0.5f, 1.0f,
514 }}};
515 static const D3DMATRIX world_mat2 =
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,
521 }}};
522 static const D3DMATRIX proj_mat =
524 1.0f, 0.0f, 0.0f, 0.0f,
525 0.0f, 1.0f, 0.0f, 0.0f,
526 0.0f, 0.0f, 1.0f, 0.0f,
527 0.0f, 0.0f, -1.0f, 1.0f,
528 }}};
529 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
531 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
532 0, 0, 640, 480, NULL, NULL, NULL, NULL);
533 d3d = Direct3DCreate8(D3D_SDK_VERSION);
534 ok(!!d3d, "Failed to create a D3D object.\n");
535 if (!(device = create_device(d3d, window, window, TRUE)))
537 skip("Failed to create a D3D device, skipping tests.\n");
538 goto done;
541 memset(&caps, 0, sizeof(caps));
542 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
543 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
544 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
545 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
547 /* Setup initial states: No lighting, fog on, fog color */
548 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
549 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
550 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
551 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
552 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
553 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
554 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
555 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
556 /* Some of the tests seem to depend on the projection matrix explicitly
557 * being set to an identity matrix, even though that's the default.
558 * (AMD Radeon HD 6310, Windows 7) */
559 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
560 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
562 /* First test: Both table fog and vertex fog off */
563 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
564 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
565 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
566 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
568 /* Start = 0, end = 1. Should be default, but set them */
569 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
570 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
571 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
572 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
574 hr = IDirect3DDevice8_BeginScene(device);
575 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
577 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
578 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
579 /* Untransformed, vertex fog = NONE, table fog = NONE:
580 * Read the fog weighting from the specular color. */
581 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
582 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
583 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
585 /* This makes it use the Z value. */
586 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
587 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
588 /* Untransformed, vertex fog != none (or table fog != none):
589 * Use the Z value as input into the equation. */
590 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
591 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
592 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
594 /* Transformed vertices. */
595 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
596 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
597 /* Transformed, vertex fog != NONE, pixel fog == NONE:
598 * Use specular color alpha component. */
599 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
600 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
601 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
603 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
604 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
605 /* Transformed, table fog != none, vertex anything:
606 * Use Z value as input to the fog equation. */
607 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
608 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
609 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
611 hr = IDirect3DDevice8_EndScene(device);
612 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
614 color = getPixelColor(device, 160, 360);
615 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
616 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
617 color = getPixelColor(device, 160, 120);
618 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
619 "Untransformed vertex with linear vertex fog has color %08x\n", color);
620 color = getPixelColor(device, 480, 120);
621 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
622 "Transformed vertex with linear vertex fog has color %08x\n", color);
623 color = getPixelColor(device, 480, 360);
624 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
625 "Transformed vertex with linear table fog has color %08x\n", color);
627 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
629 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
631 /* A simple fog + non-identity world matrix test */
632 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
633 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
635 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
636 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
637 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
638 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
640 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
641 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
643 hr = IDirect3DDevice8_BeginScene(device);
644 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
645 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
646 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
647 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
648 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
649 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
650 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
651 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
652 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
653 hr = IDirect3DDevice8_EndScene(device);
654 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
656 color = getPixelColor(device, 160, 360);
657 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
658 color = getPixelColor(device, 160, 120);
659 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
660 "Fogged out quad has color %08x\n", color);
662 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
664 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
665 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
666 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
667 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
668 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
670 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
671 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
673 hr = IDirect3DDevice8_BeginScene(device);
674 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
675 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
676 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
677 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
678 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
679 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
680 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
681 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
682 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
683 hr = IDirect3DDevice8_EndScene(device);
684 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
686 color = getPixelColor(device, 160, 360);
687 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
688 color = getPixelColor(device, 160, 120);
689 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
690 "Fogged out quad has color %08x\n", color);
692 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
694 else
696 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
699 refcount = IDirect3DDevice8_Release(device);
700 ok(!refcount, "Device has %u references left.\n", refcount);
701 done:
702 IDirect3D8_Release(d3d);
703 DestroyWindow(window);
706 /* This tests fog in combination with shaders.
707 * What's tested: linear fog (vertex and table) with pixel shader
708 * linear table fog with non foggy vertex shader
709 * vertex fog with foggy vertex shader, non-linear
710 * fog with shader, non-linear fog with foggy shader,
711 * linear table fog with foggy shader */
712 static void fog_with_shader_test(void)
714 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
715 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
716 DWORD pixel_shader[2] = {0, 0};
717 IDirect3DDevice8 *device;
718 unsigned int i, j;
719 IDirect3D8 *d3d;
720 D3DCOLOR color;
721 ULONG refcount;
722 D3DCAPS8 caps;
723 HWND window;
724 HRESULT hr;
725 union
727 float f;
728 DWORD i;
729 } start, end;
731 /* Basic vertex shader without fog computation ("non foggy") */
732 static const DWORD vertex_shader_code1[] =
734 0xfffe0100, /* vs.1.0 */
735 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
736 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
737 0x0000ffff
739 /* Basic vertex shader with reversed fog computation ("foggy") */
740 static const DWORD vertex_shader_code2[] =
742 0xfffe0100, /* vs.1.0 */
743 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
744 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
745 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
746 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
747 0x0000ffff
749 /* Basic pixel shader */
750 static const DWORD pixel_shader_code[] =
752 0xffff0101, /* ps_1_1 */
753 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
754 0x0000ffff
756 static struct
758 struct vec3 position;
759 DWORD diffuse;
761 quad[] =
763 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
764 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
765 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
766 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
768 static const DWORD decl[] =
770 D3DVSD_STREAM(0),
771 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
772 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
773 D3DVSD_END()
775 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
776 /* This reference data was collected on a nVidia GeForce 7600GS
777 * driver version 84.19 DirectX version 9.0c on Windows XP */
778 static const struct test_data_t
780 int vshader;
781 int pshader;
782 D3DFOGMODE vfog;
783 D3DFOGMODE tfog;
784 unsigned int color[11];
786 test_data[] =
788 /* Only pixel shader */
789 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
790 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
791 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
792 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
793 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
794 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
795 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
796 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
797 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
798 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
799 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
800 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
801 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
802 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
803 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
805 /* Vertex shader */
806 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
807 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
808 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
809 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
810 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
811 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
812 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
813 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
814 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
816 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
817 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
818 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
819 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
820 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
821 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
823 /* Vertex shader and pixel shader */
824 /* The next 4 tests would read the fog coord output, but it isn't available.
825 * The result is a fully fogged quad, no matter what the Z coord is. */
826 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
827 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
828 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
829 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
830 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
831 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
832 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
833 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
834 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
835 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
836 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
837 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
839 /* These use the Z coordinate with linear table fog */
840 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
841 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
842 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
843 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
844 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
845 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
846 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
847 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
848 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
849 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
850 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
851 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
853 /* Non-linear table fog without fog coord */
854 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
855 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
856 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
857 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
858 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
859 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
861 /* These tests fail on older Nvidia drivers */
862 /* Foggy vertex shader */
863 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
864 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
865 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
866 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
867 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
868 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
869 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
870 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
871 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
872 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
873 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
874 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
876 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
877 * all using the fixed fog-coord linear fog */
878 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
879 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
880 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
881 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
882 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
883 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
884 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
885 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
886 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
887 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
888 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
889 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
891 /* These use table fog. Here the shader-provided fog coordinate is
892 * ignored and the z coordinate used instead */
893 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
894 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
895 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
896 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
897 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
898 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
899 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
900 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
901 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
903 static const D3DMATRIX identity =
905 1.0f, 0.0f, 0.0f, 0.0f,
906 0.0f, 1.0f, 0.0f, 0.0f,
907 0.0f, 0.0f, 1.0f, 0.0f,
908 0.0f, 0.0f, 0.0f, 1.0f,
909 }}};
911 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
912 0, 0, 640, 480, NULL, NULL, NULL, NULL);
913 d3d = Direct3DCreate8(D3D_SDK_VERSION);
914 ok(!!d3d, "Failed to create a D3D object.\n");
915 if (!(device = create_device(d3d, window, window, TRUE)))
917 skip("Failed to create a D3D device, skipping tests.\n");
918 goto done;
921 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
922 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
923 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
925 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
926 IDirect3DDevice8_Release(device);
927 goto done;
930 /* NOTE: changing these values will not affect the tests with foggy vertex
931 * shader, as the values are hardcoded in the shader constant. */
932 start.f = 0.1f;
933 end.f = 0.9f;
935 /* Some of the tests seem to depend on the projection matrix explicitly
936 * being set to an identity matrix, even though that's the default.
937 * (AMD Radeon HD 6310, Windows 7) */
938 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
939 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
941 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
942 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
943 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
944 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
945 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
946 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
948 /* Set shader constant value */
949 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
950 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
951 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
952 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
954 /* Setup initial states: No lighting, fog on, fog color */
955 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
956 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
957 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
958 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
959 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
960 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
962 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
963 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
964 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
965 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
967 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
968 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
969 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
970 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
971 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
973 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
975 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
976 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
977 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
978 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
979 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
980 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
981 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
982 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
984 for(j = 0; j < 11; ++j)
986 /* Don't use the whole zrange to prevent rounding errors */
987 quad[0].position.z = 0.001f + j / 10.02f;
988 quad[1].position.z = 0.001f + j / 10.02f;
989 quad[2].position.z = 0.001f + j / 10.02f;
990 quad[3].position.z = 0.001f + j / 10.02f;
992 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
993 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
995 hr = IDirect3DDevice8_BeginScene(device);
996 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
998 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1001 hr = IDirect3DDevice8_EndScene(device);
1002 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1004 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1005 color = getPixelColor(device, 128, 240);
1006 ok(color_match(color, test_data[i].color[j], 13),
1007 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1008 test_data[i].vshader, test_data[i].pshader,
1009 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1011 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1015 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1016 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1017 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1018 refcount = IDirect3DDevice8_Release(device);
1019 ok(!refcount, "Device has %u references left.\n", refcount);
1020 done:
1021 IDirect3D8_Release(d3d);
1022 DestroyWindow(window);
1025 static void cnd_test(void)
1027 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1028 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1029 DWORD shader_11, shader_12, shader_13, shader_14;
1030 IDirect3DDevice8 *device;
1031 IDirect3D8 *d3d;
1032 ULONG refcount;
1033 D3DCAPS8 caps;
1034 DWORD color;
1035 HWND window;
1036 HRESULT hr;
1038 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1039 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1040 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1041 * in 1.x pixel shaders. */
1042 static const DWORD shader_code_11[] =
1044 0xffff0101, /* ps_1_1 */
1045 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1046 0x00000040, 0xb00f0000, /* texcoord t0 */
1047 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1048 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1049 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1050 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1051 0x0000ffff /* end */
1053 static const DWORD shader_code_12[] =
1055 0xffff0102, /* ps_1_2 */
1056 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1057 0x00000040, 0xb00f0000, /* texcoord t0 */
1058 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1059 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1060 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1061 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1062 0x0000ffff /* end */
1064 static const DWORD shader_code_13[] =
1066 0xffff0103, /* ps_1_3 */
1067 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1068 0x00000040, 0xb00f0000, /* texcoord t0 */
1069 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1070 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1071 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1072 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1073 0x0000ffff /* end */
1075 static const DWORD shader_code_14[] =
1077 0xffff0104, /* ps_1_3 */
1078 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1079 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1080 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1081 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1082 0x0000ffff /* end */
1085 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1086 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1087 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1088 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1089 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1090 * well enough.
1092 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1093 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1094 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1095 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1097 static const DWORD shader_code_11_coissue[] =
1099 0xffff0101, /* ps_1_1 */
1100 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1101 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1102 0x00000040, 0xb00f0000, /* texcoord t0 */
1103 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1104 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1105 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1106 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1107 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1108 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1109 0x0000ffff /* end */
1111 static const DWORD shader_code_11_coissue_2[] =
1113 0xffff0101, /* ps_1_1 */
1114 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1115 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1116 0x00000040, 0xb00f0000, /* texcoord t0 */
1117 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1118 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1119 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1120 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1121 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1122 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1123 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1124 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1125 0x0000ffff /* end */
1127 static const DWORD shader_code_12_coissue[] =
1129 0xffff0102, /* ps_1_2 */
1130 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1131 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1132 0x00000040, 0xb00f0000, /* texcoord t0 */
1133 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1134 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1135 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1136 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1137 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1138 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1139 0x0000ffff /* end */
1141 static const DWORD shader_code_12_coissue_2[] =
1143 0xffff0102, /* ps_1_2 */
1144 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1145 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1146 0x00000040, 0xb00f0000, /* texcoord t0 */
1147 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1148 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1149 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1150 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1151 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1152 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1153 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1154 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1155 0x0000ffff /* end */
1157 static const DWORD shader_code_13_coissue[] =
1159 0xffff0103, /* ps_1_3 */
1160 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1161 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1162 0x00000040, 0xb00f0000, /* texcoord t0 */
1163 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1164 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1165 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1166 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1167 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1168 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1169 0x0000ffff /* end */
1171 static const DWORD shader_code_13_coissue_2[] =
1173 0xffff0103, /* ps_1_3 */
1174 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1175 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1176 0x00000040, 0xb00f0000, /* texcoord t0 */
1177 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1178 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1179 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1180 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1181 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1182 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1183 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1184 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1185 0x0000ffff /* end */
1187 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1188 * texcrd result to cnd, it will compare against 0.5. */
1189 static const DWORD shader_code_14_coissue[] =
1191 0xffff0104, /* ps_1_4 */
1192 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1193 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1194 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1195 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1196 0x0000ffff /* end */
1198 static const DWORD shader_code_14_coissue_2[] =
1200 0xffff0104, /* ps_1_4 */
1201 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1202 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1203 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1204 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1205 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1206 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1207 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1208 0x0000ffff /* end */
1210 static const float quad1[] =
1212 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1213 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1214 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1215 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1217 static const float quad2[] =
1219 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1220 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1221 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1222 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1224 static const float quad3[] =
1226 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1227 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1228 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1229 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1231 static const float quad4[] =
1233 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1234 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1235 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1236 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1238 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1239 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1240 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1241 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1243 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1244 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1245 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1246 ok(!!d3d, "Failed to create a D3D object.\n");
1247 if (!(device = create_device(d3d, window, window, TRUE)))
1249 skip("Failed to create a D3D device, skipping tests.\n");
1250 goto done;
1253 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1254 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1255 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1257 skip("No ps_1_4 support, skipping tests.\n");
1258 IDirect3DDevice8_Release(device);
1259 goto done;
1262 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1263 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1265 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1266 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1267 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1268 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1269 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1270 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1271 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1272 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1273 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1274 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1275 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1276 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1277 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1278 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1279 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1280 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1281 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1282 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1283 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1284 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1285 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1286 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1287 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1288 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1290 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1291 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1292 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1293 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1294 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1295 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1297 hr = IDirect3DDevice8_BeginScene(device);
1298 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1300 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1301 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1302 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1303 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1305 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1306 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1307 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1308 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1310 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1311 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1312 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1313 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1315 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1316 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1317 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1318 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1320 hr = IDirect3DDevice8_EndScene(device);
1321 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1323 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1324 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1326 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1327 color = getPixelColor(device, 158, 118);
1328 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1329 color = getPixelColor(device, 162, 118);
1330 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1331 color = getPixelColor(device, 158, 122);
1332 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1333 color = getPixelColor(device, 162, 122);
1334 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1336 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1337 color = getPixelColor(device, 158, 358);
1338 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1339 color = getPixelColor(device, 162, 358);
1340 ok(color_match(color, 0x00000000, 1),
1341 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1342 color = getPixelColor(device, 158, 362);
1343 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1344 color = getPixelColor(device, 162, 362);
1345 ok(color_match(color, 0x00000000, 1),
1346 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1348 /* 1.2 shader */
1349 color = getPixelColor(device, 478, 358);
1350 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1351 color = getPixelColor(device, 482, 358);
1352 ok(color_match(color, 0x00000000, 1),
1353 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1354 color = getPixelColor(device, 478, 362);
1355 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1356 color = getPixelColor(device, 482, 362);
1357 ok(color_match(color, 0x00000000, 1),
1358 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1360 /* 1.3 shader */
1361 color = getPixelColor(device, 478, 118);
1362 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1363 color = getPixelColor(device, 482, 118);
1364 ok(color_match(color, 0x00000000, 1),
1365 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1366 color = getPixelColor(device, 478, 122);
1367 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1368 color = getPixelColor(device, 482, 122);
1369 ok(color_match(color, 0x00000000, 1),
1370 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1372 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1373 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1375 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1376 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1377 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1378 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1379 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1380 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1382 hr = IDirect3DDevice8_BeginScene(device);
1383 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1385 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1386 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1387 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1388 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1390 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1391 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1392 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1393 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1395 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1396 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1397 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1398 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1400 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
1401 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1402 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1403 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1405 hr = IDirect3DDevice8_EndScene(device);
1406 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1408 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1409 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1411 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1412 * that we swapped the values in c1 and c2 to make the other tests return some color
1414 color = getPixelColor(device, 158, 118);
1415 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1416 color = getPixelColor(device, 162, 118);
1417 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
1418 color = getPixelColor(device, 158, 122);
1419 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
1420 color = getPixelColor(device, 162, 122);
1421 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
1423 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1424 * (The Win7 nvidia driver always selects c2)
1426 color = getPixelColor(device, 158, 358);
1427 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1428 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
1429 color = getPixelColor(device, 162, 358);
1430 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1431 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
1432 color = getPixelColor(device, 158, 362);
1433 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1434 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
1435 color = getPixelColor(device, 162, 362);
1436 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1437 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
1439 /* 1.2 shader */
1440 color = getPixelColor(device, 478, 358);
1441 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1442 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
1443 color = getPixelColor(device, 482, 358);
1444 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1445 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
1446 color = getPixelColor(device, 478, 362);
1447 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1448 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
1449 color = getPixelColor(device, 482, 362);
1450 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1451 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
1453 /* 1.3 shader */
1454 color = getPixelColor(device, 478, 118);
1455 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1456 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
1457 color = getPixelColor(device, 482, 118);
1458 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1459 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
1460 color = getPixelColor(device, 478, 122);
1461 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1462 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
1463 color = getPixelColor(device, 482, 122);
1464 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1465 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
1467 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1468 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1470 /* Retest with the coissue flag on the alpha instruction instead. This
1471 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1472 * the same as coissue on .rgb. */
1473 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1474 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1476 hr = IDirect3DDevice8_BeginScene(device);
1477 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1479 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
1480 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1481 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1482 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1484 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
1485 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1486 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1487 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1489 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
1490 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1491 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1492 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1494 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
1495 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1496 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1497 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1499 hr = IDirect3DDevice8_EndScene(device);
1500 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1502 /* 1.4 shader */
1503 color = getPixelColor(device, 158, 118);
1504 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1505 color = getPixelColor(device, 162, 118);
1506 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
1507 color = getPixelColor(device, 158, 122);
1508 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1509 color = getPixelColor(device, 162, 122);
1510 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
1512 /* 1.1 shader */
1513 color = getPixelColor(device, 238, 358);
1514 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1515 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
1516 color = getPixelColor(device, 242, 358);
1517 ok(color_match(color, 0x00000000, 1),
1518 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
1519 color = getPixelColor(device, 238, 362);
1520 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1521 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
1522 color = getPixelColor(device, 242, 362);
1523 ok(color_match(color, 0x00000000, 1),
1524 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
1526 /* 1.2 shader */
1527 color = getPixelColor(device, 558, 358);
1528 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1529 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
1530 color = getPixelColor(device, 562, 358);
1531 ok(color_match(color, 0x00000000, 1),
1532 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
1533 color = getPixelColor(device, 558, 362);
1534 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1535 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
1536 color = getPixelColor(device, 562, 362);
1537 ok(color_match(color, 0x00000000, 1),
1538 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
1540 /* 1.3 shader */
1541 color = getPixelColor(device, 558, 118);
1542 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1543 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
1544 color = getPixelColor(device, 562, 118);
1545 ok(color_match(color, 0x00000000, 1),
1546 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
1547 color = getPixelColor(device, 558, 122);
1548 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1549 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
1550 color = getPixelColor(device, 562, 122);
1551 ok(color_match(color, 0x00000000, 1),
1552 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
1554 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1555 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1557 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
1558 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
1559 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
1560 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
1561 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
1562 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
1563 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
1564 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
1565 IDirect3DDevice8_DeletePixelShader(device, shader_14);
1566 IDirect3DDevice8_DeletePixelShader(device, shader_13);
1567 IDirect3DDevice8_DeletePixelShader(device, shader_12);
1568 IDirect3DDevice8_DeletePixelShader(device, shader_11);
1569 refcount = IDirect3DDevice8_Release(device);
1570 ok(!refcount, "Device has %u references left.\n", refcount);
1571 done:
1572 IDirect3D8_Release(d3d);
1573 DestroyWindow(window);
1576 static void z_range_test(void)
1578 IDirect3DDevice8 *device;
1579 IDirect3D8 *d3d;
1580 D3DCOLOR color;
1581 ULONG refcount;
1582 D3DCAPS8 caps;
1583 DWORD shader;
1584 HWND window;
1585 HRESULT hr;
1587 static const struct
1589 struct vec3 position;
1590 DWORD diffuse;
1592 quad[] =
1594 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
1595 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
1596 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
1597 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
1599 quad2[] =
1601 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
1602 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
1603 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
1604 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
1606 static const struct tvertex quad3[] =
1608 {640.0f, 240.0f, -1.1f, 1.0f, 0xffffff00},
1609 {640.0f, 480.0f, -1.1f, 1.0f, 0xffffff00},
1610 { 0.0f, 240.0f, 1.1f, 1.0f, 0xffffff00},
1611 { 0.0f, 480.0f, 1.1f, 1.0f, 0xffffff00},
1613 static const struct tvertex quad4[] =
1615 {640.0f, 240.0f, -1.1f, 1.0f, 0xff00ff00},
1616 {640.0f, 480.0f, -1.1f, 1.0f, 0xff00ff00},
1617 { 0.0f, 240.0f, 1.1f, 1.0f, 0xff00ff00},
1618 { 0.0f, 480.0f, 1.1f, 1.0f, 0xff00ff00},
1620 static const DWORD shader_code[] =
1622 0xfffe0101, /* vs_1_1 */
1623 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1624 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1625 0x0000ffff /* end */
1627 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
1628 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
1629 static const DWORD vertex_declaration[] =
1631 D3DVSD_STREAM(0),
1632 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
1633 D3DVSD_END()
1636 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1637 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1638 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1639 ok(!!d3d, "Failed to create a D3D object.\n");
1640 if (!(device = create_device(d3d, window, window, TRUE)))
1642 skip("Failed to create a D3D device, skipping tests.\n");
1643 goto done;
1646 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1647 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1649 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1650 * then call Present. Then clear the color buffer to make sure it has some defined content
1651 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1652 * by the depth value. */
1653 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
1654 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1655 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1656 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
1657 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
1658 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1660 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1661 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
1662 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1663 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
1664 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1665 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
1666 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1667 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
1668 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1669 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
1670 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1671 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
1673 hr = IDirect3DDevice8_BeginScene(device);
1674 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1676 /* Test the untransformed vertex path */
1677 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1678 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1679 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1680 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
1681 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1682 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1684 /* Test the transformed vertex path */
1685 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1686 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
1688 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
1689 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1690 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1691 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
1692 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
1693 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1695 hr = IDirect3DDevice8_EndScene(device);
1696 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1698 /* Do not test the exact corner pixels, but go pretty close to them */
1700 /* Clipped because z > 1.0 */
1701 color = getPixelColor(device, 28, 238);
1702 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1703 color = getPixelColor(device, 28, 241);
1704 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1705 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1706 else
1707 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1709 /* Not clipped, > z buffer clear value(0.75).
1711 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
1712 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
1713 * equal to a stored depth buffer value of 0.5. */
1714 color = getPixelColor(device, 31, 238);
1715 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1716 color = getPixelColor(device, 31, 241);
1717 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1718 color = getPixelColor(device, 100, 238);
1719 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
1720 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1721 color = getPixelColor(device, 100, 241);
1722 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
1723 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1725 /* Not clipped, < z buffer clear value */
1726 color = getPixelColor(device, 104, 238);
1727 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1728 color = getPixelColor(device, 104, 241);
1729 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1730 color = getPixelColor(device, 318, 238);
1731 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1732 color = getPixelColor(device, 318, 241);
1733 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1735 /* Clipped because z < 0.0 */
1736 color = getPixelColor(device, 321, 238);
1737 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1738 color = getPixelColor(device, 321, 241);
1739 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1740 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1741 else
1742 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1744 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1745 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
1747 /* Test the shader path */
1748 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
1750 skip("Vertex shaders not supported\n");
1751 IDirect3DDevice8_Release(device);
1752 goto done;
1754 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
1755 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
1757 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
1758 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1760 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1761 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1763 hr = IDirect3DDevice8_BeginScene(device);
1764 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1766 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
1767 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
1768 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1769 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1771 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1772 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
1773 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
1774 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
1775 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1776 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1778 hr = IDirect3DDevice8_EndScene(device);
1779 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1781 hr = IDirect3DDevice8_SetVertexShader(device, 0);
1782 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1784 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
1785 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
1787 /* Z < 1.0 */
1788 color = getPixelColor(device, 28, 238);
1789 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1791 /* 1.0 < z < 0.75 */
1792 color = getPixelColor(device, 31, 238);
1793 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1794 color = getPixelColor(device, 100, 238);
1795 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
1796 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1798 /* 0.75 < z < 0.0 */
1799 color = getPixelColor(device, 104, 238);
1800 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1801 color = getPixelColor(device, 318, 238);
1802 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1804 /* 0.0 < z */
1805 color = getPixelColor(device, 321, 238);
1806 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1808 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1809 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
1811 refcount = IDirect3DDevice8_Release(device);
1812 ok(!refcount, "Device has %u references left.\n", refcount);
1813 done:
1814 IDirect3D8_Release(d3d);
1815 DestroyWindow(window);
1818 static void test_scalar_instructions(void)
1820 IDirect3DDevice8 *device;
1821 IDirect3D8 *d3d;
1822 unsigned int i;
1823 D3DCOLOR color;
1824 ULONG refcount;
1825 D3DCAPS8 caps;
1826 DWORD shader;
1827 HWND window;
1828 HRESULT hr;
1830 static const struct vec3 quad[] =
1832 {-1.0f, -1.0f, 0.0f},
1833 {-1.0f, 1.0f, 0.0f},
1834 { 1.0f, -1.0f, 0.0f},
1835 { 1.0f, 1.0f, 0.0f},
1837 static const DWORD decl[] =
1839 D3DVSD_STREAM(0),
1840 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
1841 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
1842 D3DVSD_END()
1844 static const DWORD rcp_test[] =
1846 0xfffe0101, /* vs_1_1 */
1847 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1848 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1849 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1850 0x00303030, /* enough to make Windows happy. */
1851 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1852 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
1853 0x0000ffff /* END */
1855 static const DWORD rsq_test[] =
1857 0xfffe0101, /* vs_1_1 */
1858 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1859 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1860 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1861 0x00303030, /* enough to make Windows happy. */
1862 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1863 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
1864 0x0000ffff /* END */
1866 static const DWORD exp_test[] =
1868 0xfffe0101, /* vs_1_1 */
1869 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1870 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1871 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1872 0x00303030, /* enough to make Windows happy. */
1873 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1874 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
1875 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
1876 0x0000ffff, /* END */
1878 static const DWORD expp_test[] =
1880 0xfffe0101, /* vs_1_1 */
1881 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1882 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1883 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1884 0x00303030, /* enough to make Windows happy. */
1885 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1886 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
1887 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
1888 0x0000ffff, /* END */
1890 static const DWORD log_test[] =
1892 0xfffe0101, /* vs_1_1 */
1893 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1894 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1895 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1896 0x00303030, /* enough to make Windows happy. */
1897 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1898 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
1899 0x0000ffff, /* END */
1901 static const DWORD logp_test[] =
1903 0xfffe0101, /* vs_1_1 */
1904 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1905 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
1906 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1907 0x00303030, /* enough to make Windows happy. */
1908 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1909 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
1910 0x0000ffff, /* END */
1912 static const struct
1914 const char *name;
1915 const DWORD *byte_code;
1916 D3DCOLOR color;
1917 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
1918 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
1919 D3DCOLOR broken_color;
1921 test_data[] =
1923 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1924 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1925 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
1926 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
1927 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
1928 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1931 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1932 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1933 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1934 ok(!!d3d, "Failed to create a D3D object.\n");
1935 if (!(device = create_device(d3d, window, window, TRUE)))
1937 skip("Failed to create a D3D device, skipping tests.\n");
1938 goto done;
1941 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1942 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1943 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
1945 skip("No vs_1_1 support, skipping tests.\n");
1946 IDirect3DDevice8_Release(device);
1947 goto done;
1950 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1952 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
1953 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
1955 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
1956 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
1957 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1958 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
1960 hr = IDirect3DDevice8_BeginScene(device);
1961 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
1962 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1963 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
1964 hr = IDirect3DDevice8_EndScene(device);
1965 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
1967 color = getPixelColor(device, 320, 240);
1968 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
1969 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
1970 test_data[i].name, color, test_data[i].color);
1972 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1973 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
1975 hr = IDirect3DDevice8_SetVertexShader(device, 0);
1976 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
1977 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
1978 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
1981 refcount = IDirect3DDevice8_Release(device);
1982 ok(!refcount, "Device has %u references left.\n", refcount);
1983 done:
1984 IDirect3D8_Release(d3d);
1985 DestroyWindow(window);
1988 static void offscreen_test(void)
1990 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
1991 IDirect3DTexture8 *offscreenTexture;
1992 IDirect3DDevice8 *device;
1993 IDirect3D8 *d3d;
1994 D3DCOLOR color;
1995 ULONG refcount;
1996 HWND window;
1997 HRESULT hr;
1999 static const float quad[][5] =
2001 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2002 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2003 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2004 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2007 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2008 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2009 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2010 ok(!!d3d, "Failed to create a D3D object.\n");
2011 if (!(device = create_device(d3d, window, window, TRUE)))
2013 skip("Failed to create a D3D device, skipping tests.\n");
2014 goto done;
2017 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2018 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2020 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2021 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2022 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2023 if (!offscreenTexture)
2025 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2026 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2027 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2028 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2029 if (!offscreenTexture)
2031 skip("Cannot create an offscreen render target.\n");
2032 IDirect3DDevice8_Release(device);
2033 goto done;
2037 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2038 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2040 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2041 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2043 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2044 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2046 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2047 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2049 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2050 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2051 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2052 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2053 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2054 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2055 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2056 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2057 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2058 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2060 hr = IDirect3DDevice8_BeginScene(device);
2061 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2063 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2064 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2065 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2066 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2068 /* Draw without textures - Should result in a white quad. */
2069 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2070 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2072 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2073 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2074 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2075 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2077 /* This time with the texture .*/
2078 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2079 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2081 hr = IDirect3DDevice8_EndScene(device);
2082 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2084 /* Center quad - should be white */
2085 color = getPixelColor(device, 320, 240);
2086 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2087 /* Some quad in the cleared part of the texture */
2088 color = getPixelColor(device, 170, 240);
2089 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2090 /* Part of the originally cleared back buffer */
2091 color = getPixelColor(device, 10, 10);
2092 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2093 color = getPixelColor(device, 10, 470);
2094 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2096 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2098 IDirect3DSurface8_Release(backbuffer);
2099 IDirect3DTexture8_Release(offscreenTexture);
2100 IDirect3DSurface8_Release(offscreen);
2101 IDirect3DSurface8_Release(depthstencil);
2102 refcount = IDirect3DDevice8_Release(device);
2103 ok(!refcount, "Device has %u references left.\n", refcount);
2104 done:
2105 IDirect3D8_Release(d3d);
2106 DestroyWindow(window);
2109 static void alpha_test(void)
2111 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2112 IDirect3DTexture8 *offscreenTexture;
2113 IDirect3DDevice8 *device;
2114 IDirect3D8 *d3d;
2115 D3DCOLOR color;
2116 ULONG refcount;
2117 HWND window;
2118 HRESULT hr;
2120 static const struct
2122 struct vec3 position;
2123 DWORD diffuse;
2125 quad1[] =
2127 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2128 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2129 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2130 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2132 quad2[] =
2134 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2135 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2136 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2137 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2139 static const float composite_quad[][5] =
2141 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2142 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2143 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2144 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2147 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2148 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2149 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2150 ok(!!d3d, "Failed to create a D3D object.\n");
2151 if (!(device = create_device(d3d, window, window, TRUE)))
2153 skip("Failed to create a D3D device, skipping tests.\n");
2154 goto done;
2157 /* Clear the render target with alpha = 0.5 */
2158 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2159 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2161 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2162 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2163 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2165 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2166 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2167 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2168 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2170 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2171 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2173 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2174 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2176 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2177 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2178 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2179 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2180 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2181 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2182 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2183 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2184 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2185 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2187 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2188 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2189 hr = IDirect3DDevice8_BeginScene(device);
2190 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2192 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2193 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2194 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2195 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2196 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2197 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2198 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2200 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2201 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2202 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2203 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2204 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2205 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2207 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2208 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2209 * "don't work" on render targets without alpha channel, they give
2210 * essentially ZERO and ONE blend factors. */
2211 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2212 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2213 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2214 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2216 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2217 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2218 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2219 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2220 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2221 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2223 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2224 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2225 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2226 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2227 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2228 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2230 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2231 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2233 /* Render the offscreen texture onto the frame buffer to be able to
2234 * compare it regularly. Disable alpha blending for the final
2235 * composition. */
2236 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2237 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2238 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2239 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2241 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2242 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2243 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2244 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2246 hr = IDirect3DDevice8_EndScene(device);
2247 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2249 color = getPixelColor(device, 160, 360);
2250 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2251 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2253 color = getPixelColor(device, 160, 120);
2254 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2255 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2257 color = getPixelColor(device, 480, 360);
2258 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2259 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2261 color = getPixelColor(device, 480, 120);
2262 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2263 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2265 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2267 IDirect3DSurface8_Release(backbuffer);
2268 IDirect3DTexture8_Release(offscreenTexture);
2269 IDirect3DSurface8_Release(offscreen);
2270 IDirect3DSurface8_Release(depthstencil);
2271 refcount = IDirect3DDevice8_Release(device);
2272 ok(!refcount, "Device has %u references left.\n", refcount);
2273 done:
2274 IDirect3D8_Release(d3d);
2275 DestroyWindow(window);
2278 static void p8_texture_test(void)
2280 IDirect3DTexture8 *texture, *texture2;
2281 IDirect3DDevice8 *device;
2282 PALETTEENTRY table[256];
2283 unsigned char *data;
2284 D3DLOCKED_RECT lr;
2285 IDirect3D8 *d3d;
2286 D3DCOLOR color;
2287 ULONG refcount;
2288 D3DCAPS8 caps;
2289 HWND window;
2290 HRESULT hr;
2291 UINT i;
2293 static const float quad[] =
2295 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2296 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2297 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2298 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2300 static const float quad2[] =
2302 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2303 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2304 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2305 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2308 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2309 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2310 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2311 ok(!!d3d, "Failed to create a D3D object.\n");
2312 if (!(device = create_device(d3d, window, window, TRUE)))
2314 skip("Failed to create a D3D device, skipping tests.\n");
2315 goto done;
2318 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2319 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2321 skip("D3DFMT_P8 textures not supported.\n");
2322 IDirect3DDevice8_Release(device);
2323 goto done;
2326 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2327 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2328 memset(&lr, 0, sizeof(lr));
2329 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2330 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2331 data = lr.pBits;
2332 *data = 1;
2333 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2334 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2336 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2337 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2338 memset(&lr, 0, sizeof(lr));
2339 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2340 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2341 data = lr.pBits;
2342 *data = 1;
2343 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2344 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2346 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2347 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2349 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2350 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2351 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2352 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2354 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2355 alpha of every entry is set to 1.0, which MS says is required when there's no
2356 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2357 for (i = 0; i < 256; i++) {
2358 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2359 table[i].peFlags = 0xff;
2361 table[1].peRed = 0xff;
2362 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2363 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2365 table[1].peRed = 0;
2366 table[1].peBlue = 0xff;
2367 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2368 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2370 hr = IDirect3DDevice8_BeginScene(device);
2371 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2373 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2374 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2375 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2376 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2377 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2378 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2379 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2380 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2381 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2382 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2383 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2386 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2387 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2388 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2389 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2391 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2392 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2393 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2394 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2396 hr = IDirect3DDevice8_EndScene(device);
2397 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2399 color = getPixelColor(device, 32, 32);
2400 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
2401 color = getPixelColor(device, 32, 320);
2402 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2404 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2405 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2407 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2408 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2410 hr = IDirect3DDevice8_BeginScene(device);
2411 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2412 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2413 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2414 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2415 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2416 hr = IDirect3DDevice8_EndScene(device);
2417 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2419 color = getPixelColor(device, 32, 32);
2420 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2422 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2423 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2425 /* Test palettes with alpha */
2426 IDirect3DDevice8_GetDeviceCaps(device, &caps);
2427 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
2428 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2429 } else {
2430 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2431 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2433 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2434 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2436 for (i = 0; i < 256; i++) {
2437 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2438 table[i].peFlags = 0xff;
2440 table[1].peRed = 0xff;
2441 table[1].peFlags = 0x80;
2442 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2443 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2445 table[1].peRed = 0;
2446 table[1].peBlue = 0xff;
2447 table[1].peFlags = 0x80;
2448 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2449 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2451 hr = IDirect3DDevice8_BeginScene(device);
2452 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2454 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2455 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2456 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2457 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2458 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2459 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2461 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2462 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2463 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2466 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2467 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2468 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2469 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2471 hr = IDirect3DDevice8_EndScene(device);
2472 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2474 color = getPixelColor(device, 32, 32);
2475 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
2476 color = getPixelColor(device, 32, 320);
2477 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
2479 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2480 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2483 IDirect3DTexture8_Release(texture);
2484 IDirect3DTexture8_Release(texture2);
2485 refcount = IDirect3DDevice8_Release(device);
2486 ok(!refcount, "Device has %u references left.\n", refcount);
2487 done:
2488 IDirect3D8_Release(d3d);
2489 DestroyWindow(window);
2492 static void texop_test(void)
2494 IDirect3DTexture8 *texture;
2495 D3DLOCKED_RECT locked_rect;
2496 IDirect3DDevice8 *device;
2497 IDirect3D8 *d3d;
2498 unsigned int i;
2499 D3DCOLOR color;
2500 ULONG refcount;
2501 D3DCAPS8 caps;
2502 HWND window;
2503 HRESULT hr;
2505 static const struct {
2506 float x, y, z;
2507 D3DCOLOR diffuse;
2508 float s, t;
2509 } quad[] = {
2510 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
2511 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
2512 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
2513 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
2516 static const struct {
2517 D3DTEXTUREOP op;
2518 const char *name;
2519 DWORD caps_flag;
2520 D3DCOLOR result;
2521 } test_data[] = {
2522 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2523 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2524 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2525 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2526 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2527 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2529 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2530 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2532 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2533 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2534 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2535 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2536 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2537 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2538 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2539 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2540 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2541 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2542 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2543 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2544 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2545 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2546 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2549 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2550 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2551 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2552 ok(!!d3d, "Failed to create a D3D object.\n");
2553 if (!(device = create_device(d3d, window, window, TRUE)))
2555 skip("Failed to create a D3D device, skipping tests.\n");
2556 goto done;
2559 memset(&caps, 0, sizeof(caps));
2560 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2561 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
2563 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
2564 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
2566 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
2567 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
2568 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
2569 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
2570 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
2571 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2572 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
2573 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2574 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
2576 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
2577 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2578 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2579 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2580 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
2581 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2583 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
2584 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2586 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2587 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
2588 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
2589 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
2590 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
2591 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
2593 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
2594 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
2596 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
2598 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
2600 skip("tex operation %s not supported\n", test_data[i].name);
2601 continue;
2604 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
2605 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
2607 hr = IDirect3DDevice8_BeginScene(device);
2608 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
2610 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2611 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
2613 hr = IDirect3DDevice8_EndScene(device);
2614 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
2616 color = getPixelColor(device, 320, 240);
2617 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
2618 test_data[i].name, color, test_data[i].result);
2620 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2621 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
2623 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
2624 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
2627 IDirect3DTexture8_Release(texture);
2628 refcount = IDirect3DDevice8_Release(device);
2629 ok(!refcount, "Device has %u references left.\n", refcount);
2630 done:
2631 IDirect3D8_Release(d3d);
2632 DestroyWindow(window);
2635 /* This test tests depth clamping / clipping behaviour:
2636 * - With software vertex processing, depth values are clamped to the
2637 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2638 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2639 * same as regular vertices here.
2640 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2641 * Normal vertices are always clipped. Pretransformed vertices are
2642 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2643 * - The viewport's MinZ/MaxZ is irrelevant for this.
2645 static void depth_clamp_test(void)
2647 IDirect3DDevice8 *device;
2648 D3DVIEWPORT8 vp;
2649 IDirect3D8 *d3d;
2650 D3DCOLOR color;
2651 ULONG refcount;
2652 D3DCAPS8 caps;
2653 HWND window;
2654 HRESULT hr;
2656 static const struct tvertex quad1[] =
2658 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2659 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2660 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2661 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2663 static const struct tvertex quad2[] =
2665 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2666 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2667 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2668 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2670 static const struct tvertex quad3[] =
2672 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2673 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2674 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2675 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2677 static const struct tvertex quad4[] =
2679 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2680 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2681 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2682 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2684 static const struct
2686 struct vec3 position;
2687 DWORD diffuse;
2689 quad5[] =
2691 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
2692 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
2693 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
2694 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
2696 quad6[] =
2698 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
2699 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
2700 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
2701 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
2704 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2705 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2706 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2707 ok(!!d3d, "Failed to create a D3D object.\n");
2708 if (!(device = create_device(d3d, window, window, TRUE)))
2710 skip("Failed to create a D3D device, skipping tests.\n");
2711 goto done;
2714 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2715 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2717 vp.X = 0;
2718 vp.Y = 0;
2719 vp.Width = 640;
2720 vp.Height = 480;
2721 vp.MinZ = 0.0;
2722 vp.MaxZ = 7.5;
2724 hr = IDirect3DDevice8_SetViewport(device, &vp);
2725 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2727 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
2728 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2730 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2731 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2732 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2733 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2734 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2735 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2736 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2737 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2739 hr = IDirect3DDevice8_BeginScene(device);
2740 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2742 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2743 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
2745 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
2746 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2747 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
2748 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2750 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2751 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2753 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
2754 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2755 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
2756 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2758 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2759 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2760 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2761 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2763 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
2764 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2766 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2767 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2769 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
2770 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2772 hr = IDirect3DDevice8_EndScene(device);
2773 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2775 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2777 color = getPixelColor(device, 75, 75);
2778 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2779 color = getPixelColor(device, 150, 150);
2780 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2781 color = getPixelColor(device, 320, 240);
2782 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2783 color = getPixelColor(device, 320, 330);
2784 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2785 color = getPixelColor(device, 320, 330);
2786 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2788 else
2790 color = getPixelColor(device, 75, 75);
2791 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
2792 color = getPixelColor(device, 150, 150);
2793 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
2794 color = getPixelColor(device, 320, 240);
2795 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
2796 color = getPixelColor(device, 320, 330);
2797 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
2798 color = getPixelColor(device, 320, 330);
2799 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
2802 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2803 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2805 refcount = IDirect3DDevice8_Release(device);
2806 ok(!refcount, "Device has %u references left.\n", refcount);
2807 done:
2808 IDirect3D8_Release(d3d);
2809 DestroyWindow(window);
2812 static void depth_buffer_test(void)
2814 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
2815 IDirect3DSurface8 *depth_stencil;
2816 IDirect3DDevice8 *device;
2817 unsigned int i, j;
2818 D3DVIEWPORT8 vp;
2819 IDirect3D8 *d3d;
2820 D3DCOLOR color;
2821 ULONG refcount;
2822 HWND window;
2823 HRESULT hr;
2825 static const struct
2827 struct vec3 position;
2828 DWORD diffuse;
2830 quad1[] =
2832 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
2833 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
2834 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
2835 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
2837 quad2[] =
2839 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
2840 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
2841 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
2842 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
2844 quad3[] =
2846 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
2847 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
2848 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
2849 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
2851 static const DWORD expected_colors[4][4] =
2853 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
2854 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
2855 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
2856 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
2859 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2860 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2861 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2862 ok(!!d3d, "Failed to create a D3D object.\n");
2863 if (!(device = create_device(d3d, window, window, TRUE)))
2865 skip("Failed to create a D3D device, skipping tests.\n");
2866 goto done;
2869 vp.X = 0;
2870 vp.Y = 0;
2871 vp.Width = 640;
2872 vp.Height = 480;
2873 vp.MinZ = 0.0;
2874 vp.MaxZ = 1.0;
2876 hr = IDirect3DDevice8_SetViewport(device, &vp);
2877 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2879 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2880 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2881 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2882 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2883 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2884 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2885 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2886 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2887 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2888 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2890 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
2891 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2892 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
2893 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2894 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
2895 D3DMULTISAMPLE_NONE, FALSE, &rt1);
2896 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2897 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
2898 D3DMULTISAMPLE_NONE, FALSE, &rt2);
2899 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2900 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2901 D3DMULTISAMPLE_NONE, FALSE, &rt3);
2902 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2904 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
2905 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
2907 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2909 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2910 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2911 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2912 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2914 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
2915 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2916 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
2917 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2919 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
2920 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2921 hr = IDirect3DDevice8_BeginScene(device);
2922 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2923 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
2924 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2925 hr = IDirect3DDevice8_EndScene(device);
2926 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2928 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2929 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2931 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2932 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2934 hr = IDirect3DDevice8_BeginScene(device);
2935 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2936 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
2937 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2938 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
2939 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2940 hr = IDirect3DDevice8_EndScene(device);
2941 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2943 for (i = 0; i < 4; ++i)
2945 for (j = 0; j < 4; ++j)
2947 unsigned int x = 80 * ((2 * j) + 1);
2948 unsigned int y = 60 * ((2 * i) + 1);
2949 color = getPixelColor(device, x, y);
2950 ok(color_match(color, expected_colors[i][j], 0),
2951 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
2955 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2956 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2958 IDirect3DSurface8_Release(depth_stencil);
2959 IDirect3DSurface8_Release(backbuffer);
2960 IDirect3DSurface8_Release(rt3);
2961 IDirect3DSurface8_Release(rt2);
2962 IDirect3DSurface8_Release(rt1);
2963 refcount = IDirect3DDevice8_Release(device);
2964 ok(!refcount, "Device has %u references left.\n", refcount);
2965 done:
2966 IDirect3D8_Release(d3d);
2967 DestroyWindow(window);
2970 /* Test that partial depth copies work the way they're supposed to. The clear
2971 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2972 * the following draw should only copy back the part that was modified. */
2973 static void depth_buffer2_test(void)
2975 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
2976 IDirect3DSurface8 *depth_stencil;
2977 IDirect3DDevice8 *device;
2978 unsigned int i, j;
2979 D3DVIEWPORT8 vp;
2980 IDirect3D8 *d3d;
2981 D3DCOLOR color;
2982 ULONG refcount;
2983 HWND window;
2984 HRESULT hr;
2986 static const struct
2988 struct vec3 position;
2989 DWORD diffuse;
2991 quad[] =
2993 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
2994 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
2995 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
2996 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
2999 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3000 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3001 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3002 ok(!!d3d, "Failed to create a D3D object.\n");
3003 if (!(device = create_device(d3d, window, window, TRUE)))
3005 skip("Failed to create a D3D device, skipping tests.\n");
3006 goto done;
3009 vp.X = 0;
3010 vp.Y = 0;
3011 vp.Width = 640;
3012 vp.Height = 480;
3013 vp.MinZ = 0.0;
3014 vp.MaxZ = 1.0;
3016 hr = IDirect3DDevice8_SetViewport(device, &vp);
3017 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3019 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3020 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3021 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3022 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3023 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3024 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3025 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3027 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3028 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3030 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3031 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3032 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3033 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3034 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3035 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3036 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3037 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3038 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3039 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3041 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3042 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3043 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3044 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3046 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3047 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3048 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3049 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3051 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3052 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3053 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3054 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3056 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3057 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3059 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3060 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3062 hr = IDirect3DDevice8_BeginScene(device);
3063 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3064 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3065 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3066 hr = IDirect3DDevice8_EndScene(device);
3067 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3069 for (i = 0; i < 4; ++i)
3071 for (j = 0; j < 4; ++j)
3073 unsigned int x = 80 * ((2 * j) + 1);
3074 unsigned int y = 60 * ((2 * i) + 1);
3075 color = getPixelColor(device, x, y);
3076 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3077 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3081 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3082 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3084 IDirect3DSurface8_Release(depth_stencil);
3085 IDirect3DSurface8_Release(backbuffer);
3086 IDirect3DSurface8_Release(rt2);
3087 IDirect3DSurface8_Release(rt1);
3088 refcount = IDirect3DDevice8_Release(device);
3089 ok(!refcount, "Device has %u references left.\n", refcount);
3090 done:
3091 IDirect3D8_Release(d3d);
3092 DestroyWindow(window);
3095 static void intz_test(void)
3097 IDirect3DSurface8 *original_rt, *rt;
3098 IDirect3DTexture8 *texture;
3099 IDirect3DDevice8 *device;
3100 IDirect3DSurface8 *ds;
3101 IDirect3D8 *d3d;
3102 ULONG refcount;
3103 D3DCAPS8 caps;
3104 HWND window;
3105 HRESULT hr;
3106 DWORD ps;
3107 UINT i;
3109 static const DWORD ps_code[] =
3111 0xffff0101, /* ps_1_1 */
3112 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3113 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3114 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3115 0x00000042, 0xb00f0000, /* tex t0 */
3116 0x00000042, 0xb00f0001, /* tex t1 */
3117 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3118 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3119 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3120 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3121 0x0000ffff, /* end */
3123 static const struct
3125 float x, y, z;
3126 float s0, t0, p0;
3127 float s1, t1, p1, q1;
3129 quad[] =
3131 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3132 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3133 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3134 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3136 half_quad_1[] =
3138 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3139 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3140 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3141 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3143 half_quad_2[] =
3145 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3146 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3147 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3148 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3150 static const struct
3152 UINT x, y;
3153 D3DCOLOR color;
3155 expected_colors[] =
3157 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3158 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3159 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3160 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3161 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3162 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3163 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3164 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3167 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3168 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3169 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3170 ok(!!d3d, "Failed to create a D3D object.\n");
3171 if (!(device = create_device(d3d, window, window, TRUE)))
3173 skip("Failed to create a D3D device, skipping tests.\n");
3174 goto done;
3177 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3178 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3179 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3181 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3182 IDirect3DDevice8_Release(device);
3183 goto done;
3185 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3187 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3188 IDirect3DDevice8_Release(device);
3189 goto done;
3192 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3193 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3195 skip("No INTZ support, skipping INTZ test.\n");
3196 IDirect3DDevice8_Release(device);
3197 goto done;
3200 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3201 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3203 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3204 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3205 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3206 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3207 D3DMULTISAMPLE_NONE, FALSE, &rt);
3208 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3209 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3210 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3212 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3213 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3214 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3215 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3216 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3217 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3218 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3219 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3220 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3221 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3222 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3224 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3225 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3226 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3227 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3228 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3229 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3230 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3231 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3233 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3234 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3235 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3236 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3237 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3238 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3239 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3240 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3241 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3242 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3243 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3244 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3245 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3247 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3248 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3250 /* Render offscreen, using the INTZ texture as depth buffer */
3251 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3252 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3253 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3254 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3256 /* Setup the depth/stencil surface. */
3257 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3258 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3260 hr = IDirect3DDevice8_BeginScene(device);
3261 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3262 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3263 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3264 hr = IDirect3DDevice8_EndScene(device);
3265 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3267 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3268 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3269 IDirect3DSurface8_Release(ds);
3270 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3271 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3272 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3273 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3274 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3275 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3277 /* Read the depth values back. */
3278 hr = IDirect3DDevice8_BeginScene(device);
3279 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3280 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3281 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3282 hr = IDirect3DDevice8_EndScene(device);
3283 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3285 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3287 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3288 ok(color_match(color, expected_colors[i].color, 1),
3289 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3290 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3293 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3294 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3296 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3297 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3298 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3299 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3300 IDirect3DTexture8_Release(texture);
3302 /* Render onscreen while using the INTZ texture as depth buffer */
3303 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3304 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3305 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3306 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3307 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3308 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3309 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3310 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3311 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3313 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3314 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3316 hr = IDirect3DDevice8_BeginScene(device);
3317 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3318 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3319 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3320 hr = IDirect3DDevice8_EndScene(device);
3321 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3323 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3324 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3325 IDirect3DSurface8_Release(ds);
3326 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3327 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3328 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3329 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3330 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3331 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3333 /* Read the depth values back. */
3334 hr = IDirect3DDevice8_BeginScene(device);
3335 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3336 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3337 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3338 hr = IDirect3DDevice8_EndScene(device);
3339 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3341 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3343 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3344 ok(color_match(color, expected_colors[i].color, 1),
3345 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3346 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3349 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3350 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3352 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3353 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3354 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3355 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3356 IDirect3DTexture8_Release(texture);
3358 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3359 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3360 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3361 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3362 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3363 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3364 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3365 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3366 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3367 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3369 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3370 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3372 hr = IDirect3DDevice8_BeginScene(device);
3373 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3374 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3375 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3376 hr = IDirect3DDevice8_EndScene(device);
3377 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3379 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3380 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3382 hr = IDirect3DDevice8_BeginScene(device);
3383 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3384 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3386 hr = IDirect3DDevice8_EndScene(device);
3387 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3389 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3390 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3391 IDirect3DSurface8_Release(ds);
3392 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3393 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3394 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3395 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3396 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3397 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3399 /* Read the depth values back. */
3400 hr = IDirect3DDevice8_BeginScene(device);
3401 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3402 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3403 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3404 hr = IDirect3DDevice8_EndScene(device);
3405 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3407 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3409 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3410 ok(color_match(color, expected_colors[i].color, 1),
3411 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3412 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3415 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3416 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3418 IDirect3DTexture8_Release(texture);
3419 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3420 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3421 IDirect3DSurface8_Release(original_rt);
3422 IDirect3DSurface8_Release(rt);
3423 refcount = IDirect3DDevice8_Release(device);
3424 ok(!refcount, "Device has %u references left.\n", refcount);
3425 done:
3426 IDirect3D8_Release(d3d);
3427 DestroyWindow(window);
3430 static void shadow_test(void)
3432 IDirect3DSurface8 *original_rt, *rt;
3433 IDirect3DDevice8 *device;
3434 IDirect3D8 *d3d;
3435 ULONG refcount;
3436 D3DCAPS8 caps;
3437 HWND window;
3438 HRESULT hr;
3439 DWORD ps;
3440 UINT i;
3442 static const DWORD ps_code[] =
3444 0xffff0101, /* ps_1_1 */
3445 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3446 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3447 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3448 0x00000042, 0xb00f0000, /* tex t0 */
3449 0x00000042, 0xb00f0001, /* tex t1 */
3450 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3451 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3452 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3453 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3454 0x0000ffff, /* end */
3456 static const struct
3458 D3DFORMAT format;
3459 const char *name;
3461 formats[] =
3463 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
3464 {D3DFMT_D32, "D3DFMT_D32"},
3465 {D3DFMT_D15S1, "D3DFMT_D15S1"},
3466 {D3DFMT_D24S8, "D3DFMT_D24S8"},
3467 {D3DFMT_D24X8, "D3DFMT_D24X8"},
3468 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
3469 {D3DFMT_D16, "D3DFMT_D16"},
3471 static const struct
3473 float x, y, z;
3474 float s0, t0, p0;
3475 float s1, t1, p1, q1;
3477 quad[] =
3479 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
3480 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
3481 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
3482 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
3484 static const struct
3486 UINT x, y;
3487 D3DCOLOR color;
3489 expected_colors[] =
3491 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3492 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3493 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3494 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3495 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3496 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3497 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3498 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3501 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3502 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3503 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3504 ok(!!d3d, "Failed to create a D3D object.\n");
3505 if (!(device = create_device(d3d, window, window, TRUE)))
3507 skip("Failed to create a D3D device, skipping tests.\n");
3508 goto done;
3511 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3512 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3513 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3515 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3516 IDirect3DDevice8_Release(device);
3517 goto done;
3520 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3521 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3523 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
3524 D3DMULTISAMPLE_NONE, FALSE, &rt);
3525 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3526 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3527 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3529 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3530 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3531 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3532 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3533 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3534 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3535 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3536 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3537 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3538 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3539 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3541 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3542 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3543 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3544 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3545 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3546 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3547 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3548 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3550 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3551 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3552 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3553 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3554 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3555 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3556 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3557 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3558 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3559 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3560 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3561 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3562 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3564 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
3566 D3DFORMAT format = formats[i].format;
3567 IDirect3DTexture8 *texture;
3568 IDirect3DSurface8 *ds;
3569 unsigned int j;
3571 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3572 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
3573 continue;
3575 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
3576 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
3577 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3579 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3580 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3582 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3583 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3585 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3586 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3588 /* Setup the depth/stencil surface. */
3589 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3590 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3592 hr = IDirect3DDevice8_BeginScene(device);
3593 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3594 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3595 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3596 hr = IDirect3DDevice8_EndScene(device);
3597 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3599 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3600 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3601 IDirect3DSurface8_Release(ds);
3603 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3604 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3605 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3606 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3608 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3609 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3611 /* Do the actual shadow mapping. */
3612 hr = IDirect3DDevice8_BeginScene(device);
3613 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3614 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3615 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3616 hr = IDirect3DDevice8_EndScene(device);
3617 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3619 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3620 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3621 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3622 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3623 IDirect3DTexture8_Release(texture);
3625 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
3627 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
3628 ok(color_match(color, expected_colors[j].color, 0),
3629 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
3630 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
3631 formats[i].name, color);
3634 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3635 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3638 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3639 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3640 IDirect3DSurface8_Release(original_rt);
3641 IDirect3DSurface8_Release(rt);
3642 refcount = IDirect3DDevice8_Release(device);
3643 ok(!refcount, "Device has %u references left.\n", refcount);
3644 done:
3645 IDirect3D8_Release(d3d);
3646 DestroyWindow(window);
3649 static void multisample_copy_rects_test(void)
3651 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
3652 RECT src_rect = {64, 64, 128, 128};
3653 POINT dst_point = {96, 96};
3654 D3DLOCKED_RECT locked_rect;
3655 IDirect3DDevice8 *device;
3656 IDirect3D8 *d3d;
3657 D3DCOLOR color;
3658 ULONG refcount;
3659 HWND window;
3660 HRESULT hr;
3662 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3663 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3664 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3665 ok(!!d3d, "Failed to create a D3D object.\n");
3666 if (!(device = create_device(d3d, window, window, TRUE)))
3668 skip("Failed to create a D3D device, skipping tests.\n");
3669 goto done;
3672 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
3673 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
3675 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
3676 IDirect3DDevice8_Release(device);
3677 goto done;
3680 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
3681 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
3682 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3683 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
3684 D3DMULTISAMPLE_2_SAMPLES, &ds);
3685 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
3686 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
3687 D3DMULTISAMPLE_NONE, &ds_plain);
3688 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
3689 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
3690 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
3692 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3693 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3695 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
3696 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3698 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
3699 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
3701 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
3702 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
3704 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3705 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3707 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
3708 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
3710 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
3711 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
3713 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
3714 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3716 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
3717 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3719 hr = IDirect3DSurface8_UnlockRect(readback);
3720 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
3722 IDirect3DSurface8_Release(readback);
3723 IDirect3DSurface8_Release(ds_plain);
3724 IDirect3DSurface8_Release(ds);
3725 IDirect3DSurface8_Release(rt);
3726 refcount = IDirect3DDevice8_Release(device);
3727 ok(!refcount, "Device has %u references left.\n", refcount);
3728 done:
3729 IDirect3D8_Release(d3d);
3730 DestroyWindow(window);
3733 static void resz_test(void)
3735 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
3736 IDirect3DTexture8 *texture;
3737 IDirect3DDevice8 *device;
3738 IDirect3D8 *d3d;
3739 DWORD ps, value;
3740 unsigned int i;
3741 ULONG refcount;
3742 D3DCAPS8 caps;
3743 HWND window;
3744 HRESULT hr;
3746 static const DWORD ps_code[] =
3748 0xffff0101, /* ps_1_1 */
3749 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3750 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3751 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3752 0x00000042, 0xb00f0000, /* tex t0 */
3753 0x00000042, 0xb00f0001, /* tex t1 */
3754 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3755 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3756 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3757 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3758 0x0000ffff, /* end */
3760 static const struct
3762 float x, y, z;
3763 float s0, t0, p0;
3764 float s1, t1, p1, q1;
3766 quad[] =
3768 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3769 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3770 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3771 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3773 static const struct
3775 UINT x, y;
3776 D3DCOLOR color;
3778 expected_colors[] =
3780 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3781 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3782 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3783 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3784 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3785 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3786 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3787 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3790 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3791 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3792 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3793 ok(!!d3d, "Failed to create a D3D object.\n");
3794 if (!(device = create_device(d3d, window, window, TRUE)))
3796 skip("Failed to create a D3D device, skipping tests.\n");
3797 goto done;
3800 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
3801 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
3803 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
3804 IDirect3DDevice8_Release(device);
3805 goto done;
3807 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
3808 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
3810 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
3811 IDirect3DDevice8_Release(device);
3812 goto done;
3814 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3815 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3817 skip("No INTZ support, skipping RESZ test.\n");
3818 IDirect3DDevice8_Release(device);
3819 goto done;
3821 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3822 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
3824 skip("No RESZ support, skipping RESZ test.\n");
3825 IDirect3DDevice8_Release(device);
3826 goto done;
3829 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3830 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3831 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3833 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3834 IDirect3DDevice8_Release(device);
3835 goto done;
3838 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3839 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
3840 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
3841 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
3843 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3844 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
3845 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3846 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
3847 D3DMULTISAMPLE_2_SAMPLES, &ds);
3849 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3850 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3851 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3852 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
3853 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3855 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
3856 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3857 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
3858 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3860 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3861 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3862 IDirect3DSurface8_Release(intz_ds);
3863 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3864 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3866 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3867 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3868 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3869 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3870 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3871 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3872 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3873 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3874 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3875 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3876 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3878 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3879 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3880 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3881 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3882 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3883 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3884 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3885 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3887 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3888 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3889 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3890 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3891 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3892 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3893 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3894 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3895 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3896 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3897 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3898 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3899 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3901 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
3902 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
3903 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3905 hr = IDirect3DDevice8_BeginScene(device);
3906 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3907 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3908 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3910 /* The destination depth texture has to be bound to sampler 0 */
3911 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3912 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3914 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
3915 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3916 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3917 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3918 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3919 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
3920 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3921 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3922 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3923 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
3924 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3925 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3926 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3927 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
3928 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3930 /* The actual multisampled depth buffer resolve happens here */
3931 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3932 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3933 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
3934 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
3936 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3937 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3938 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3939 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3940 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3941 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3943 /* Read the depth values back. */
3944 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3946 hr = IDirect3DDevice8_EndScene(device);
3947 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3949 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3951 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3952 ok(color_match(color, expected_colors[i].color, 1),
3953 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3954 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3957 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3958 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3960 /* Test edge cases - try with no texture at all */
3961 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3962 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3963 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3964 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3965 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3966 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3968 hr = IDirect3DDevice8_BeginScene(device);
3969 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3970 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3971 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3972 hr = IDirect3DDevice8_EndScene(device);
3973 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3975 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3976 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3978 /* With a non-multisampled depth buffer */
3979 IDirect3DSurface8_Release(ds);
3980 IDirect3DSurface8_Release(rt);
3981 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
3982 D3DMULTISAMPLE_NONE, &ds);
3984 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3985 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3986 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3987 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3989 hr = IDirect3DDevice8_BeginScene(device);
3990 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3991 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3992 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3993 hr = IDirect3DDevice8_EndScene(device);
3994 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3996 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3997 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3999 hr = IDirect3DDevice8_BeginScene(device);
4000 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4001 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4002 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4003 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4004 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4005 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4006 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4007 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4008 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4009 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4010 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4011 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4012 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4013 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4014 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4015 hr = IDirect3DDevice8_EndScene(device);
4016 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4018 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4019 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4021 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4022 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4023 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4024 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4026 /* Read the depth values back. */
4027 hr = IDirect3DDevice8_BeginScene(device);
4028 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4029 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4030 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4031 hr = IDirect3DDevice8_EndScene(device);
4032 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4034 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4036 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4037 ok(color_match(color, expected_colors[i].color, 1),
4038 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4039 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4042 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4043 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4045 IDirect3DSurface8_Release(ds);
4046 IDirect3DTexture8_Release(texture);
4047 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4048 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4049 IDirect3DSurface8_Release(original_ds);
4050 IDirect3DSurface8_Release(original_rt);
4052 refcount = IDirect3DDevice8_Release(device);
4053 ok(!refcount, "Device has %u references left.\n", refcount);
4054 done:
4055 IDirect3D8_Release(d3d);
4056 DestroyWindow(window);
4059 static void zenable_test(void)
4061 IDirect3DDevice8 *device;
4062 IDirect3D8 *d3d;
4063 D3DCOLOR color;
4064 ULONG refcount;
4065 D3DCAPS8 caps;
4066 HWND window;
4067 HRESULT hr;
4068 UINT x, y;
4069 UINT i, j;
4071 static const struct
4073 struct vec4 position;
4074 D3DCOLOR diffuse;
4076 tquad[] =
4078 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4079 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4080 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4081 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4084 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4085 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4086 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4087 ok(!!d3d, "Failed to create a D3D object.\n");
4088 if (!(device = create_device(d3d, window, window, TRUE)))
4090 skip("Failed to create a D3D device, skipping tests.\n");
4091 goto done;
4094 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4095 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4096 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4097 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4099 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4100 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4101 hr = IDirect3DDevice8_BeginScene(device);
4102 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4103 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4105 hr = IDirect3DDevice8_EndScene(device);
4106 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4108 for (i = 0; i < 4; ++i)
4110 for (j = 0; j < 4; ++j)
4112 x = 80 * ((2 * j) + 1);
4113 y = 60 * ((2 * i) + 1);
4114 color = getPixelColor(device, x, y);
4115 ok(color_match(color, 0x0000ff00, 1),
4116 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4120 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4121 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4123 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4124 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4126 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4127 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4129 static const DWORD vs_code[] =
4131 0xfffe0101, /* vs_1_1 */
4132 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4133 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4134 0x0000ffff
4136 static const DWORD ps_code[] =
4138 0xffff0101, /* ps_1_1 */
4139 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4140 0x0000ffff /* end */
4142 static const struct vec3 quad[] =
4144 {-1.0f, -1.0f, -0.5f},
4145 {-1.0f, 1.0f, -0.5f},
4146 { 1.0f, -1.0f, 1.5f},
4147 { 1.0f, 1.0f, 1.5f},
4149 static const D3DCOLOR expected[] =
4151 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4152 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4153 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4154 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4156 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4157 * vertices either. */
4158 static const D3DCOLOR expected_broken[] =
4160 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4161 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4162 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4163 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4165 static const DWORD decl[] =
4167 D3DVSD_STREAM(0),
4168 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4169 D3DVSD_END()
4171 DWORD vs, ps;
4173 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4174 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4175 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4176 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4177 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4178 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4179 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4180 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4182 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4183 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4184 hr = IDirect3DDevice8_BeginScene(device);
4185 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4186 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4187 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4188 hr = IDirect3DDevice8_EndScene(device);
4189 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4191 for (i = 0; i < 4; ++i)
4193 for (j = 0; j < 4; ++j)
4195 x = 80 * ((2 * j) + 1);
4196 y = 60 * ((2 * i) + 1);
4197 color = getPixelColor(device, x, y);
4198 ok(color_match(color, expected[i * 4 + j], 1)
4199 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4200 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4204 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4205 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4207 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4208 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4209 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4210 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4213 refcount = IDirect3DDevice8_Release(device);
4214 ok(!refcount, "Device has %u references left.\n", refcount);
4215 done:
4216 IDirect3D8_Release(d3d);
4217 DestroyWindow(window);
4220 static void fog_special_test(void)
4222 IDirect3DDevice8 *device;
4223 IDirect3D8 *d3d;
4224 unsigned int i;
4225 D3DCOLOR color;
4226 ULONG refcount;
4227 D3DCAPS8 caps;
4228 DWORD ps, vs;
4229 HWND window;
4230 HRESULT hr;
4231 union
4233 float f;
4234 DWORD d;
4235 } conv;
4237 static const struct
4239 struct vec3 position;
4240 D3DCOLOR diffuse;
4242 quad[] =
4244 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4245 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4246 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4247 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4249 static const struct
4251 DWORD vertexmode, tablemode;
4252 BOOL vs, ps;
4253 D3DCOLOR color_left, color_right;
4255 tests[] =
4257 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4258 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4259 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4260 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4262 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4263 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4264 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4265 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4267 static const DWORD pixel_shader_code[] =
4269 0xffff0101, /* ps.1.1 */
4270 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4271 0x0000ffff
4273 static const DWORD vertex_decl[] =
4275 D3DVSD_STREAM(0),
4276 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4277 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4278 D3DVSD_END()
4280 static const DWORD vertex_shader_code[] =
4282 0xfffe0101, /* vs.1.1 */
4283 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4284 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4285 0x0000ffff
4287 static const D3DMATRIX identity =
4289 1.0f, 0.0f, 0.0f, 0.0f,
4290 0.0f, 1.0f, 0.0f, 0.0f,
4291 0.0f, 0.0f, 1.0f, 0.0f,
4292 0.0f, 0.0f, 0.0f, 1.0f,
4293 }}};
4295 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4296 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4297 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4298 ok(!!d3d, "Failed to create a D3D object.\n");
4299 if (!(device = create_device(d3d, window, window, TRUE)))
4301 skip("Failed to create a D3D device, skipping tests.\n");
4302 goto done;
4305 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4306 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4307 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4309 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4310 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4312 else
4314 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4315 vs = 0;
4317 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4319 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4320 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4322 else
4324 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4325 ps = 0;
4328 /* The table fog tests seem to depend on the projection matrix explicitly
4329 * being set to an identity matrix, even though that's the default.
4330 * (AMD Radeon HD 6310, Windows 7) */
4331 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4332 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
4334 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4335 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4336 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4337 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
4338 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4339 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
4341 conv.f = 0.5f;
4342 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4343 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
4344 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4345 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
4347 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
4349 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4350 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4352 if (!tests[i].vs)
4354 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4355 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4357 else if (vs)
4359 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4360 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4362 else
4364 continue;
4367 if (!tests[i].ps)
4369 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4370 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4372 else if (ps)
4374 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4375 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4377 else
4379 continue;
4382 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
4383 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
4384 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
4385 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
4387 hr = IDirect3DDevice8_BeginScene(device);
4388 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4389 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4390 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4391 hr = IDirect3DDevice8_EndScene(device);
4392 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4394 color = getPixelColor(device, 310, 240);
4395 ok(color_match(color, tests[i].color_left, 1),
4396 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
4397 color = getPixelColor(device, 330, 240);
4398 ok(color_match(color, tests[i].color_right, 1),
4399 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
4401 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4402 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4405 if (vs)
4406 IDirect3DDevice8_DeleteVertexShader(device, vs);
4407 if (ps)
4408 IDirect3DDevice8_DeletePixelShader(device, ps);
4409 refcount = IDirect3DDevice8_Release(device);
4410 ok(!refcount, "Device has %u references left.\n", refcount);
4411 done:
4412 IDirect3D8_Release(d3d);
4413 DestroyWindow(window);
4416 static void volume_dxt5_test(void)
4418 IDirect3DVolumeTexture8 *texture;
4419 IDirect3DDevice8 *device;
4420 D3DLOCKED_BOX box;
4421 IDirect3D8 *d3d;
4422 unsigned int i;
4423 D3DCOLOR color;
4424 ULONG refcount;
4425 HWND window;
4426 HRESULT hr;
4428 static const char texture_data[] =
4430 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4431 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4432 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4433 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4434 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4436 static const struct
4438 struct vec3 position;
4439 struct vec3 texcrd;
4441 quads[] =
4443 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4444 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4445 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4446 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4448 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4449 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4450 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4451 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4453 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4455 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4456 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4457 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4458 ok(!!d3d, "Failed to create a D3D object.\n");
4459 if (!(device = create_device(d3d, window, window, TRUE)))
4461 skip("Failed to create a D3D device, skipping tests.\n");
4462 goto done;
4465 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4466 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
4468 skip("Volume DXT5 textures are not supported, skipping test.\n");
4469 IDirect3DDevice8_Release(device);
4470 goto done;
4473 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
4474 D3DPOOL_MANAGED, &texture);
4475 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4477 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
4478 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
4479 memcpy(box.pBits, texture_data, sizeof(texture_data));
4480 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
4481 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
4483 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
4484 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4485 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4486 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4487 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4488 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4489 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4490 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
4491 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4492 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4493 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4494 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
4496 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
4497 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4498 hr = IDirect3DDevice8_BeginScene(device);
4499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4500 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
4501 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4502 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
4503 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4504 hr = IDirect3DDevice8_EndScene(device);
4505 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4507 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4508 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4509 for (i = 0; i < 4; i++)
4511 color = getPixelColor(device, 80 + 160 * i, 240);
4512 ok (color_match(color, expected_colors[i], 1),
4513 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
4516 IDirect3DVolumeTexture8_Release(texture);
4517 refcount = IDirect3DDevice8_Release(device);
4518 ok(!refcount, "Device has %u references left.\n", refcount);
4519 done:
4520 IDirect3D8_Release(d3d);
4521 DestroyWindow(window);
4524 static void volume_v16u16_test(void)
4526 IDirect3DVolumeTexture8 *texture;
4527 IDirect3DDevice8 *device;
4528 D3DLOCKED_BOX box;
4529 IDirect3D8 *d3d;
4530 unsigned int i;
4531 D3DCOLOR color;
4532 ULONG refcount;
4533 D3DCAPS8 caps;
4534 DWORD shader;
4535 SHORT *texel;
4536 HWND window;
4537 HRESULT hr;
4539 static const struct
4541 struct vec3 position;
4542 struct vec3 texcrd;
4544 quads[] =
4546 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4547 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4548 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4549 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4551 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4552 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4553 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4554 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4556 static const DWORD shader_code[] =
4558 0xffff0101, /* ps_1_1 */
4559 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
4560 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
4561 0x00000042, 0xb00f0000, /* tex t0 */
4562 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
4563 0x0000ffff /* end */
4566 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4567 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4568 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4569 ok(!!d3d, "Failed to create a D3D object.\n");
4570 if (!(device = create_device(d3d, window, window, TRUE)))
4572 skip("Failed to create a D3D device, skipping tests.\n");
4573 goto done;
4576 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4577 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
4579 skip("Volume V16U16 textures are not supported, skipping test.\n");
4580 IDirect3DDevice8_Release(device);
4581 goto done;
4583 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4584 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
4585 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4587 skip("No pixel shader 1.1 support, skipping test.\n");
4588 IDirect3DDevice8_Release(device);
4589 goto done;
4592 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
4593 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4594 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
4595 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4596 hr = IDirect3DDevice8_SetPixelShader(device, shader);
4597 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4598 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4599 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
4601 for (i = 0; i < 2; i++)
4603 D3DPOOL pool;
4605 if (i)
4606 pool = D3DPOOL_SYSTEMMEM;
4607 else
4608 pool = D3DPOOL_MANAGED;
4610 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
4611 pool, &texture);
4612 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4614 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
4615 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
4617 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
4618 texel[0] = 32767;
4619 texel[1] = 32767;
4620 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
4621 texel[0] = -32768;
4622 texel[1] = 0;
4623 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
4624 texel[0] = -16384;
4625 texel[1] = 16384;
4626 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
4627 texel[0] = 0;
4628 texel[1] = 0;
4630 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
4631 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
4633 if (i)
4635 IDirect3DVolumeTexture8 *texture2;
4637 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
4638 D3DPOOL_DEFAULT, &texture2);
4639 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4641 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
4642 (IDirect3DBaseTexture8 *)texture2);
4643 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4645 IDirect3DVolumeTexture8_Release(texture);
4646 texture = texture2;
4649 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
4650 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4652 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
4653 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4654 hr = IDirect3DDevice8_BeginScene(device);
4655 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4656 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
4657 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4658 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
4659 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4660 hr = IDirect3DDevice8_EndScene(device);
4661 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4663 color = getPixelColor(device, 120, 160);
4664 ok (color_match(color, 0x000080ff, 2),
4665 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
4666 color = getPixelColor(device, 120, 400);
4667 ok (color_match(color, 0x00ffffff, 2),
4668 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
4669 color = getPixelColor(device, 360, 160);
4670 ok (color_match(color, 0x007f7fff, 2),
4671 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
4672 color = getPixelColor(device, 360, 400);
4673 ok (color_match(color, 0x0040c0ff, 2),
4674 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
4676 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4677 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4679 IDirect3DVolumeTexture8_Release(texture);
4682 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
4683 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
4684 refcount = IDirect3DDevice8_Release(device);
4685 ok(!refcount, "Device has %u references left.\n", refcount);
4686 done:
4687 IDirect3D8_Release(d3d);
4688 DestroyWindow(window);
4691 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
4693 D3DSURFACE_DESC desc;
4694 D3DLOCKED_RECT l;
4695 HRESULT hr;
4696 unsigned int x, y;
4697 DWORD *mem;
4699 hr = IDirect3DSurface8_GetDesc(surface, &desc);
4700 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4701 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
4702 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
4703 if (FAILED(hr))
4704 return;
4706 for (y = 0; y < desc.Height; y++)
4708 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
4709 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
4711 mem[x] = color;
4714 hr = IDirect3DSurface8_UnlockRect(surface);
4715 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
4718 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
4720 HRESULT hr;
4721 static const struct
4723 struct vec3 position;
4724 struct vec2 texcoord;
4726 quad[] =
4728 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
4729 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
4730 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
4731 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
4734 hr = IDirect3DDevice8_BeginScene(device);
4735 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4736 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
4737 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4738 hr = IDirect3DDevice8_EndScene(device);
4739 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4742 static void add_dirty_rect_test(void)
4744 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
4745 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
4746 D3DLOCKED_RECT locked_rect;
4747 IDirect3DDevice8 *device;
4748 IDirect3D8 *d3d;
4749 unsigned int i;
4750 D3DCOLOR color;
4751 ULONG refcount;
4752 DWORD *texel;
4753 HWND window;
4754 HRESULT hr;
4756 static const RECT part_rect = {96, 96, 160, 160};
4758 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4759 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4760 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4761 ok(!!d3d, "Failed to create a D3D object.\n");
4762 if (!(device = create_device(d3d, window, window, TRUE)))
4764 skip("Failed to create a D3D device, skipping tests.\n");
4765 goto done;
4768 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
4769 D3DPOOL_DEFAULT, &tex_dst1);
4770 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4771 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
4772 D3DPOOL_DEFAULT, &tex_dst2);
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_SYSTEMMEM, &tex_src_red);
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_green);
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_MANAGED, &tex_managed);
4782 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4784 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
4785 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
4786 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
4787 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
4788 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
4789 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
4790 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed);
4791 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
4793 fill_surface(surface_src_red, 0x00ff0000, 0);
4794 fill_surface(surface_src_green, 0x0000ff00, 0);
4796 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
4797 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4798 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4799 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4800 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4801 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
4803 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4804 (IDirect3DBaseTexture8 *)tex_dst1);
4805 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4807 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
4808 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
4809 (IDirect3DBaseTexture8 *)tex_dst2);
4810 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4811 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4812 (IDirect3DBaseTexture8 *)tex_dst2);
4813 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4815 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
4816 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4817 add_dirty_rect_test_draw(device);
4818 color = getPixelColor(device, 320, 240);
4819 ok(color_match(color, 0x0000ff00, 1),
4820 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4821 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4822 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4824 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
4825 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4826 add_dirty_rect_test_draw(device);
4827 color = getPixelColor(device, 320, 240);
4828 todo_wine ok(color_match(color, 0x00ff0000, 1),
4829 "Expected color 0x00ff0000, got 0x%08x.\n", color);
4830 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4831 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4833 /* AddDirtyRect on the destination is ignored. */
4834 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
4835 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
4836 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4837 (IDirect3DBaseTexture8 *)tex_dst2);
4838 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4839 add_dirty_rect_test_draw(device);
4840 color = getPixelColor(device, 320, 240);
4841 todo_wine ok(color_match(color, 0x00ff0000, 1),
4842 "Expected color 0x00ff0000, got 0x%08x.\n", color);
4843 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4844 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4846 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
4847 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
4848 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4849 (IDirect3DBaseTexture8 *)tex_dst2);
4850 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4851 add_dirty_rect_test_draw(device);
4852 color = getPixelColor(device, 320, 240);
4853 todo_wine ok(color_match(color, 0x00ff0000, 1),
4854 "Expected color 0x00ff0000, got 0x%08x.\n", color);
4855 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4856 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4858 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
4859 * tracking is supported. */
4860 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
4861 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
4862 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4863 (IDirect3DBaseTexture8 *)tex_dst2);
4864 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4865 add_dirty_rect_test_draw(device);
4866 color = getPixelColor(device, 320, 240);
4867 ok(color_match(color, 0x0000ff00, 1),
4868 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4869 color = getPixelColor(device, 1, 1);
4870 todo_wine ok(color_match(color, 0x00ff0000, 1),
4871 "Expected color 0x00ff0000, got 0x%08x.\n", color);
4872 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4873 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4875 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
4876 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
4877 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4878 (IDirect3DBaseTexture8 *)tex_dst2);
4879 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4880 add_dirty_rect_test_draw(device);
4881 color = getPixelColor(device, 1, 1);
4882 ok(color_match(color, 0x0000ff00, 1),
4883 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4885 /* Locks with NO_DIRTY_UPDATE are ignored. */
4886 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
4887 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4888 (IDirect3DBaseTexture8 *)tex_dst2);
4889 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4890 add_dirty_rect_test_draw(device);
4891 color = getPixelColor(device, 320, 240);
4892 todo_wine ok(color_match(color, 0x0000ff00, 1),
4893 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4894 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4895 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4897 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
4898 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
4899 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4900 (IDirect3DBaseTexture8 *)tex_dst2);
4901 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4902 add_dirty_rect_test_draw(device);
4903 color = getPixelColor(device, 320, 240);
4904 todo_wine ok(color_match(color, 0x0000ff00, 1),
4905 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4906 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4907 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4909 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
4910 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4911 (IDirect3DBaseTexture8 *)tex_dst2);
4912 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4913 add_dirty_rect_test_draw(device);
4914 color = getPixelColor(device, 320, 240);
4915 ok(color_match(color, 0x000000ff, 1),
4916 "Expected color 0x000000ff, got 0x%08x.\n", color);
4917 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4918 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4920 /* Maps without either of these flags record a dirty rectangle. */
4921 fill_surface(surface_src_green, 0x00ffffff, 0);
4922 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4923 (IDirect3DBaseTexture8 *)tex_dst2);
4924 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4925 add_dirty_rect_test_draw(device);
4926 color = getPixelColor(device, 320, 240);
4927 ok(color_match(color, 0x00ffffff, 1),
4928 "Expected color 0x00ffffff, got 0x%08x.\n", color);
4929 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4930 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4932 /* Partial LockRect works just like a partial AddDirtyRect call. */
4933 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
4934 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
4935 texel = locked_rect.pBits;
4936 for (i = 0; i < 64; i++)
4937 texel[i] = 0x00ff00ff;
4938 for (i = 1; i < 64; i++)
4939 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
4940 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
4941 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4942 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4943 (IDirect3DBaseTexture8 *)tex_dst2);
4944 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4945 add_dirty_rect_test_draw(device);
4946 color = getPixelColor(device, 320, 240);
4947 ok(color_match(color, 0x00ff00ff, 1),
4948 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
4949 color = getPixelColor(device, 1, 1);
4950 ok(color_match(color, 0x00ffffff, 1),
4951 "Expected color 0x00ffffff, got 0x%08x.\n", color);
4952 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4953 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4955 fill_surface(surface_src_red, 0x00ff0000, 0);
4956 fill_surface(surface_src_green, 0x0000ff00, 0);
4958 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
4959 (IDirect3DBaseTexture8 *)tex_dst1);
4960 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
4961 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
4962 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4963 add_dirty_rect_test_draw(device);
4964 color = getPixelColor(device, 320, 240);
4965 ok(color_match(color, 0x0000ff00, 1),
4966 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4967 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4968 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4970 /* UpdateSurface ignores the missing dirty marker. */
4971 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
4972 (IDirect3DBaseTexture8 *)tex_dst2);
4973 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
4974 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
4975 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
4976 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4977 add_dirty_rect_test_draw(device);
4978 color = getPixelColor(device, 320, 240);
4979 ok(color_match(color, 0x0000ff00, 1),
4980 "Expected color 0x0000ff00, got 0x%08x.\n", color);
4981 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4982 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4984 fill_surface(surface_managed, 0x00ff0000, 0);
4985 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
4986 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4987 add_dirty_rect_test_draw(device);
4988 color = getPixelColor(device, 320, 240);
4989 ok(color_match(color, 0x00ff0000, 1),
4990 "Expected color 0x00ff0000, got 0x%08x.\n", color);
4991 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4992 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4994 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
4995 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
4996 add_dirty_rect_test_draw(device);
4997 color = getPixelColor(device, 320, 240);
4998 ok(color_match(color, 0x00ff0000, 1),
4999 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5000 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5001 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5003 /* AddDirtyRect uploads the new contents.
5004 * Side note, not tested in the test: Partial surface updates work, and two separate
5005 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5006 * untested. */
5007 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5008 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5009 add_dirty_rect_test_draw(device);
5010 color = getPixelColor(device, 320, 240);
5011 ok(color_match(color, 0x0000ff00, 1),
5012 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5013 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5014 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5016 /* So does ResourceManagerDiscardBytes. */
5017 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5018 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5019 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5020 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5021 add_dirty_rect_test_draw(device);
5022 color = getPixelColor(device, 320, 240);
5023 ok(color_match(color, 0x000000ff, 1),
5024 "Expected color 0x000000ff, got 0x%08x.\n", color);
5025 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5026 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5028 /* AddDirtyRect on a locked texture is allowed. */
5029 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5030 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5031 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5032 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5033 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5034 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5036 /* Redundant AddDirtyRect calls are ok. */
5037 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5038 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5039 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5040 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5042 IDirect3DSurface8_Release(surface_dst2);
5043 IDirect3DSurface8_Release(surface_managed);
5044 IDirect3DSurface8_Release(surface_src_red);
5045 IDirect3DSurface8_Release(surface_src_green);
5046 IDirect3DTexture8_Release(tex_src_red);
5047 IDirect3DTexture8_Release(tex_src_green);
5048 IDirect3DTexture8_Release(tex_dst1);
5049 IDirect3DTexture8_Release(tex_dst2);
5050 IDirect3DTexture8_Release(tex_managed);
5051 refcount = IDirect3DDevice8_Release(device);
5052 ok(!refcount, "Device has %u references left.\n", refcount);
5053 done:
5054 IDirect3D8_Release(d3d);
5055 DestroyWindow(window);
5058 START_TEST(visual)
5060 D3DADAPTER_IDENTIFIER8 identifier;
5061 IDirect3D8 *d3d;
5062 HRESULT hr;
5064 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
5066 skip("Failed to create D3D8 object.\n");
5067 return;
5070 memset(&identifier, 0, sizeof(identifier));
5071 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
5072 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
5073 trace("Driver string: \"%s\"\n", identifier.Driver);
5074 trace("Description string: \"%s\"\n", identifier.Description);
5075 /* Only Windows XP's default VGA driver should have an empty description */
5076 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
5077 trace("Driver version %d.%d.%d.%d\n",
5078 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
5079 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
5081 IDirect3D8_Release(d3d);
5083 test_sanity();
5084 depth_clamp_test();
5085 lighting_test();
5086 clear_test();
5087 fog_test();
5088 z_range_test();
5089 offscreen_test();
5090 alpha_test();
5091 test_scalar_instructions();
5092 fog_with_shader_test();
5093 cnd_test();
5094 p8_texture_test();
5095 texop_test();
5096 depth_buffer_test();
5097 depth_buffer2_test();
5098 intz_test();
5099 shadow_test();
5100 multisample_copy_rects_test();
5101 zenable_test();
5102 resz_test();
5103 fog_special_test();
5104 volume_dxt5_test();
5105 volume_v16u16_test();
5106 add_dirty_rect_test();