d3d8/tests: Fix a couple of return value checks.
[wine.git] / dlls / d3d8 / tests / visual.c
blob191cf08900a34bce2abffdbed3471bc9821d6ae3
1 /*
2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2007 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 static HMODULE d3d8_handle = 0;
28 struct vec3
30 float x, y, z;
33 struct vec4
35 float x, y, z, w;
38 static HWND create_window(void)
40 WNDCLASS wc = {0};
41 HWND ret;
42 wc.lpfnWndProc = DefWindowProc;
43 wc.lpszClassName = "d3d8_test_wc";
44 RegisterClass(&wc);
46 ret = CreateWindow("d3d8_test_wc", "d3d8_test",
47 WS_POPUP | WS_SYSMENU , 20, 20, 640, 480, 0, 0, 0, 0);
48 ShowWindow(ret, SW_SHOW);
49 return ret;
52 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55 c1 >>= 8; c2 >>= 8;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 c1 >>= 8; c2 >>= 8;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59 c1 >>= 8; c2 >>= 8;
60 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
61 return TRUE;
64 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
66 DWORD ret;
67 IDirect3DTexture8 *tex = NULL;
68 IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
69 HRESULT hr;
70 D3DLOCKED_RECT lockedRect;
71 RECT rectToLock = {x, y, x+1, y+1};
73 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
74 if(FAILED(hr) || !tex ) /* This is not a test */
76 trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr);
77 return 0xdeadbeef;
79 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &surf);
80 if(FAILED(hr) || !tex ) /* This is not a test */
82 trace("Can't get surface from texture, hr=%#08x\n", hr);
83 ret = 0xdeadbeee;
84 goto out;
87 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
88 if(FAILED(hr))
90 trace("Can't get the render target, hr=%#08x\n", hr);
91 ret = 0xdeadbeed;
92 goto out;
94 hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
95 if(FAILED(hr))
97 trace("Can't read the render target, hr=%#08x\n", hr);
98 ret = 0xdeadbeec;
99 goto out;
102 hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
103 if(FAILED(hr))
105 trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
106 ret = 0xdeadbeeb;
107 goto out;
109 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
110 * really important for these tests
112 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
113 hr = IDirect3DSurface8_UnlockRect(surf);
114 if(FAILED(hr))
116 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
119 out:
120 if(backbuf) IDirect3DSurface8_Release(backbuf);
121 if(surf) IDirect3DSurface8_Release(surf);
122 if(tex) IDirect3DTexture8_Release(tex);
123 return ret;
126 static IDirect3DDevice8 *init_d3d8(void)
128 IDirect3D8 * (__stdcall * d3d8_create)(UINT SDKVersion) = 0;
129 IDirect3D8 *d3d8_ptr = 0;
130 IDirect3DDevice8 *device_ptr = 0;
131 D3DPRESENT_PARAMETERS present_parameters;
132 HRESULT hr;
134 d3d8_create = (void *)GetProcAddress(d3d8_handle, "Direct3DCreate8");
135 ok(d3d8_create != NULL, "Failed to get address of Direct3DCreate8\n");
136 if (!d3d8_create) return NULL;
138 d3d8_ptr = d3d8_create(D3D_SDK_VERSION);
139 if (!d3d8_ptr)
141 skip("could not create D3D8\n");
142 return NULL;
145 ZeroMemory(&present_parameters, sizeof(present_parameters));
146 present_parameters.Windowed = TRUE;
147 present_parameters.hDeviceWindow = create_window();
148 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
149 present_parameters.BackBufferWidth = 640;
150 present_parameters.BackBufferHeight = 480;
151 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
152 present_parameters.EnableAutoDepthStencil = TRUE;
153 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
155 hr = IDirect3D8_CreateDevice(d3d8_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
156 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
157 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL || broken(hr == D3DERR_NOTAVAILABLE), "IDirect3D_CreateDevice returned: %#08x\n", hr);
159 return device_ptr;
162 struct vertex
164 float x, y, z;
165 DWORD diffuse;
168 struct tvertex
170 float x, y, z, w;
171 DWORD diffuse;
174 struct nvertex
176 float x, y, z;
177 float nx, ny, nz;
178 DWORD diffuse;
181 static void lighting_test(IDirect3DDevice8 *device)
183 HRESULT hr;
184 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
185 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
186 DWORD color;
188 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
189 0.0f, 1.0f, 0.0f, 0.0f,
190 0.0f, 0.0f, 1.0f, 0.0f,
191 0.0f, 0.0f, 0.0f, 1.0f };
193 struct vertex unlitquad[] =
195 {-1.0f, -1.0f, 0.1f, 0xffff0000},
196 {-1.0f, 0.0f, 0.1f, 0xffff0000},
197 { 0.0f, 0.0f, 0.1f, 0xffff0000},
198 { 0.0f, -1.0f, 0.1f, 0xffff0000},
200 struct vertex litquad[] =
202 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
203 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
204 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
205 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
207 struct nvertex unlitnquad[] =
209 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
210 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
211 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
212 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
214 struct nvertex litnquad[] =
216 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
217 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
218 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
219 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
221 WORD Indices[] = {0, 1, 2, 2, 3, 0};
223 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
224 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
226 /* Setup some states that may cause issues */
227 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
228 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
229 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
230 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
231 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
232 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
233 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
234 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
235 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
236 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
237 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
238 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
239 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
240 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
241 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
242 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
243 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
244 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
245 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
246 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
247 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
248 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
250 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
251 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
253 hr = IDirect3DDevice8_BeginScene(device);
254 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr);
255 if(hr == D3D_OK)
257 /* No lights are defined... That means, lit vertices should be entirely black */
258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
259 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
260 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
261 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
262 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
265 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
266 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
267 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
268 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
270 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
271 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed with %#08x\n", hr);
273 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
274 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
275 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
276 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
277 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
279 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
280 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
281 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
282 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
283 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
285 hr = IDirect3DDevice8_EndScene(device);
286 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %#08x\n", hr);
289 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
290 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
291 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
292 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
293 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
294 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
295 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
296 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
298 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
300 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
304 static void clear_test(IDirect3DDevice8 *device)
306 /* Tests the correctness of clearing parameters */
307 HRESULT hr;
308 D3DRECT rect[2];
309 D3DRECT rect_negneg;
310 DWORD color;
312 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
313 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
315 /* Positive x, negative y */
316 rect[0].x1 = 0;
317 rect[0].y1 = 480;
318 rect[0].x2 = 320;
319 rect[0].y2 = 240;
321 /* Positive x, positive y */
322 rect[1].x1 = 0;
323 rect[1].y1 = 0;
324 rect[1].x2 = 320;
325 rect[1].y2 = 240;
326 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
327 * is ignored, the positive is still cleared afterwards
329 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
330 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
332 /* negative x, negative y */
333 rect_negneg.x1 = 640;
334 rect_negneg.y1 = 240;
335 rect_negneg.x2 = 320;
336 rect_negneg.y2 = 0;
337 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
338 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
340 color = getPixelColor(device, 160, 360); /* lower left quad */
341 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
342 color = getPixelColor(device, 160, 120); /* upper left quad */
343 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
344 color = getPixelColor(device, 480, 360); /* lower right quad */
345 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
346 color = getPixelColor(device, 480, 120); /* upper right quad */
347 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
349 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
352 struct sVertex {
353 float x, y, z;
354 DWORD diffuse;
355 DWORD specular;
358 struct sVertexT {
359 float x, y, z, rhw;
360 DWORD diffuse;
361 DWORD specular;
364 static void fog_test(IDirect3DDevice8 *device)
366 HRESULT hr;
367 DWORD color;
368 float start = 0.0, end = 1.0;
370 /* Gets full z based fog with linear fog, no fog with specular color */
371 struct sVertex untransformed_1[] = {
372 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
373 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
374 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
375 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
377 /* Ok, I am too lazy to deal with transform matrices */
378 struct sVertex untransformed_2[] = {
379 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
380 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
381 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
382 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
384 /* Untransformed ones. Give them a different diffuse color to make the test look
385 * nicer. It also makes making sure that they are drawn correctly easier.
387 struct sVertexT transformed_1[] = {
388 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
389 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
390 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
391 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
393 struct sVertexT transformed_2[] = {
394 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
395 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
396 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
397 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
399 WORD Indices[] = {0, 1, 2, 2, 3, 0};
401 D3DCAPS8 caps;
402 float ident_mat[16] =
404 1.0f, 0.0f, 0.0f, 0.0f,
405 0.0f, 1.0f, 0.0f, 0.0f,
406 0.0f, 0.0f, 1.0f, 0.0f,
407 0.0f, 0.0f, 0.0f, 1.0f
409 float world_mat1[16] =
411 1.0f, 0.0f, 0.0f, 0.0f,
412 0.0f, 1.0f, 0.0f, 0.0f,
413 0.0f, 0.0f, 1.0f, 0.0f,
414 0.0f, 0.0f, -0.5f, 1.0f
416 float world_mat2[16] =
418 1.0f, 0.0f, 0.0f, 0.0f,
419 0.0f, 1.0f, 0.0f, 0.0f,
420 0.0f, 0.0f, 1.0f, 0.0f,
421 0.0f, 0.0f, 1.0f, 1.0f
423 float proj_mat[16] =
425 1.0f, 0.0f, 0.0f, 0.0f,
426 0.0f, 1.0f, 0.0f, 0.0f,
427 0.0f, 0.0f, 1.0f, 0.0f,
428 0.0f, 0.0f, -1.0f, 1.0f
431 struct sVertex far_quad1[] =
433 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
434 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
435 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
436 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
438 struct sVertex far_quad2[] =
440 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
441 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
442 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
443 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
446 memset(&caps, 0, sizeof(caps));
447 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
448 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
450 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
451 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
453 /* Setup initial states: No lighting, fog on, fog color */
454 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
456 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
457 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
458 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
459 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
461 /* First test: Both table fog and vertex fog off */
462 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
463 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
465 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
467 /* Start = 0, end = 1. Should be default, but set them */
468 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
469 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
470 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
471 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
473 if(IDirect3DDevice8_BeginScene(device) == D3D_OK)
475 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
476 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
477 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
478 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
479 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
480 sizeof(untransformed_1[0]));
481 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
483 /* That makes it use the Z value */
484 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
485 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
486 /* Untransformed, vertex fog != none (or table fog != none):
487 * Use the Z value as input into the equation
489 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
490 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
491 sizeof(untransformed_2[0]));
492 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
494 /* transformed verts */
495 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
496 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
497 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
498 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
499 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
500 sizeof(transformed_1[0]));
501 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
503 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
504 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
505 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
506 * equation
508 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
509 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
510 sizeof(transformed_2[0]));
511 ok(SUCCEEDED(hr), "IDirect3DDevice8_DrawIndexedPrimitiveUP returned %#x.\n", hr);
513 hr = IDirect3DDevice8_EndScene(device);
514 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
516 else
518 ok(FALSE, "BeginScene failed\n");
521 color = getPixelColor(device, 160, 360);
522 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
523 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
524 color = getPixelColor(device, 160, 120);
525 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
526 "Untransformed vertex with linear vertex fog has color %08x\n", color);
527 color = getPixelColor(device, 480, 120);
528 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
529 "Transformed vertex with linear vertex fog has color %08x\n", color);
530 color = getPixelColor(device, 480, 360);
531 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
532 "Transformed vertex with linear table fog has color %08x\n", color);
534 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
536 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
538 /* A simple fog + non-identity world matrix test */
539 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat1);
540 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
542 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
543 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
544 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
545 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
547 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
548 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
550 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
552 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
553 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
555 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
556 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
557 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
559 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
560 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
561 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
563 hr = IDirect3DDevice8_EndScene(device);
564 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
566 else
568 ok(FALSE, "BeginScene failed\n");
571 color = getPixelColor(device, 160, 360);
572 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
573 color = getPixelColor(device, 160, 120);
574 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
575 "Fogged out quad has color %08x\n", color);
577 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
579 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
580 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat2);
581 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
582 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) proj_mat);
583 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
585 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
586 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
588 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
590 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
591 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
593 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
594 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
595 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
597 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
598 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
599 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
601 hr = IDirect3DDevice8_EndScene(device);
602 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
604 else
606 ok(FALSE, "BeginScene failed\n");
609 color = getPixelColor(device, 160, 360);
610 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
611 color = getPixelColor(device, 160, 120);
612 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
613 "Fogged out quad has color %08x\n", color);
615 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
617 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) ident_mat);
618 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
619 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) ident_mat);
620 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
622 else
624 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
627 /* Turn off the fog master switch to avoid confusing other tests */
628 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
629 ok(hr == D3D_OK, "Turning off fog calculations returned %#08x\n", hr);
632 /* This tests fog in combination with shaders.
633 * What's tested: linear fog (vertex and table) with pixel shader
634 * linear table fog with non foggy vertex shader
635 * vertex fog with foggy vertex shader, non-linear
636 * fog with shader, non-linear fog with foggy shader,
637 * linear table fog with foggy shader */
638 static void fog_with_shader_test(IDirect3DDevice8 *device)
640 HRESULT hr;
641 DWORD color;
642 union
644 float f;
645 DWORD i;
646 } start, end;
647 unsigned int i, j;
649 /* Basic vertex shader without fog computation ("non foggy") */
650 static const DWORD vertex_shader_code1[] =
652 0xfffe0100, /* vs.1.0 */
653 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
654 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
655 0x0000ffff
657 /* Basic vertex shader with reversed fog computation ("foggy") */
658 static const DWORD vertex_shader_code2[] =
660 0xfffe0100, /* vs.1.0 */
661 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
662 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
663 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
664 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
665 0x0000ffff
667 /* Basic pixel shader */
668 static const DWORD pixel_shader_code[] =
670 0xffff0101, /* ps_1_1 */
671 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
672 0x0000ffff
674 static struct vertex quad[] =
676 {-1.0f, -1.0f, 0.0f, 0xffff0000},
677 {-1.0f, 1.0f, 0.0f, 0xffff0000},
678 { 1.0f, -1.0f, 0.0f, 0xffff0000},
679 { 1.0f, 1.0f, 0.0f, 0xffff0000},
681 static const DWORD decl[] =
683 D3DVSD_STREAM(0),
684 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
685 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
686 D3DVSD_END()
688 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
689 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
690 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
691 DWORD pixel_shader[2] = {0, 0};
693 /* This reference data was collected on a nVidia GeForce 7600GS
694 * driver version 84.19 DirectX version 9.0c on Windows XP */
695 static const struct test_data_t
697 int vshader;
698 int pshader;
699 D3DFOGMODE vfog;
700 D3DFOGMODE tfog;
701 unsigned int color[11];
703 test_data[] =
705 /* Only pixel shader */
706 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
707 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
708 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
709 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
710 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
711 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
712 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
713 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
714 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
715 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
716 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
717 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
718 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
719 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
720 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
722 /* Vertex shader */
723 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
724 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
725 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
726 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
727 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
728 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
729 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
730 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
731 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
733 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
734 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
735 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
736 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
737 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
738 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
740 /* Vertex shader and pixel shader */
741 /* The next 4 tests would read the fog coord output, but it isn't available.
742 * The result is a fully fogged quad, no matter what the Z coord is. */
743 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
744 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
745 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
746 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
747 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
748 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
749 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
750 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
751 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
752 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
753 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
754 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
756 /* These use the Z coordinate with linear table fog */
757 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
758 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
759 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
760 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
761 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
762 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
763 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
764 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
765 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
766 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
767 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
768 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
770 /* Non-linear table fog without fog coord */
771 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
772 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
773 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
774 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
775 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
776 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
778 /* These tests fail on older Nvidia drivers */
779 /* Foggy vertex shader */
780 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
781 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
782 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
783 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
784 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
785 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
786 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
787 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
788 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
789 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
790 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
791 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
793 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
794 * all using the fixed fog-coord linear fog */
795 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
796 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
797 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
798 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
799 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
800 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
801 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
802 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
803 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
804 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
805 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
806 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
808 /* These use table fog. Here the shader-provided fog coordinate is
809 * ignored and the z coordinate used instead */
810 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
811 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
812 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
813 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
814 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
815 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
816 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
817 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
818 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
821 /* NOTE: changing these values will not affect the tests with foggy vertex shader,
822 * as the values are hardcoded in the shader constant */
823 start.f = 0.1f;
824 end.f = 0.9f;
826 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
827 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
828 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
829 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
830 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
831 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
833 /* Set shader constant value */
834 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
835 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
837 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
839 /* Setup initial states: No lighting, fog on, fog color */
840 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
841 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
842 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
843 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
844 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
845 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
847 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
848 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
849 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
850 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
852 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
853 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
854 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
855 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
856 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
858 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
860 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
861 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
862 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
863 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
864 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
865 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
866 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
867 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
869 for(j = 0; j < 11; ++j)
871 /* Don't use the whole zrange to prevent rounding errors */
872 quad[0].z = 0.001f + j / 10.02f;
873 quad[1].z = 0.001f + j / 10.02f;
874 quad[2].z = 0.001f + j / 10.02f;
875 quad[3].z = 0.001f + j / 10.02f;
877 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0f, 0);
878 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
880 hr = IDirect3DDevice8_BeginScene(device);
881 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
883 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
884 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
886 hr = IDirect3DDevice8_EndScene(device);
887 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
889 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
890 color = getPixelColor(device, 128, 240);
891 ok(color_match(color, test_data[i].color[j], 13),
892 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
893 test_data[i].vshader, test_data[i].pshader,
894 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
896 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
900 /* Reset states */
901 hr = IDirect3DDevice8_SetVertexShader(device, 0);
902 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
903 hr = IDirect3DDevice8_SetPixelShader(device, 0);
904 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
905 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
906 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
908 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
909 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
910 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
913 static void present_test(IDirect3DDevice8 *device)
915 struct vertex quad[] =
917 {-1.0f, -1.0f, 0.9f, 0xffff0000},
918 {-1.0f, 1.0f, 0.9f, 0xffff0000},
919 { 1.0f, -1.0f, 0.1f, 0xffff0000},
920 { 1.0f, 1.0f, 0.1f, 0xffff0000},
922 HRESULT hr;
923 DWORD color;
925 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
926 * then call Present. Then clear the color buffer to make sure it has some defined content
927 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
928 * by the depth value.
930 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
931 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
932 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
933 ok(SUCCEEDED(hr), "IDirect3DDevice8_Present returned %#x.\n", hr);
934 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4f, 0);
935 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear returned %#x.\n", hr);
937 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
938 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
939 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
940 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
941 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
942 ok(hr == D3D_OK, "IDirect3DDevice8_SetFVF returned %08x\n", hr);
944 hr = IDirect3DDevice8_BeginScene(device);
945 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %08x\n", hr);
946 if(hr == D3D_OK)
948 /* No lights are defined... That means, lit vertices should be entirely black */
949 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
950 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %08x\n", hr);
952 hr = IDirect3DDevice8_EndScene(device);
953 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %08x\n", hr);
956 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
957 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
959 color = getPixelColor(device, 512, 240);
960 ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
961 color = getPixelColor(device, 64, 240);
962 ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
964 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
965 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
968 static void test_rcp_rsq(IDirect3DDevice8 *device)
970 HRESULT hr;
971 DWORD shader;
972 DWORD color;
973 float constant[4] = {1.0, 1.0, 1.0, 2.0};
975 static const float quad[][3] = {
976 {-1.0f, -1.0f, 0.0f},
977 {-1.0f, 1.0f, 0.0f},
978 { 1.0f, -1.0f, 0.0f},
979 { 1.0f, 1.0f, 0.0f},
982 const DWORD rcp_test[] = {
983 0xfffe0101, /* vs.1.1 */
985 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
986 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
987 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
988 0x00303030, /* enough to make windows happy */
990 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
991 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
992 0x0000ffff /* END */
995 const DWORD rsq_test[] = {
996 0xfffe0101, /* vs.1.1 */
998 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
999 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
1000 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1001 0x00303030, /* enough to make windows happy */
1003 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1004 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
1005 0x0000ffff /* END */
1008 DWORD decl[] =
1010 D3DVSD_STREAM(0),
1011 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* D3DVSDE_POSITION, Register v0 */
1012 D3DVSD_END()
1015 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
1016 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1018 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
1019 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
1021 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1022 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1023 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
1025 hr = IDirect3DDevice8_BeginScene(device);
1026 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
1027 if(SUCCEEDED(hr))
1029 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1030 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
1031 hr = IDirect3DDevice8_EndScene(device);
1032 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
1035 color = getPixelColor(device, 320, 240);
1036 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), 4),
1037 "RCP test returned color 0x%08x, expected 0x00808080.\n", color);
1039 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1040 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
1042 IDirect3DDevice8_SetVertexShader(device, 0);
1043 IDirect3DDevice8_DeleteVertexShader(device, shader);
1045 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff996633, 0.0f, 0);
1046 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1048 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
1049 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
1051 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1052 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1053 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
1055 hr = IDirect3DDevice8_BeginScene(device);
1056 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
1057 if(SUCCEEDED(hr))
1059 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1060 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
1061 hr = IDirect3DDevice8_EndScene(device);
1062 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
1065 color = getPixelColor(device, 320, 240);
1066 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), 4),
1067 "RSQ test returned color 0x%08x, expected 0x00b4b4b4.\n", color);
1069 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1070 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
1072 IDirect3DDevice8_SetVertexShader(device, 0);
1073 IDirect3DDevice8_DeleteVertexShader(device, shader);
1076 static void offscreen_test(IDirect3DDevice8 *device)
1078 HRESULT hr;
1079 IDirect3DTexture8 *offscreenTexture = NULL;
1080 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
1081 DWORD color;
1083 static const float quad[][5] = {
1084 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1085 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1086 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1087 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1090 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
1091 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
1093 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1094 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
1096 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
1097 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1098 if(!offscreenTexture) {
1099 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1100 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
1101 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1102 if(!offscreenTexture) {
1103 skip("Cannot create an offscreen render target\n");
1104 goto out;
1108 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1109 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
1110 if(!backbuffer) {
1111 goto out;
1114 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1115 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
1116 if(!offscreen) {
1117 goto out;
1120 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1121 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1123 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1124 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1125 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1126 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1127 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
1128 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
1129 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
1130 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
1131 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1132 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
1134 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
1135 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
1136 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
1137 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1138 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
1140 /* Draw without textures - Should result in a white quad */
1141 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1142 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1144 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1145 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
1146 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1147 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1149 /* This time with the texture */
1150 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1151 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1153 IDirect3DDevice8_EndScene(device);
1156 /* Center quad - should be white */
1157 color = getPixelColor(device, 320, 240);
1158 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1159 /* Some quad in the cleared part of the texture */
1160 color = getPixelColor(device, 170, 240);
1161 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1162 /* Part of the originally cleared back buffer */
1163 color = getPixelColor(device, 10, 10);
1164 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1165 if(0) {
1166 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1167 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1168 * the offscreen rendering mode this test would succeed or fail
1170 color = getPixelColor(device, 10, 470);
1171 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1174 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1176 out:
1177 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1178 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetTexture returned %#x.\n", hr);
1180 /* restore things */
1181 if(backbuffer) {
1182 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1183 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetRenderTarget returned %#x.\n", hr);
1184 IDirect3DSurface8_Release(backbuffer);
1186 if(offscreenTexture) {
1187 IDirect3DTexture8_Release(offscreenTexture);
1189 if(offscreen) {
1190 IDirect3DSurface8_Release(offscreen);
1192 if(depthstencil) {
1193 IDirect3DSurface8_Release(depthstencil);
1197 static void alpha_test(IDirect3DDevice8 *device)
1199 HRESULT hr;
1200 IDirect3DTexture8 *offscreenTexture;
1201 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
1202 DWORD color;
1204 struct vertex quad1[] =
1206 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
1207 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
1208 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
1209 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
1211 struct vertex quad2[] =
1213 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
1214 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
1215 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
1216 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
1218 static const float composite_quad[][5] = {
1219 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
1220 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
1221 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
1222 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
1225 /* Clear the render target with alpha = 0.5 */
1226 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1227 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1229 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
1230 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1232 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
1233 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
1235 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1236 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
1237 if(!backbuffer) {
1238 goto out;
1240 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1241 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
1242 if(!offscreen) {
1243 goto out;
1246 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1247 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1249 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1250 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1251 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1252 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1253 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
1254 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
1255 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
1256 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
1257 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1258 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
1260 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1261 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1262 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
1264 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
1265 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1266 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1268 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1269 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1270 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1272 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1273 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1275 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1276 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1277 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1279 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
1280 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
1281 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
1282 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
1283 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1284 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1285 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1287 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1288 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1289 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1290 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1291 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1292 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1294 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1295 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1296 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1297 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1298 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1299 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1301 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1302 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1304 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1305 * Disable alpha blending for the final composition
1307 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1308 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1309 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1310 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1312 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1313 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1314 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
1315 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1316 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1317 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1319 hr = IDirect3DDevice8_EndScene(device);
1320 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1323 color = getPixelColor(device, 160, 360);
1324 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1325 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
1327 color = getPixelColor(device, 160, 120);
1328 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
1329 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
1331 color = getPixelColor(device, 480, 360);
1332 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1333 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
1335 color = getPixelColor(device, 480, 120);
1336 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1337 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
1339 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1341 out:
1342 /* restore things */
1343 if(backbuffer) {
1344 IDirect3DSurface8_Release(backbuffer);
1346 if(offscreenTexture) {
1347 IDirect3DTexture8_Release(offscreenTexture);
1349 if(offscreen) {
1350 IDirect3DSurface8_Release(offscreen);
1352 if(depthstencil) {
1353 IDirect3DSurface8_Release(depthstencil);
1357 static void p8_texture_test(IDirect3DDevice8 *device)
1359 IDirect3D8 *d3d = NULL;
1360 HRESULT hr;
1361 IDirect3DTexture8 *texture = NULL, *texture2 = NULL;
1362 D3DLOCKED_RECT lr;
1363 unsigned char *data;
1364 DWORD color, red, green, blue;
1365 PALETTEENTRY table[256];
1366 D3DCAPS8 caps;
1367 UINT i;
1368 float quad[] = {
1369 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
1370 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
1371 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
1372 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
1374 float quad2[] = {
1375 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
1376 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
1377 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
1378 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
1381 IDirect3DDevice8_GetDirect3D(device, &d3d);
1383 if(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1384 D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK) {
1385 skip("D3DFMT_P8 textures not supported\n");
1386 goto out;
1389 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1390 D3DPOOL_MANAGED, &texture2);
1391 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1392 if(!texture2) {
1393 skip("Failed to create D3DFMT_P8 texture\n");
1394 goto out;
1397 memset(&lr, 0, sizeof(lr));
1398 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
1399 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1400 data = lr.pBits;
1401 *data = 1;
1403 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
1404 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1406 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1407 D3DPOOL_MANAGED, &texture);
1408 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1409 if(!texture) {
1410 skip("Failed to create D3DFMT_P8 texture\n");
1411 goto out;
1414 memset(&lr, 0, sizeof(lr));
1415 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
1416 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1417 data = lr.pBits;
1418 *data = 1;
1420 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1421 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1423 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1424 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1426 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1427 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1429 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
1430 alpha of every entry is set to 1.0, which MS says is required when there's no
1431 D3DPTEXTURECAPS_ALPHAPALETTE capability */
1432 for (i = 0; i < 256; i++) {
1433 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1434 table[i].peFlags = 0xff;
1436 table[1].peRed = 0xff;
1437 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1438 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1440 table[1].peRed = 0;
1441 table[1].peBlue = 0xff;
1442 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1443 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1445 hr = IDirect3DDevice8_BeginScene(device);
1446 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1447 if(SUCCEEDED(hr)) {
1448 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1449 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1450 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1451 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1453 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1454 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1456 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1457 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1459 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1460 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1461 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1462 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1464 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
1465 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1466 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1467 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1469 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1470 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1471 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1472 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1474 hr = IDirect3DDevice8_EndScene(device);
1475 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1478 color = getPixelColor(device, 32, 32);
1479 red = (color & 0x00ff0000) >> 16;
1480 green = (color & 0x0000ff00) >> 8;
1481 blue = (color & 0x000000ff) >> 0;
1482 ok(red == 0xff && blue == 0 && green == 0,
1483 "got color %08x, expected 0x00ff0000\n", color);
1485 color = getPixelColor(device, 32, 320);
1486 red = (color & 0x00ff0000) >> 16;
1487 green = (color & 0x0000ff00) >> 8;
1488 blue = (color & 0x000000ff) >> 0;
1489 ok(red == 0 && blue == 0xff && green == 0,
1490 "got color %08x, expected 0x000000ff\n", color);
1492 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1493 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1495 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1496 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1498 hr = IDirect3DDevice8_BeginScene(device);
1499 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1500 if(SUCCEEDED(hr)) {
1501 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1502 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1504 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1505 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1507 hr = IDirect3DDevice8_EndScene(device);
1508 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1512 color = getPixelColor(device, 32, 32);
1513 red = (color & 0x00ff0000) >> 16;
1514 green = (color & 0x0000ff00) >> 8;
1515 blue = (color & 0x000000ff) >> 0;
1516 ok(red == 0 && blue == 0xff && green == 0,
1517 "got color %08x, expected 0x000000ff\n", color);
1519 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1520 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1522 /* Test palettes with alpha */
1523 IDirect3DDevice8_GetDeviceCaps(device, &caps);
1524 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
1525 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
1526 } else {
1527 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1528 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1530 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1531 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1533 for (i = 0; i < 256; i++) {
1534 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1535 table[i].peFlags = 0xff;
1537 table[1].peRed = 0xff;
1538 table[1].peFlags = 0x80;
1539 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1540 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1542 table[1].peRed = 0;
1543 table[1].peBlue = 0xff;
1544 table[1].peFlags = 0x80;
1545 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1546 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1548 hr = IDirect3DDevice8_BeginScene(device);
1549 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1550 if(SUCCEEDED(hr)) {
1551 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1552 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1553 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1554 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1556 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1557 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1559 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1560 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1562 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1563 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1565 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1566 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1568 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1569 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1571 hr = IDirect3DDevice8_EndScene(device);
1572 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1575 color = getPixelColor(device, 32, 32);
1576 red = (color & 0x00ff0000) >> 16;
1577 green = (color & 0x0000ff00) >> 8;
1578 blue = (color & 0x000000ff) >> 0;
1579 ok(red >= 0x7e && red <= 0x81 && blue == 0 && green == 0,
1580 "got color %08x, expected 0x00800000 or near\n", color);
1582 color = getPixelColor(device, 32, 320);
1583 red = (color & 0x00ff0000) >> 16;
1584 green = (color & 0x0000ff00) >> 8;
1585 blue = (color & 0x000000ff) >> 0;
1586 ok(red == 0 && blue >= 0x7e && blue <= 0x81 && green == 0,
1587 "got color %08x, expected 0x00000080 or near\n", color);
1589 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1590 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1593 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1594 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1595 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1596 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1598 out:
1599 if(texture) IDirect3DTexture8_Release(texture);
1600 if(texture2) IDirect3DTexture8_Release(texture2);
1601 IDirect3D8_Release(d3d);
1604 static void texop_test(IDirect3DDevice8 *device)
1606 IDirect3DTexture8 *texture = NULL;
1607 D3DLOCKED_RECT locked_rect;
1608 D3DCOLOR color;
1609 D3DCAPS8 caps;
1610 HRESULT hr;
1611 unsigned int i;
1613 static const struct {
1614 float x, y, z;
1615 D3DCOLOR diffuse;
1616 float s, t;
1617 } quad[] = {
1618 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
1619 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
1620 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
1621 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
1624 static const struct {
1625 D3DTEXTUREOP op;
1626 const char *name;
1627 DWORD caps_flag;
1628 D3DCOLOR result;
1629 } test_data[] = {
1630 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1631 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
1632 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
1633 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
1634 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1635 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1637 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
1638 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1640 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1641 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1642 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1643 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
1644 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
1645 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1646 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1647 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
1648 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
1649 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1650 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
1651 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
1652 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
1653 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
1654 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
1657 memset(&caps, 0, sizeof(caps));
1658 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1659 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
1661 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
1662 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
1664 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
1665 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
1666 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
1667 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1668 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
1669 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1670 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1671 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1672 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1674 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
1675 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1676 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1677 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1678 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
1679 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1681 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
1682 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1684 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1685 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1686 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
1687 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1688 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
1689 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1691 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1692 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1694 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1696 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
1698 skip("tex operation %s not supported\n", test_data[i].name);
1699 continue;
1702 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
1703 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
1705 hr = IDirect3DDevice8_BeginScene(device);
1706 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
1708 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1709 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
1711 hr = IDirect3DDevice8_EndScene(device);
1712 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
1714 color = getPixelColor(device, 320, 240);
1715 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
1716 test_data[i].name, color, test_data[i].result);
1718 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1719 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
1721 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1722 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1725 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1726 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1727 if (texture) IDirect3DTexture8_Release(texture);
1730 /* This test tests depth clamping / clipping behaviour:
1731 * - With software vertex processing, depth values are clamped to the
1732 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
1733 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
1734 * same as regular vertices here.
1735 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
1736 * Normal vertices are always clipped. Pretransformed vertices are
1737 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
1738 * - The viewport's MinZ/MaxZ is irrelevant for this.
1740 static void depth_clamp_test(IDirect3DDevice8 *device)
1742 const struct tvertex quad1[] =
1744 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1745 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1746 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1747 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1749 const struct tvertex quad2[] =
1751 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1752 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1753 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1754 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1756 const struct tvertex quad3[] =
1758 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1759 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1760 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1761 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1763 const struct tvertex quad4[] =
1765 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1766 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1767 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1768 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1770 const struct vertex quad5[] =
1772 { -0.5f, 0.5f, 10.0f, 0xff14f914},
1773 { 0.5f, 0.5f, 10.0f, 0xff14f914},
1774 { -0.5f, -0.5f, 10.0f, 0xff14f914},
1775 { 0.5f, -0.5f, 10.0f, 0xff14f914},
1777 const struct vertex quad6[] =
1779 { -1.0f, 0.5f, 10.0f, 0xfff91414},
1780 { 1.0f, 0.5f, 10.0f, 0xfff91414},
1781 { -1.0f, 0.25f, 10.0f, 0xfff91414},
1782 { 1.0f, 0.25f, 10.0f, 0xfff91414},
1785 D3DVIEWPORT8 vp;
1786 D3DCOLOR color;
1787 D3DCAPS8 caps;
1788 HRESULT hr;
1790 vp.X = 0;
1791 vp.Y = 0;
1792 vp.Width = 640;
1793 vp.Height = 480;
1794 vp.MinZ = 0.0;
1795 vp.MaxZ = 7.5;
1797 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1798 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1800 hr = IDirect3DDevice8_SetViewport(device, &vp);
1801 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1803 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
1804 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1806 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1807 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1808 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1809 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1810 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1811 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1812 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1815 hr = IDirect3DDevice8_BeginScene(device);
1816 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1818 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1819 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
1821 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1823 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1824 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1826 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1827 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1829 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1831 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
1832 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1834 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1835 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1836 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1837 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1839 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
1840 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1842 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1843 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1845 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
1846 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1848 hr = IDirect3DDevice8_EndScene(device);
1849 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1851 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1853 color = getPixelColor(device, 75, 75);
1854 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1855 color = getPixelColor(device, 150, 150);
1856 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1857 color = getPixelColor(device, 320, 240);
1858 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1859 color = getPixelColor(device, 320, 330);
1860 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1861 color = getPixelColor(device, 320, 330);
1862 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1864 else
1866 color = getPixelColor(device, 75, 75);
1867 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1868 color = getPixelColor(device, 150, 150);
1869 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1870 color = getPixelColor(device, 320, 240);
1871 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
1872 color = getPixelColor(device, 320, 330);
1873 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1874 color = getPixelColor(device, 320, 330);
1875 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1878 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1879 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1881 vp.MinZ = 0.0;
1882 vp.MaxZ = 1.0;
1883 hr = IDirect3DDevice8_SetViewport(device, &vp);
1884 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1887 static void depth_buffer_test(IDirect3DDevice8 *device)
1889 static const struct vertex quad1[] =
1891 { -1.0, 1.0, 0.33f, 0xff00ff00},
1892 { 1.0, 1.0, 0.33f, 0xff00ff00},
1893 { -1.0, -1.0, 0.33f, 0xff00ff00},
1894 { 1.0, -1.0, 0.33f, 0xff00ff00},
1896 static const struct vertex quad2[] =
1898 { -1.0, 1.0, 0.50f, 0xffff00ff},
1899 { 1.0, 1.0, 0.50f, 0xffff00ff},
1900 { -1.0, -1.0, 0.50f, 0xffff00ff},
1901 { 1.0, -1.0, 0.50f, 0xffff00ff},
1903 static const struct vertex quad3[] =
1905 { -1.0, 1.0, 0.66f, 0xffff0000},
1906 { 1.0, 1.0, 0.66f, 0xffff0000},
1907 { -1.0, -1.0, 0.66f, 0xffff0000},
1908 { 1.0, -1.0, 0.66f, 0xffff0000},
1910 static const DWORD expected_colors[4][4] =
1912 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1913 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1914 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
1915 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
1918 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
1919 IDirect3DSurface8 *depth_stencil;
1920 unsigned int i, j;
1921 D3DVIEWPORT8 vp;
1922 D3DCOLOR color;
1923 HRESULT hr;
1925 vp.X = 0;
1926 vp.Y = 0;
1927 vp.Width = 640;
1928 vp.Height = 480;
1929 vp.MinZ = 0.0;
1930 vp.MaxZ = 1.0;
1932 hr = IDirect3DDevice8_SetViewport(device, &vp);
1933 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1935 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1936 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1937 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1938 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1939 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1940 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1941 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1942 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1943 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1944 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1946 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1947 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1948 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1949 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1950 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
1951 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1952 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1953 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1954 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1955 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1956 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1957 D3DMULTISAMPLE_NONE, FALSE, &rt3);
1958 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1960 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
1961 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1962 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
1963 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1965 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1966 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1967 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1968 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1970 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1971 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1972 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1973 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1975 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1976 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1977 hr = IDirect3DDevice8_BeginScene(device);
1978 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1979 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1980 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1981 hr = IDirect3DDevice8_EndScene(device);
1982 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1984 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1985 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1986 IDirect3DSurface8_Release(depth_stencil);
1987 IDirect3DSurface8_Release(backbuffer);
1988 IDirect3DSurface8_Release(rt3);
1989 IDirect3DSurface8_Release(rt2);
1990 IDirect3DSurface8_Release(rt1);
1992 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1993 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1995 hr = IDirect3DDevice8_BeginScene(device);
1996 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1997 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1998 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1999 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
2000 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2001 hr = IDirect3DDevice8_EndScene(device);
2002 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2004 for (i = 0; i < 4; ++i)
2006 for (j = 0; j < 4; ++j)
2008 unsigned int x = 80 * ((2 * j) + 1);
2009 unsigned int y = 60 * ((2 * i) + 1);
2010 color = getPixelColor(device, x, y);
2011 ok(color_match(color, expected_colors[i][j], 0),
2012 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
2016 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2017 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2020 /* Test that partial depth copies work the way they're supposed to. The clear
2021 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2022 * the following draw should only copy back the part that was modified. */
2023 static void depth_buffer2_test(IDirect3DDevice8 *device)
2025 static const struct vertex quad[] =
2027 { -1.0, 1.0, 0.66f, 0xffff0000},
2028 { 1.0, 1.0, 0.66f, 0xffff0000},
2029 { -1.0, -1.0, 0.66f, 0xffff0000},
2030 { 1.0, -1.0, 0.66f, 0xffff0000},
2033 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
2034 IDirect3DSurface8 *depth_stencil;
2035 unsigned int i, j;
2036 D3DVIEWPORT8 vp;
2037 D3DCOLOR color;
2038 HRESULT hr;
2040 vp.X = 0;
2041 vp.Y = 0;
2042 vp.Width = 640;
2043 vp.Height = 480;
2044 vp.MinZ = 0.0;
2045 vp.MaxZ = 1.0;
2047 hr = IDirect3DDevice8_SetViewport(device, &vp);
2048 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2050 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2051 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2052 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2053 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2054 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2056 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2058 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2059 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2061 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2062 D3DMULTISAMPLE_NONE, FALSE, &rt1);
2063 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2064 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
2065 D3DMULTISAMPLE_NONE, FALSE, &rt2);
2066 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2067 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
2068 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2069 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
2070 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2072 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
2073 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2074 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2075 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2077 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2078 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2079 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
2080 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2082 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
2083 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2084 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
2085 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2087 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2088 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2089 IDirect3DSurface8_Release(depth_stencil);
2090 IDirect3DSurface8_Release(backbuffer);
2091 IDirect3DSurface8_Release(rt2);
2092 IDirect3DSurface8_Release(rt1);
2094 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2095 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2097 hr = IDirect3DDevice8_BeginScene(device);
2098 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2099 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2100 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2101 hr = IDirect3DDevice8_EndScene(device);
2102 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2104 for (i = 0; i < 4; ++i)
2106 for (j = 0; j < 4; ++j)
2108 unsigned int x = 80 * ((2 * j) + 1);
2109 unsigned int y = 60 * ((2 * i) + 1);
2110 color = getPixelColor(device, x, y);
2111 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
2112 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
2116 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2117 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2120 static void intz_test(IDirect3DDevice8 *device)
2122 static const DWORD ps_code[] =
2124 0xffff0101, /* ps_1_1 */
2125 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2126 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2127 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2128 0x00000042, 0xb00f0000, /* tex t0 */
2129 0x00000042, 0xb00f0001, /* tex t1 */
2130 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2131 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2132 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2133 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2134 0x0000ffff, /* end */
2136 struct
2138 float x, y, z;
2139 float s0, t0, p0;
2140 float s1, t1, p1, q1;
2142 quad[] =
2144 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2145 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2146 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2147 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2149 half_quad_1[] =
2151 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2152 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2153 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2154 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2156 half_quad_2[] =
2158 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2159 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2160 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2161 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2163 struct
2165 UINT x, y;
2166 D3DCOLOR color;
2168 expected_colors[] =
2170 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2171 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2172 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2173 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2174 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2175 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2176 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2177 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2180 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2181 IDirect3DTexture8 *texture;
2182 IDirect3DSurface8 *ds;
2183 IDirect3D8 *d3d8;
2184 D3DCAPS8 caps;
2185 HRESULT hr;
2186 DWORD ps;
2187 UINT i;
2189 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2190 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2191 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2193 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
2194 return;
2196 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2198 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2199 return;
2202 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2203 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2205 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2206 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2207 if (FAILED(hr))
2209 skip("No INTZ support, skipping INTZ test.\n");
2210 return;
2213 IDirect3D8_Release(d3d8);
2215 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2216 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2217 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2218 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2220 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2221 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2222 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2223 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2224 D3DMULTISAMPLE_NONE, FALSE, &rt);
2225 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2226 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2227 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2229 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2230 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2231 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2232 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2233 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2234 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2236 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2238 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2241 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2242 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2243 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2244 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2245 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2246 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2247 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2248 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2250 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2251 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2252 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2253 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2254 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2255 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2256 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2257 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2258 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2259 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2260 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2261 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2262 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2264 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2265 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2267 /* Render offscreen, using the INTZ texture as depth buffer */
2268 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2269 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2270 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2271 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2273 /* Setup the depth/stencil surface. */
2274 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2275 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2277 hr = IDirect3DDevice8_BeginScene(device);
2278 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2279 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2280 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2281 hr = IDirect3DDevice8_EndScene(device);
2282 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2284 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2285 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2286 IDirect3DSurface8_Release(ds);
2287 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2288 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2289 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2290 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2291 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2292 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2294 /* Read the depth values back. */
2295 hr = IDirect3DDevice8_BeginScene(device);
2296 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2297 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2298 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2299 hr = IDirect3DDevice8_EndScene(device);
2300 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2302 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2304 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2305 ok(color_match(color, expected_colors[i].color, 1),
2306 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2307 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2310 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2311 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2313 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2314 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2315 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2316 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2317 IDirect3DTexture8_Release(texture);
2319 /* Render onscreen while using the INTZ texture as depth buffer */
2320 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2321 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2322 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2323 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2324 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2325 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2326 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2327 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2328 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2330 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2331 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2333 hr = IDirect3DDevice8_BeginScene(device);
2334 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2335 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2336 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2337 hr = IDirect3DDevice8_EndScene(device);
2338 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2340 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2341 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2342 IDirect3DSurface8_Release(ds);
2343 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2344 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2345 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2346 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2347 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2348 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2350 /* Read the depth values back. */
2351 hr = IDirect3DDevice8_BeginScene(device);
2352 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2353 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2354 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2355 hr = IDirect3DDevice8_EndScene(device);
2356 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2358 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2360 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2361 ok(color_match(color, expected_colors[i].color, 1),
2362 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2363 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2366 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2367 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2369 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2370 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2371 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2372 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2373 IDirect3DTexture8_Release(texture);
2375 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
2376 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2377 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2378 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2379 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2380 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2381 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2382 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2383 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2384 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2386 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2387 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2389 hr = IDirect3DDevice8_BeginScene(device);
2390 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2391 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
2392 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2393 hr = IDirect3DDevice8_EndScene(device);
2394 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2396 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2397 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2399 hr = IDirect3DDevice8_BeginScene(device);
2400 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2401 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
2402 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2403 hr = IDirect3DDevice8_EndScene(device);
2404 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2406 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2407 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2408 IDirect3DSurface8_Release(ds);
2409 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2410 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2411 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2412 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2413 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2414 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2416 /* Read the depth values back. */
2417 hr = IDirect3DDevice8_BeginScene(device);
2418 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2419 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2421 hr = IDirect3DDevice8_EndScene(device);
2422 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2424 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2426 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2427 ok(color_match(color, expected_colors[i].color, 1),
2428 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2429 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2432 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2433 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2435 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2436 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2437 IDirect3DSurface8_Release(original_ds);
2438 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2439 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2440 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2441 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2442 IDirect3DTexture8_Release(texture);
2443 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2444 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2445 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2446 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2448 IDirect3DSurface8_Release(original_rt);
2449 IDirect3DSurface8_Release(rt);
2452 static void shadow_test(IDirect3DDevice8 *device)
2454 static const DWORD ps_code[] =
2456 0xffff0101, /* ps_1_1 */
2457 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2458 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2459 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2460 0x00000042, 0xb00f0000, /* tex t0 */
2461 0x00000042, 0xb00f0001, /* tex t1 */
2462 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2463 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2464 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2465 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2466 0x0000ffff, /* end */
2468 struct
2470 D3DFORMAT format;
2471 const char *name;
2473 formats[] =
2475 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
2476 {D3DFMT_D32, "D3DFMT_D32"},
2477 {D3DFMT_D15S1, "D3DFMT_D15S1"},
2478 {D3DFMT_D24S8, "D3DFMT_D24S8"},
2479 {D3DFMT_D24X8, "D3DFMT_D24X8"},
2480 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
2481 {D3DFMT_D16, "D3DFMT_D16"},
2483 struct
2485 float x, y, z;
2486 float s0, t0, p0;
2487 float s1, t1, p1, q1;
2489 quad[] =
2491 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2492 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2493 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2494 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2496 struct
2498 UINT x, y;
2499 D3DCOLOR color;
2501 expected_colors[] =
2503 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2504 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2505 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2506 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2507 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2508 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2509 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2510 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2513 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2514 IDirect3D8 *d3d8;
2515 D3DCAPS8 caps;
2516 HRESULT hr;
2517 DWORD ps;
2518 UINT i;
2520 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2521 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2522 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2524 skip("No pixel shader 1.1 support, skipping shadow test.\n");
2525 return;
2528 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2529 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2530 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2531 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2532 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2533 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2535 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2536 D3DMULTISAMPLE_NONE, FALSE, &rt);
2537 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2538 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2539 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2541 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2542 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2543 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2544 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2545 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2546 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2547 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2548 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2550 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2553 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2554 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2555 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2556 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2557 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2558 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2559 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2560 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2562 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2563 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2564 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2565 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2566 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2567 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2568 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2569 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2570 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2571 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2572 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2573 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2574 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2576 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2578 D3DFORMAT format = formats[i].format;
2579 IDirect3DTexture8 *texture;
2580 IDirect3DSurface8 *ds;
2581 unsigned int j;
2583 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2584 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2585 if (FAILED(hr)) continue;
2587 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2588 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2589 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2591 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2592 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2594 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2595 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2597 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2598 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2600 /* Setup the depth/stencil surface. */
2601 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2602 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2604 hr = IDirect3DDevice8_BeginScene(device);
2605 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2606 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2608 hr = IDirect3DDevice8_EndScene(device);
2609 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2611 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2612 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2613 IDirect3DSurface8_Release(ds);
2615 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2616 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2617 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2618 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2620 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2621 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2623 /* Do the actual shadow mapping. */
2624 hr = IDirect3DDevice8_BeginScene(device);
2625 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2626 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2627 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2628 hr = IDirect3DDevice8_EndScene(device);
2629 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2631 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2632 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2633 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2634 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2635 IDirect3DTexture8_Release(texture);
2637 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2639 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2640 ok(color_match(color, expected_colors[j].color, 0),
2641 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2642 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2643 formats[i].name, color);
2646 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2647 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2650 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2651 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2652 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2653 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2655 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2656 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2657 IDirect3DSurface8_Release(original_ds);
2659 IDirect3DSurface8_Release(original_rt);
2660 IDirect3DSurface8_Release(rt);
2662 IDirect3D8_Release(d3d8);
2665 static void multisample_copy_rects_test(IDirect3DDevice8 *device)
2667 IDirect3DSurface8 *original_ds, *original_rt, *ds, *ds_plain, *rt, *readback;
2668 RECT src_rect = {64, 64, 128, 128};
2669 POINT dst_point = {96, 96};
2670 D3DLOCKED_RECT locked_rect;
2671 IDirect3D8 *d3d8;
2672 D3DCOLOR color;
2673 HRESULT hr;
2675 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2676 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2677 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2678 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2679 IDirect3D8_Release(d3d8);
2680 if (FAILED(hr))
2682 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
2683 return;
2686 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
2687 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2688 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2689 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2690 D3DMULTISAMPLE_2_SAMPLES, &ds);
2691 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2692 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2693 D3DMULTISAMPLE_NONE, &ds_plain);
2694 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2695 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
2696 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
2698 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2699 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2700 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2701 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2703 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2704 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2706 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2707 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2709 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
2710 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2712 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
2713 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2715 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2716 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2718 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
2719 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2721 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
2722 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
2724 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
2725 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2727 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
2728 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
2730 hr = IDirect3DSurface8_UnlockRect(readback);
2731 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
2733 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2734 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
2736 IDirect3DSurface8_Release(original_ds);
2737 IDirect3DSurface8_Release(original_rt);
2738 IDirect3DSurface8_Release(readback);
2739 IDirect3DSurface8_Release(ds_plain);
2740 IDirect3DSurface8_Release(ds);
2741 IDirect3DSurface8_Release(rt);
2744 static void resz_test(IDirect3DDevice8 *device)
2746 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
2747 IDirect3D8 *d3d8;
2748 D3DCAPS8 caps;
2749 HRESULT hr;
2750 unsigned int i;
2751 static const DWORD ps_code[] =
2753 0xffff0101, /* ps_1_1 */
2754 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2755 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2756 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2757 0x00000042, 0xb00f0000, /* tex t0 */
2758 0x00000042, 0xb00f0001, /* tex t1 */
2759 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2760 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2761 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2762 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2763 0x0000ffff, /* end */
2765 struct
2767 float x, y, z;
2768 float s0, t0, p0;
2769 float s1, t1, p1, q1;
2771 quad[] =
2773 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2774 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2775 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2776 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2778 struct
2780 UINT x, y;
2781 D3DCOLOR color;
2783 expected_colors[] =
2785 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2786 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2787 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2788 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2789 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2790 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2791 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2792 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2794 IDirect3DTexture8 *texture;
2795 DWORD ps, value;
2797 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2798 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2799 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2800 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2801 if (FAILED(hr))
2803 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
2804 return;
2806 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2807 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2808 if (FAILED(hr))
2810 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
2811 return;
2813 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2814 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2815 if (FAILED(hr))
2817 skip("No INTZ support, skipping RESZ test.\n");
2818 return;
2820 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2821 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
2822 if (FAILED(hr))
2824 skip("No RESZ support, skipping RESZ test.\n");
2825 return;
2827 IDirect3D8_Release(d3d8);
2829 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2830 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2831 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2833 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2834 return;
2837 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2838 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2839 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2840 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2842 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2843 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2844 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2845 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2846 D3DMULTISAMPLE_2_SAMPLES, &ds);
2848 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2849 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2850 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2851 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
2852 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2854 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
2855 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2856 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
2857 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2859 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2860 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2861 IDirect3DSurface8_Release(intz_ds);
2862 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2863 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2865 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2866 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2867 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2868 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2869 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2870 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2871 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2872 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2873 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2874 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2875 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2877 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2878 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2879 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2880 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2881 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2882 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2883 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2884 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2886 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2887 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2888 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2889 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2890 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2891 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2892 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2893 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2894 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2895 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2896 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2897 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2898 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2900 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
2901 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2902 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2904 hr = IDirect3DDevice8_BeginScene(device);
2905 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2907 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2909 /* The destination depth texture has to be bound to sampler 0 */
2910 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2911 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2913 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
2914 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2915 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2916 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2918 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2919 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2920 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2921 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2922 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2923 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2924 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2925 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2926 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2927 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2929 /* The actual multisampled depth buffer resolve happens here */
2930 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2931 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2932 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
2933 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
2935 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2936 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2937 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2938 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2939 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2940 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2942 /* Read the depth values back. */
2943 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2944 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2945 hr = IDirect3DDevice8_EndScene(device);
2946 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2948 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2950 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2951 ok(color_match(color, expected_colors[i].color, 1),
2952 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2953 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2956 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2957 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2959 /* Test edge cases - try with no texture at all */
2960 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2961 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2962 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2963 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2964 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2965 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2967 hr = IDirect3DDevice8_BeginScene(device);
2968 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2969 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2970 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2971 hr = IDirect3DDevice8_EndScene(device);
2972 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2974 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2975 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2977 /* With a non-multisampled depth buffer */
2978 IDirect3DSurface8_Release(ds);
2979 IDirect3DSurface8_Release(rt);
2980 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2981 D3DMULTISAMPLE_NONE, &ds);
2983 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2984 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2985 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2986 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2988 hr = IDirect3DDevice8_BeginScene(device);
2989 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2990 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2991 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2992 hr = IDirect3DDevice8_EndScene(device);
2993 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2995 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2996 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2998 hr = IDirect3DDevice8_BeginScene(device);
2999 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3000 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3001 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3002 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3003 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
3005 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3006 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3007 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3008 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
3009 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3010 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3011 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
3013 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3014 hr = IDirect3DDevice8_EndScene(device);
3015 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3017 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3018 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3020 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3021 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3022 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3023 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3025 /* Read the depth values back. */
3026 hr = IDirect3DDevice8_BeginScene(device);
3027 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3028 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3029 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3030 hr = IDirect3DDevice8_EndScene(device);
3031 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3033 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3035 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3036 ok(color_match(color, expected_colors[i].color, 1),
3037 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3038 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3041 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3042 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3044 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
3045 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3046 IDirect3DSurface8_Release(ds);
3047 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3048 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3049 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3050 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3051 IDirect3DTexture8_Release(texture);
3052 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3053 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3054 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3055 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3056 IDirect3DSurface8_Release(original_ds);
3057 IDirect3DSurface8_Release(original_rt);
3060 static void zenable_test(IDirect3DDevice8 *device)
3062 static const struct
3064 struct vec4 position;
3065 D3DCOLOR diffuse;
3067 tquad[] =
3069 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
3070 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
3071 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
3072 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
3074 D3DCOLOR color;
3075 D3DCAPS8 caps;
3076 HRESULT hr;
3077 UINT x, y;
3078 UINT i, j;
3080 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3081 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
3082 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3083 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3085 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3086 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3087 hr = IDirect3DDevice8_BeginScene(device);
3088 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3089 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
3090 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3091 hr = IDirect3DDevice8_EndScene(device);
3092 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3094 for (i = 0; i < 4; ++i)
3096 for (j = 0; j < 4; ++j)
3098 x = 80 * ((2 * j) + 1);
3099 y = 60 * ((2 * i) + 1);
3100 color = getPixelColor(device, x, y);
3101 ok(color_match(color, 0x0000ff00, 1),
3102 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
3106 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3107 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3109 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3110 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3112 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
3113 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3115 static const DWORD vs_code[] =
3117 0xfffe0101, /* vs_1_1 */
3118 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3119 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
3120 0x0000ffff
3122 static const DWORD ps_code[] =
3124 0xffff0101, /* ps_1_1 */
3125 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
3126 0x0000ffff /* end */
3128 static const struct vec3 quad[] =
3130 {-1.0f, -1.0f, -0.5f},
3131 {-1.0f, 1.0f, -0.5f},
3132 { 1.0f, -1.0f, 1.5f},
3133 { 1.0f, 1.0f, 1.5f},
3135 static const D3DCOLOR expected[] =
3137 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
3138 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
3139 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
3140 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
3142 static const DWORD decl[] =
3144 D3DVSD_STREAM(0),
3145 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
3146 D3DVSD_END()
3148 DWORD vs, ps;
3150 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
3151 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3152 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3153 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
3154 hr = IDirect3DDevice8_SetVertexShader(device, vs);
3155 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3156 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3157 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3159 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3160 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3161 hr = IDirect3DDevice8_BeginScene(device);
3162 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3163 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3164 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3165 hr = IDirect3DDevice8_EndScene(device);
3166 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3168 for (i = 0; i < 4; ++i)
3170 for (j = 0; j < 4; ++j)
3172 x = 80 * ((2 * j) + 1);
3173 y = 60 * ((2 * i) + 1);
3174 color = getPixelColor(device, x, y);
3175 ok(color_match(color, expected[i * 4 + j], 1),
3176 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
3180 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3181 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3183 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3184 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3185 hr = IDirect3DDevice8_SetVertexShader(device, 0);
3186 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3187 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3188 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
3189 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
3190 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
3194 START_TEST(visual)
3196 IDirect3DDevice8 *device_ptr;
3197 HRESULT hr;
3198 DWORD color;
3199 D3DCAPS8 caps;
3201 d3d8_handle = LoadLibraryA("d3d8.dll");
3202 if (!d3d8_handle)
3204 win_skip("Could not load d3d8.dll\n");
3205 return;
3208 device_ptr = init_d3d8();
3209 if (!device_ptr)
3211 win_skip("Could not initialize direct3d\n");
3212 return;
3215 IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
3217 /* Check for the reliability of the returned data */
3218 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3219 if(FAILED(hr))
3221 skip("Clear failed, can't assure correctness of the test results\n");
3222 goto cleanup;
3225 color = getPixelColor(device_ptr, 1, 1);
3226 if(color !=0x00ff0000)
3228 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3229 goto cleanup;
3231 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3233 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3234 if(FAILED(hr))
3236 skip("Clear failed, can't assure correctness of the test results\n");
3237 goto cleanup;
3240 color = getPixelColor(device_ptr, 639, 479);
3241 if(color != 0x0000ddee)
3243 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3244 goto cleanup;
3246 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3248 /* Now run the real test */
3249 depth_clamp_test(device_ptr);
3250 lighting_test(device_ptr);
3251 clear_test(device_ptr);
3252 fog_test(device_ptr);
3253 present_test(device_ptr);
3254 offscreen_test(device_ptr);
3255 alpha_test(device_ptr);
3257 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3259 test_rcp_rsq(device_ptr);
3260 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
3261 fog_with_shader_test(device_ptr);
3263 else
3265 skip("No vs.1.1 support\n");
3268 p8_texture_test(device_ptr);
3269 texop_test(device_ptr);
3270 depth_buffer_test(device_ptr);
3271 depth_buffer2_test(device_ptr);
3272 intz_test(device_ptr);
3273 shadow_test(device_ptr);
3274 multisample_copy_rects_test(device_ptr);
3275 zenable_test(device_ptr);
3276 resz_test(device_ptr);
3278 cleanup:
3279 if(device_ptr) {
3280 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
3281 ULONG refcount;
3283 IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
3284 DestroyWindow(creation_parameters.hFocusWindow);
3285 refcount = IDirect3DDevice8_Release(device_ptr);
3286 ok(!refcount, "Device has %u references left\n", refcount);