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