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