push 15b96ea46b12fa9aa8d3d4072be1bf1f7af34661
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob3211076bb29c68760678dc276792557576adb2b4
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 c1 >>= 8; c2 >>= 8;
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 return TRUE;
62 /* Locks a given surface and returns the color at (x,y). It's the caller's
63 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 DWORD color;
67 HRESULT hr;
68 D3DSURFACE_DESC desc;
69 RECT rectToLock = {x, y, x+1, y+1};
70 D3DLOCKED_RECT lockedRect;
72 hr = IDirect3DSurface9_GetDesc(surface, &desc);
73 if(FAILED(hr)) /* This is not a test */
75 trace("Can't get the surface description, hr=%08x\n", hr);
76 return 0xdeadbeef;
79 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80 if(FAILED(hr)) /* This is not a test */
82 trace("Can't lock the surface, hr=%08x\n", hr);
83 return 0xdeadbeef;
85 switch(desc.Format) {
86 case D3DFMT_A8R8G8B8:
88 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89 break;
91 default:
92 trace("Error: unknown surface format: %d\n", desc.Format);
93 color = 0xdeadbeef;
94 break;
96 hr = IDirect3DSurface9_UnlockRect(surface);
97 if(FAILED(hr))
99 trace("Can't unlock the surface, hr=%08x\n", hr);
101 return color;
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 DWORD ret;
107 IDirect3DSurface9 *surf;
108 HRESULT hr;
109 D3DLOCKED_RECT lockedRect;
110 RECT rectToLock = {x, y, x+1, y+1};
112 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113 if(FAILED(hr) || !surf ) /* This is not a test */
115 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116 return 0xdeadbeef;
119 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120 if(FAILED(hr))
122 trace("Can't read the front buffer data, hr=%08x\n", hr);
123 ret = 0xdeadbeed;
124 goto out;
127 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128 if(FAILED(hr))
130 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131 ret = 0xdeadbeec;
132 goto out;
135 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136 * really important for these tests
138 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139 hr = IDirect3DSurface9_UnlockRect(surf);
140 if(FAILED(hr))
142 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
145 out:
146 if(surf) IDirect3DSurface9_Release(surf);
147 return ret;
150 static IDirect3DDevice9 *init_d3d9(void)
152 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153 IDirect3D9 *d3d9_ptr = 0;
154 IDirect3DDevice9 *device_ptr = 0;
155 D3DPRESENT_PARAMETERS present_parameters;
156 HRESULT hr;
157 D3DADAPTER_IDENTIFIER9 identifier;
159 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161 if (!d3d9_create) return NULL;
163 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
165 if (!d3d9_ptr) return NULL;
167 ZeroMemory(&present_parameters, sizeof(present_parameters));
168 present_parameters.Windowed = FALSE;
169 present_parameters.hDeviceWindow = create_window();
170 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
171 present_parameters.BackBufferWidth = 640;
172 present_parameters.BackBufferHeight = 480;
173 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
174 present_parameters.EnableAutoDepthStencil = TRUE;
175 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
177 memset(&identifier, 0, sizeof(identifier));
178 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
179 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
180 trace("Driver string: \"%s\"\n", identifier.Driver);
181 trace("Description string: \"%s\"\n", identifier.Description);
182 trace("Device name string: \"%s\"\n", identifier.DeviceName);
183 trace("Driver version %d.%d.%d.%d\n",
184 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
185 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
187 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
188 if(FAILED(hr)) {
189 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
190 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191 if(FAILED(hr)) {
192 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
195 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
197 return device_ptr;
200 struct vertex
202 float x, y, z;
203 DWORD diffuse;
206 struct tvertex
208 float x, y, z, rhw;
209 DWORD diffuse;
212 struct nvertex
214 float x, y, z;
215 float nx, ny, nz;
216 DWORD diffuse;
219 static void lighting_test(IDirect3DDevice9 *device)
221 HRESULT hr;
222 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
223 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
224 DWORD color;
226 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
227 0.0f, 1.0f, 0.0f, 0.0f,
228 0.0f, 0.0f, 1.0f, 0.0f,
229 0.0f, 0.0f, 0.0f, 1.0f };
231 struct vertex unlitquad[] =
233 {-1.0f, -1.0f, 0.1f, 0xffff0000},
234 {-1.0f, 0.0f, 0.1f, 0xffff0000},
235 { 0.0f, 0.0f, 0.1f, 0xffff0000},
236 { 0.0f, -1.0f, 0.1f, 0xffff0000},
238 struct vertex litquad[] =
240 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
241 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
242 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
243 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
245 struct nvertex unlitnquad[] =
247 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
248 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
249 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
250 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
252 struct nvertex litnquad[] =
254 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
255 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
256 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
257 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
259 WORD Indices[] = {0, 1, 2, 2, 3, 0};
261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
262 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
264 /* Setup some states that may cause issues */
265 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
266 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
267 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
268 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
269 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
270 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
272 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
274 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
276 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
278 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
280 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
282 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
286 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
288 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
290 hr = IDirect3DDevice9_SetFVF(device, fvf);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
293 hr = IDirect3DDevice9_BeginScene(device);
294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
295 if(hr == D3D_OK)
297 /* No lights are defined... That means, lit vertices should be entirely black */
298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
301 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
302 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
306 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
307 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
308 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
310 hr = IDirect3DDevice9_SetFVF(device, nfvf);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
314 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
315 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
316 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
317 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
320 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
321 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
322 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
323 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
325 IDirect3DDevice9_EndScene(device);
326 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
329 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
331 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
332 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
333 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
334 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
335 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
336 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
337 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
338 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
344 static void clear_test(IDirect3DDevice9 *device)
346 /* Tests the correctness of clearing parameters */
347 HRESULT hr;
348 D3DRECT rect[2];
349 D3DRECT rect_negneg;
350 DWORD color;
351 D3DVIEWPORT9 old_vp, vp;
352 RECT scissor;
353 DWORD oldColorWrite;
354 BOOL invalid_clear_failed = FALSE;
356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
357 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
359 /* Positive x, negative y */
360 rect[0].x1 = 0;
361 rect[0].y1 = 480;
362 rect[0].x2 = 320;
363 rect[0].y2 = 240;
365 /* Positive x, positive y */
366 rect[1].x1 = 0;
367 rect[1].y1 = 0;
368 rect[1].x2 = 320;
369 rect[1].y2 = 240;
370 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
371 * returns D3D_OK, but ignores the rectangle silently
373 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
374 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
375 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
377 /* negative x, negative y */
378 rect_negneg.x1 = 640;
379 rect_negneg.y1 = 240;
380 rect_negneg.x2 = 320;
381 rect_negneg.y2 = 0;
382 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
383 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
384 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
386 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
388 color = getPixelColor(device, 160, 360); /* lower left quad */
389 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
390 color = getPixelColor(device, 160, 120); /* upper left quad */
391 if(invalid_clear_failed) {
392 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
393 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
394 } else {
395 /* If the negative rectangle was dropped silently, the correct ones are cleared */
396 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
398 color = getPixelColor(device, 480, 360); /* lower right quad */
399 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
400 color = getPixelColor(device, 480, 120); /* upper right quad */
401 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
403 /* Test how the viewport affects clears */
404 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
405 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
406 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
407 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
409 vp.X = 160;
410 vp.Y = 120;
411 vp.Width = 160;
412 vp.Height = 120;
413 vp.MinZ = 0.0;
414 vp.MaxZ = 1.0;
415 hr = IDirect3DDevice9_SetViewport(device, &vp);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
417 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
418 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
420 vp.X = 320;
421 vp.Y = 240;
422 vp.Width = 320;
423 vp.Height = 240;
424 vp.MinZ = 0.0;
425 vp.MaxZ = 1.0;
426 hr = IDirect3DDevice9_SetViewport(device, &vp);
427 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
428 rect[0].x1 = 160;
429 rect[0].y1 = 120;
430 rect[0].x2 = 480;
431 rect[0].y2 = 360;
432 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
433 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
435 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
436 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
438 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
439 color = getPixelColor(device, 158, 118);
440 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
441 color = getPixelColor(device, 162, 118);
442 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
443 color = getPixelColor(device, 158, 122);
444 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
445 color = getPixelColor(device, 162, 122);
446 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
448 color = getPixelColor(device, 318, 238);
449 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
450 color = getPixelColor(device, 322, 238);
451 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
452 color = getPixelColor(device, 318, 242);
453 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
454 color = getPixelColor(device, 322, 242);
455 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
457 color = getPixelColor(device, 478, 358);
458 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
459 color = getPixelColor(device, 482, 358);
460 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
461 color = getPixelColor(device, 478, 362);
462 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
463 color = getPixelColor(device, 482, 362);
464 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
467 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
469 scissor.left = 160;
470 scissor.right = 480;
471 scissor.top = 120;
472 scissor.bottom = 360;
473 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
474 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
476 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
478 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
479 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
480 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
481 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
484 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
486 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
487 color = getPixelColor(device, 158, 118);
488 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
489 color = getPixelColor(device, 162, 118);
490 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
491 color = getPixelColor(device, 158, 122);
492 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
493 color = getPixelColor(device, 162, 122);
494 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
496 color = getPixelColor(device, 158, 358);
497 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
498 color = getPixelColor(device, 162, 358);
499 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
500 color = getPixelColor(device, 158, 358);
501 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
502 color = getPixelColor(device, 162, 362);
503 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
505 color = getPixelColor(device, 478, 118);
506 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
507 color = getPixelColor(device, 478, 122);
508 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
509 color = getPixelColor(device, 482, 122);
510 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
511 color = getPixelColor(device, 482, 358);
512 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
514 color = getPixelColor(device, 478, 358);
515 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
516 color = getPixelColor(device, 478, 362);
517 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
518 color = getPixelColor(device, 482, 358);
519 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
520 color = getPixelColor(device, 482, 362);
521 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
523 color = getPixelColor(device, 318, 238);
524 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
525 color = getPixelColor(device, 318, 242);
526 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
527 color = getPixelColor(device, 322, 238);
528 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
529 color = getPixelColor(device, 322, 242);
530 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
532 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
533 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
535 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
537 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
538 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
543 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
545 /* Colorwriteenable does not affect the clear */
546 color = getPixelColor(device, 320, 240);
547 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
550 typedef struct {
551 float in[4];
552 DWORD out;
553 } test_data_t;
556 * c7 mova ARGB mov ARGB
557 * -2.4 -2 0x00ffff00 -3 0x00ff0000
558 * -1.6 -2 0x00ffff00 -2 0x00ffff00
559 * -0.4 0 0x0000ffff -1 0x0000ff00
560 * 0.4 0 0x0000ffff 0 0x0000ffff
561 * 1.6 2 0x00ff00ff 1 0x000000ff
562 * 2.4 2 0x00ff00ff 2 0x00ff00ff
564 static void test_mova(IDirect3DDevice9 *device)
566 static const DWORD mova_test[] = {
567 0xfffe0200, /* vs_2_0 */
568 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
569 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
570 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
571 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
572 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
573 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
574 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
575 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
576 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
577 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
578 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
579 0x0000ffff /* END */
581 static const DWORD mov_test[] = {
582 0xfffe0101, /* vs_1_1 */
583 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
584 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
585 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
586 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
587 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
588 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
589 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
590 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
591 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
592 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
593 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
594 0x0000ffff /* END */
597 static const test_data_t test_data[2][6] = {
599 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
600 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
601 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
602 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
603 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
604 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
607 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
608 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
609 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
610 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
611 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
612 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
616 static const float quad[][3] = {
617 {-1.0f, -1.0f, 0.0f},
618 {-1.0f, 1.0f, 0.0f},
619 { 1.0f, -1.0f, 0.0f},
620 { 1.0f, 1.0f, 0.0f},
623 static const D3DVERTEXELEMENT9 decl_elements[] = {
624 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
625 D3DDECL_END()
628 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
629 IDirect3DVertexShader9 *mova_shader = NULL;
630 IDirect3DVertexShader9 *mov_shader = NULL;
631 HRESULT hr;
632 UINT i, j;
634 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
635 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
636 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
637 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
638 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
639 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
640 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
641 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
643 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
644 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
645 for(j = 0; j < 2; ++j)
647 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
649 DWORD color;
651 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
652 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
654 hr = IDirect3DDevice9_BeginScene(device);
655 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
658 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
660 hr = IDirect3DDevice9_EndScene(device);
661 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
663 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
664 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
666 color = getPixelColor(device, 320, 240);
667 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
668 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
671 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
673 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
674 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
677 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
678 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
680 IDirect3DVertexDeclaration9_Release(vertex_declaration);
681 IDirect3DVertexShader9_Release(mova_shader);
682 IDirect3DVertexShader9_Release(mov_shader);
685 struct sVertex {
686 float x, y, z;
687 DWORD diffuse;
688 DWORD specular;
691 struct sVertexT {
692 float x, y, z, rhw;
693 DWORD diffuse;
694 DWORD specular;
697 static void fog_test(IDirect3DDevice9 *device)
699 HRESULT hr;
700 DWORD color;
701 BYTE r, g, b;
702 float start = 0.0f, end = 1.0f;
703 D3DCAPS9 caps;
704 int i;
706 /* Gets full z based fog with linear fog, no fog with specular color */
707 struct sVertex unstransformed_1[] = {
708 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
709 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
710 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
711 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
713 /* Ok, I am too lazy to deal with transform matrices */
714 struct sVertex unstransformed_2[] = {
715 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
716 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
717 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
718 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
720 /* Untransformed ones. Give them a different diffuse color to make the test look
721 * nicer. It also makes making sure that they are drawn correctly easier.
723 struct sVertexT transformed_1[] = {
724 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
725 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
726 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
727 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
729 struct sVertexT transformed_2[] = {
730 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
731 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
732 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
733 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
735 struct vertex rev_fog_quads[] = {
736 {-1.0, -1.0, 0.1, 0x000000ff},
737 {-1.0, 0.0, 0.1, 0x000000ff},
738 { 0.0, 0.0, 0.1, 0x000000ff},
739 { 0.0, -1.0, 0.1, 0x000000ff},
741 { 0.0, -1.0, 0.9, 0x000000ff},
742 { 0.0, 0.0, 0.9, 0x000000ff},
743 { 1.0, 0.0, 0.9, 0x000000ff},
744 { 1.0, -1.0, 0.9, 0x000000ff},
746 { 0.0, 0.0, 0.4, 0x000000ff},
747 { 0.0, 1.0, 0.4, 0x000000ff},
748 { 1.0, 1.0, 0.4, 0x000000ff},
749 { 1.0, 0.0, 0.4, 0x000000ff},
751 {-1.0, 0.0, 0.7, 0x000000ff},
752 {-1.0, 1.0, 0.7, 0x000000ff},
753 { 0.0, 1.0, 0.7, 0x000000ff},
754 { 0.0, 0.0, 0.7, 0x000000ff},
756 WORD Indices[] = {0, 1, 2, 2, 3, 0};
758 memset(&caps, 0, sizeof(caps));
759 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
760 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
762 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
764 /* Setup initial states: No lighting, fog on, fog color */
765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
766 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
767 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
768 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
770 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
772 /* First test: Both table fog and vertex fog off */
773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
774 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
775 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
776 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
778 /* Start = 0, end = 1. Should be default, but set them */
779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
780 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
782 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
784 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
786 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
787 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
788 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
789 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
790 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
791 sizeof(unstransformed_1[0]));
792 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
794 /* That makes it use the Z value */
795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
796 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
797 /* Untransformed, vertex fog != none (or table fog != none):
798 * Use the Z value as input into the equation
800 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
801 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
802 sizeof(unstransformed_1[0]));
803 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
805 /* transformed verts */
806 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
807 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
808 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
809 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
810 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
811 sizeof(transformed_1[0]));
812 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
815 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
816 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
817 * equation
819 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
820 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
821 sizeof(transformed_2[0]));
823 hr = IDirect3DDevice9_EndScene(device);
824 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
826 else
828 ok(FALSE, "BeginScene failed\n");
831 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
832 color = getPixelColor(device, 160, 360);
833 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
834 color = getPixelColor(device, 160, 120);
835 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
836 color = getPixelColor(device, 480, 120);
837 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
838 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
840 color = getPixelColor(device, 480, 360);
841 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
843 else
845 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
846 * The settings above result in no fogging with vertex fog
848 color = getPixelColor(device, 480, 120);
849 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
850 trace("Info: Table fog not supported by this device\n");
853 /* Now test the special case fogstart == fogend */
854 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
855 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
857 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
859 start = 512;
860 end = 512;
861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
862 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
864 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
867 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
869 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
871 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
873 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
874 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
875 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
876 * The third transformed quad remains unfogged because the fogcoords are read from the specular
877 * color and has fixed fogstart and fogend.
879 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
880 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
881 sizeof(unstransformed_1[0]));
882 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
883 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
884 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
885 sizeof(unstransformed_1[0]));
886 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
888 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
889 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
890 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
891 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
892 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
893 sizeof(transformed_1[0]));
894 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
896 hr = IDirect3DDevice9_EndScene(device);
897 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
899 else
901 ok(FALSE, "BeginScene failed\n");
903 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
904 color = getPixelColor(device, 160, 360);
905 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
906 color = getPixelColor(device, 160, 120);
907 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
908 color = getPixelColor(device, 480, 120);
909 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
911 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
912 * but without shaders it seems to work everywhere
914 end = 0.2;
915 start = 0.8;
916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
917 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
919 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
921 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
923 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
924 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
925 * so skip this for now
927 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
928 const char *mode = (i ? "table" : "vertex");
929 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
930 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
932 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
934 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
935 hr = IDirect3DDevice9_BeginScene(device);
936 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
937 if(SUCCEEDED(hr)) {
938 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
939 4, 5, 6, 6, 7, 4,
940 8, 9, 10, 10, 11, 8,
941 12, 13, 14, 14, 15, 12};
943 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
944 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
945 sizeof(rev_fog_quads[0]));
947 hr = IDirect3DDevice9_EndScene(device);
948 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
950 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
951 color = getPixelColor(device, 160, 360);
952 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
954 color = getPixelColor(device, 160, 120);
955 r = (color & 0x00ff0000) >> 16;
956 g = (color & 0x0000ff00) >> 8;
957 b = (color & 0x000000ff);
958 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
959 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
961 color = getPixelColor(device, 480, 120);
962 r = (color & 0x00ff0000) >> 16;
963 g = (color & 0x0000ff00) >> 8;
964 b = (color & 0x000000ff);
965 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
966 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
968 color = getPixelColor(device, 480, 360);
969 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
971 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
972 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
973 break;
976 /* Turn off the fog master switch to avoid confusing other tests */
977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
978 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
979 start = 0.0;
980 end = 1.0;
981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
982 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
983 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
984 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
986 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
988 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
991 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
992 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
993 * regardless of the actual addressing mode set. */
994 static void test_cube_wrap(IDirect3DDevice9 *device)
996 static const float quad[][6] = {
997 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
998 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
999 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1000 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1003 static const D3DVERTEXELEMENT9 decl_elements[] = {
1004 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1005 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1006 D3DDECL_END()
1009 static const struct {
1010 D3DTEXTUREADDRESS mode;
1011 const char *name;
1012 } address_modes[] = {
1013 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1014 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1015 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1016 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1017 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1020 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1021 IDirect3DCubeTexture9 *texture = NULL;
1022 IDirect3DSurface9 *surface = NULL;
1023 D3DLOCKED_RECT locked_rect;
1024 HRESULT hr;
1025 UINT x;
1026 INT y, face;
1028 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1029 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1030 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1031 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1033 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1034 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1035 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1037 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1038 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1040 for (y = 0; y < 128; ++y)
1042 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1043 for (x = 0; x < 64; ++x)
1045 *ptr++ = 0xffff0000;
1047 for (x = 64; x < 128; ++x)
1049 *ptr++ = 0xff0000ff;
1053 hr = IDirect3DSurface9_UnlockRect(surface);
1054 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1056 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1057 D3DPOOL_DEFAULT, &texture, NULL);
1058 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1060 /* Create cube faces */
1061 for (face = 0; face < 6; ++face)
1063 IDirect3DSurface9 *face_surface = NULL;
1065 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1066 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1068 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1069 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1071 IDirect3DSurface9_Release(face_surface);
1074 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1075 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1077 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1078 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1079 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1080 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1081 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1082 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1085 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1087 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1089 DWORD color;
1091 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1092 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1093 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1094 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1096 hr = IDirect3DDevice9_BeginScene(device);
1097 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1100 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1102 hr = IDirect3DDevice9_EndScene(device);
1103 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1106 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1108 /* Due to the nature of this test, we sample essentially at the edge
1109 * between two faces. Because of this it's undefined from which face
1110 * the driver will sample. Fortunately that's not important for this
1111 * test, since all we care about is that it doesn't sample from the
1112 * other side of the surface or from the border. */
1113 color = getPixelColor(device, 320, 240);
1114 ok(color == 0x00ff0000 || color == 0x000000ff,
1115 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1116 color, address_modes[x].name);
1118 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1119 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1122 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1123 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1125 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1126 IDirect3DCubeTexture9_Release(texture);
1127 IDirect3DSurface9_Release(surface);
1130 static void offscreen_test(IDirect3DDevice9 *device)
1132 HRESULT hr;
1133 IDirect3DTexture9 *offscreenTexture = NULL;
1134 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1135 DWORD color;
1137 static const float quad[][5] = {
1138 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1139 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1140 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1141 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1144 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1145 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1147 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1148 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1149 if(!offscreenTexture) {
1150 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1151 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1152 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1153 if(!offscreenTexture) {
1154 skip("Cannot create an offscreen render target\n");
1155 goto out;
1159 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1160 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1161 if(!backbuffer) {
1162 goto out;
1165 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1166 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1167 if(!offscreen) {
1168 goto out;
1171 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1172 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1174 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1175 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1176 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1177 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1178 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1179 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1180 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1181 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1183 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1185 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1186 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1187 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1189 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1191 /* Draw without textures - Should result in a white quad */
1192 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1193 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1195 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1196 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1197 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1198 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1200 /* This time with the texture */
1201 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1202 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1204 IDirect3DDevice9_EndScene(device);
1207 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1209 /* Center quad - should be white */
1210 color = getPixelColor(device, 320, 240);
1211 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1212 /* Some quad in the cleared part of the texture */
1213 color = getPixelColor(device, 170, 240);
1214 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1215 /* Part of the originally cleared back buffer */
1216 color = getPixelColor(device, 10, 10);
1217 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1218 if(0) {
1219 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1220 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1221 * the offscreen rendering mode this test would succeed or fail
1223 color = getPixelColor(device, 10, 470);
1224 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1227 out:
1228 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1230 /* restore things */
1231 if(backbuffer) {
1232 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1233 IDirect3DSurface9_Release(backbuffer);
1235 if(offscreenTexture) {
1236 IDirect3DTexture9_Release(offscreenTexture);
1238 if(offscreen) {
1239 IDirect3DSurface9_Release(offscreen);
1243 /* This test tests fog in combination with shaders.
1244 * What's tested: linear fog (vertex and table) with pixel shader
1245 * linear table fog with non foggy vertex shader
1246 * vertex fog with foggy vertex shader
1247 * What's not tested: non linear fog with shader
1248 * table fog with foggy vertex shader
1250 static void fog_with_shader_test(IDirect3DDevice9 *device)
1252 HRESULT hr;
1253 DWORD color;
1254 union {
1255 float f;
1256 DWORD i;
1257 } start, end;
1258 unsigned int i, j;
1260 /* basic vertex shader without fog computation ("non foggy") */
1261 static const DWORD vertex_shader_code1[] = {
1262 0xfffe0101, /* vs_1_1 */
1263 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1264 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1265 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1266 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1267 0x0000ffff
1269 /* basic vertex shader with reversed fog computation ("foggy") */
1270 static const DWORD vertex_shader_code2[] = {
1271 0xfffe0101, /* vs_1_1 */
1272 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1273 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1274 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1275 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1276 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1277 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1278 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1279 0x0000ffff
1281 /* basic pixel shader */
1282 static const DWORD pixel_shader_code[] = {
1283 0xffff0101, /* ps_1_1 */
1284 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1285 0x0000ffff
1288 static struct vertex quad[] = {
1289 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1290 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1291 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1292 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1295 static const D3DVERTEXELEMENT9 decl_elements[] = {
1296 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1297 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1298 D3DDECL_END()
1301 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1302 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1303 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1305 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1306 static const struct test_data_t {
1307 int vshader;
1308 int pshader;
1309 D3DFOGMODE vfog;
1310 D3DFOGMODE tfog;
1311 unsigned int color[11];
1312 } test_data[] = {
1313 /* only pixel shader: */
1314 {0, 1, 0, 3,
1315 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1316 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1317 {0, 1, 1, 3,
1318 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1319 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1320 {0, 1, 2, 3,
1321 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1322 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1323 {0, 1, 3, 0,
1324 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1325 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1326 {0, 1, 3, 3,
1327 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1328 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1330 /* vertex shader */
1331 {1, 0, 0, 0,
1332 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1333 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1334 {1, 0, 0, 3,
1335 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1336 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1337 {1, 0, 1, 3,
1338 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1339 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1341 {1, 0, 2, 3,
1342 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1343 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1344 {1, 0, 3, 3,
1345 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1346 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1348 /* vertex shader and pixel shader */
1349 {1, 1, 0, 3,
1350 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1351 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1352 {1, 1, 1, 3,
1353 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1354 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1355 {1, 1, 2, 3,
1356 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1357 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1359 {1, 1, 3, 3,
1360 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1361 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1364 #if 0 /* FIXME: these fail on GeForce 8500 */
1365 /* foggy vertex shader */
1366 {2, 0, 0, 0,
1367 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1368 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1369 {2, 0, 1, 0,
1370 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1371 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1372 {2, 0, 2, 0,
1373 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1374 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1375 {2, 0, 3, 0,
1376 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1377 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1378 #endif
1380 /* foggy vertex shader and pixel shader */
1381 {2, 1, 0, 0,
1382 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1383 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1384 {2, 1, 1, 0,
1385 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1386 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1387 {2, 1, 2, 0,
1388 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1389 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1390 {2, 1, 3, 0,
1391 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1392 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1396 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1397 start.f=0.1f;
1398 end.f=0.9f;
1400 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1401 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1402 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1403 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1404 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1405 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1406 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1407 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1409 /* Setup initial states: No lighting, fog on, fog color */
1410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1411 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1413 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1414 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1415 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1416 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1417 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1420 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1422 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1424 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1426 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1427 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1428 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1430 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1432 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1433 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1434 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1435 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1437 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1439 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1441 for(j=0; j < 11; j++)
1443 /* Don't use the whole zrange to prevent rounding errors */
1444 quad[0].z = 0.001f + (float)j / 10.02f;
1445 quad[1].z = 0.001f + (float)j / 10.02f;
1446 quad[2].z = 0.001f + (float)j / 10.02f;
1447 quad[3].z = 0.001f + (float)j / 10.02f;
1449 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1450 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1452 hr = IDirect3DDevice9_BeginScene(device);
1453 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1456 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1458 hr = IDirect3DDevice9_EndScene(device);
1459 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1461 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1463 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1464 color = getPixelColor(device, 128, 240);
1465 ok(color_match(color, test_data[i].color[j], 13),
1466 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1467 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1471 /* reset states */
1472 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1473 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1474 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1475 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1476 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1477 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1478 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1479 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1481 IDirect3DVertexShader9_Release(vertex_shader[1]);
1482 IDirect3DVertexShader9_Release(vertex_shader[2]);
1483 IDirect3DPixelShader9_Release(pixel_shader[1]);
1484 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1487 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1488 unsigned int i, x, y;
1489 HRESULT hr;
1490 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1491 D3DLOCKED_RECT locked_rect;
1493 /* Generate the textures */
1494 for(i=0; i<2; i++)
1496 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1497 D3DPOOL_MANAGED, &texture[i], NULL);
1498 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1500 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1501 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1502 for (y = 0; y < 128; ++y)
1504 if(i)
1505 { /* Set up black texture with 2x2 texel white spot in the middle */
1506 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1507 for (x = 0; x < 128; ++x)
1509 if(y>62 && y<66 && x>62 && x<66)
1510 *ptr++ = 0xffffffff;
1511 else
1512 *ptr++ = 0xff000000;
1515 else
1516 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1517 * (if multiplied with bumpenvmat)
1519 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1520 for (x = 0; x < 128; ++x)
1522 if(abs(x-64)>abs(y-64))
1524 if(x < 64)
1525 *ptr++ = 0xc000;
1526 else
1527 *ptr++ = 0x4000;
1529 else
1531 if(y < 64)
1532 *ptr++ = 0x0040;
1533 else
1534 *ptr++ = 0x00c0;
1539 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1540 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1542 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1543 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1545 /* Disable texture filtering */
1546 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1547 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1549 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1551 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1552 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1553 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1554 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1558 /* test the behavior of the texbem instruction
1559 * with normal 2D and projective 2D textures
1561 static void texbem_test(IDirect3DDevice9 *device)
1563 HRESULT hr;
1564 DWORD color;
1565 int i;
1567 static const DWORD pixel_shader_code[] = {
1568 0xffff0101, /* ps_1_1*/
1569 0x00000042, 0xb00f0000, /* tex t0*/
1570 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1571 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1572 0x0000ffff
1574 static const DWORD double_texbem_code[] = {
1575 0xffff0103, /* ps_1_3 */
1576 0x00000042, 0xb00f0000, /* tex t0 */
1577 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1578 0x00000042, 0xb00f0002, /* tex t2 */
1579 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1580 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1581 0x0000ffff /* end */
1585 static const float quad[][7] = {
1586 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1587 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1588 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1589 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1591 static const float quad_proj[][9] = {
1592 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1593 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1594 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1595 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1598 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1599 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1600 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1601 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1602 D3DDECL_END()
1604 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1605 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1606 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1607 D3DDECL_END()
1608 } };
1610 /* use asymmetric matrix to test loading */
1611 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1613 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1614 IDirect3DPixelShader9 *pixel_shader = NULL;
1615 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1616 D3DLOCKED_RECT locked_rect;
1618 generate_bumpmap_textures(device);
1620 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1621 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1622 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1623 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1624 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1626 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1627 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1629 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1630 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1632 for(i=0; i<2; i++)
1634 if(i)
1636 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1637 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1640 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1641 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1642 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1643 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1645 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1646 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1647 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1648 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1650 hr = IDirect3DDevice9_BeginScene(device);
1651 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1653 if(!i)
1654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1655 else
1656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1657 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1659 hr = IDirect3DDevice9_EndScene(device);
1660 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1662 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1663 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1665 color = getPixelColor(device, 320-32, 240);
1666 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1667 color = getPixelColor(device, 320+32, 240);
1668 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669 color = getPixelColor(device, 320, 240-32);
1670 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1671 color = getPixelColor(device, 320, 240+32);
1672 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1674 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1675 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676 IDirect3DPixelShader9_Release(pixel_shader);
1678 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1679 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1680 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1683 /* clean up */
1684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1685 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1687 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1688 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1690 for(i=0; i<2; i++)
1692 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1693 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1694 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1695 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1696 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1697 IDirect3DTexture9_Release(texture);
1700 /* Test double texbem */
1701 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1702 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1703 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1704 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1705 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1706 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1707 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1708 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1710 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1711 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1712 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1713 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1715 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1716 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1718 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1719 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1720 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1721 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1722 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1723 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1726 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1727 #define tex 0x00ff0000
1728 #define tex1 0x0000ff00
1729 #define origin 0x000000ff
1730 static const DWORD pixel_data[] = {
1731 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1732 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1733 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1734 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1735 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1736 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1737 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1738 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1740 #undef tex1
1741 #undef tex2
1742 #undef origin
1744 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1745 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1746 for(i = 0; i < 8; i++) {
1747 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1749 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1750 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1753 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1754 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1755 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1756 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1757 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1758 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1759 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1760 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1761 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1762 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1763 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1764 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1766 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1767 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1768 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1769 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1770 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1771 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1773 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1774 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1775 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1776 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1777 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1778 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1780 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1781 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1782 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1783 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1784 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1785 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1786 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1787 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1789 hr = IDirect3DDevice9_BeginScene(device);
1790 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1791 if(SUCCEEDED(hr)) {
1792 static const float double_quad[] = {
1793 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1794 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1795 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1796 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1800 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1801 hr = IDirect3DDevice9_EndScene(device);
1802 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1805 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1806 color = getPixelColor(device, 320, 240);
1807 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1809 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1810 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1811 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1812 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1813 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1814 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1815 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1816 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1817 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1818 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1820 IDirect3DPixelShader9_Release(pixel_shader);
1821 IDirect3DTexture9_Release(texture);
1822 IDirect3DTexture9_Release(texture1);
1823 IDirect3DTexture9_Release(texture2);
1826 static void z_range_test(IDirect3DDevice9 *device)
1828 const struct vertex quad[] =
1830 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1831 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1832 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1833 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1835 const struct vertex quad2[] =
1837 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1838 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1839 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1840 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1843 const struct tvertex quad3[] =
1845 { 0, 240, 1.1f, 1.0, 0xffffff00},
1846 { 0, 480, 1.1f, 1.0, 0xffffff00},
1847 { 640, 240, -1.1f, 1.0, 0xffffff00},
1848 { 640, 480, -1.1f, 1.0, 0xffffff00},
1850 const struct tvertex quad4[] =
1852 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1853 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1854 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1855 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1857 HRESULT hr;
1858 DWORD color;
1859 IDirect3DVertexShader9 *shader;
1860 IDirect3DVertexDeclaration9 *decl;
1861 D3DCAPS9 caps;
1862 const DWORD shader_code[] = {
1863 0xfffe0101, /* vs_1_1 */
1864 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1865 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1866 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1867 0x0000ffff /* end */
1869 static const D3DVERTEXELEMENT9 decl_elements[] = {
1870 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1871 D3DDECL_END()
1873 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1874 * then call Present. Then clear the color buffer to make sure it has some defined content
1875 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1876 * by the depth value.
1878 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1879 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1880 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1887 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1888 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1889 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1890 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1891 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1892 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1894 hr = IDirect3DDevice9_BeginScene(device);
1895 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1896 if(hr == D3D_OK)
1898 /* Test the untransformed vertex path */
1899 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1900 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1901 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1902 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1903 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1904 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1906 /* Test the transformed vertex path */
1907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1908 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1911 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1913 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1915 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1917 hr = IDirect3DDevice9_EndScene(device);
1918 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1921 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1922 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1924 /* Do not test the exact corner pixels, but go pretty close to them */
1926 /* Clipped because z > 1.0 */
1927 color = getPixelColor(device, 28, 238);
1928 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1929 color = getPixelColor(device, 28, 241);
1930 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1932 /* Not clipped, > z buffer clear value(0.75) */
1933 color = getPixelColor(device, 31, 238);
1934 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1935 color = getPixelColor(device, 31, 241);
1936 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1937 color = getPixelColor(device, 100, 238);
1938 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1939 color = getPixelColor(device, 100, 241);
1940 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1942 /* Not clipped, < z buffer clear value */
1943 color = getPixelColor(device, 104, 238);
1944 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1945 color = getPixelColor(device, 104, 241);
1946 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1947 color = getPixelColor(device, 318, 238);
1948 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1949 color = getPixelColor(device, 318, 241);
1950 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1952 /* Clipped because z < 0.0 */
1953 color = getPixelColor(device, 321, 238);
1954 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1955 color = getPixelColor(device, 321, 241);
1956 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1958 /* Test the shader path */
1959 IDirect3DDevice9_GetDeviceCaps(device, &caps);
1960 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1961 skip("Vertex shaders not supported\n");
1962 goto out;
1964 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1965 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1966 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1967 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
1969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1971 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1972 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
1973 IDirect3DDevice9_SetVertexShader(device, shader);
1974 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
1976 hr = IDirect3DDevice9_BeginScene(device);
1977 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1978 if(hr == D3D_OK)
1980 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1981 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1982 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1984 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1986 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1987 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1989 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1991 hr = IDirect3DDevice9_EndScene(device);
1992 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1995 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1996 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
1997 IDirect3DDevice9_SetVertexShader(device, NULL);
1998 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2000 IDirect3DVertexDeclaration9_Release(decl);
2001 IDirect3DVertexShader9_Release(shader);
2003 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2004 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2005 /* Z < 1.0 */
2006 color = getPixelColor(device, 28, 238);
2007 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2009 /* 1.0 < z < 0.75 */
2010 color = getPixelColor(device, 31, 238);
2011 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2012 color = getPixelColor(device, 100, 238);
2013 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2015 /* 0.75 < z < 0.0 */
2016 color = getPixelColor(device, 104, 238);
2017 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2018 color = getPixelColor(device, 318, 238);
2019 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2021 /* 0.0 < z */
2022 color = getPixelColor(device, 321, 238);
2023 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2025 out:
2026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2027 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2028 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2029 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2030 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2031 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2034 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2036 D3DSURFACE_DESC desc;
2037 D3DLOCKED_RECT l;
2038 HRESULT hr;
2039 unsigned int x, y;
2040 DWORD *mem;
2042 memset(&desc, 0, sizeof(desc));
2043 memset(&l, 0, sizeof(l));
2044 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2045 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2046 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2047 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2048 if(FAILED(hr)) return;
2050 for(y = 0; y < desc.Height; y++)
2052 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2053 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2055 mem[x] = color;
2058 hr = IDirect3DSurface9_UnlockRect(surface);
2059 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2062 /* This tests a variety of possible StretchRect() situations */
2063 static void stretchrect_test(IDirect3DDevice9 *device)
2065 HRESULT hr;
2066 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2067 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2068 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2069 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2070 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2071 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2072 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2073 IDirect3DSurface9 *orig_rt = NULL;
2074 DWORD color;
2076 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2077 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2078 if(!orig_rt) {
2079 goto out;
2082 /* Create our temporary surfaces in system memory */
2083 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2084 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2085 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2086 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2088 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2089 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2090 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2091 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2092 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2093 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2094 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2096 /* Create render target surfaces */
2097 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2098 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2099 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2100 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2101 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2102 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2104 /* Create render target textures */
2105 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2106 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2107 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2108 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2109 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2110 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2111 if (tex_rt32) {
2112 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2113 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2115 if (tex_rt64) {
2116 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2117 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2119 if (tex_rt_dest64) {
2120 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2121 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2124 /* Create regular textures in D3DPOOL_DEFAULT */
2125 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2126 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2127 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2128 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2129 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2130 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2131 if (tex32) {
2132 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2133 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2135 if (tex64) {
2136 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2137 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2139 if (tex_dest64) {
2140 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2141 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2144 /*********************************************************************
2145 * Tests for when the source parameter is an offscreen plain surface *
2146 *********************************************************************/
2148 /* Fill the offscreen 64x64 surface with green */
2149 if (surf_offscreen64)
2150 fill_surface(surf_offscreen64, 0xff00ff00);
2152 /* offscreenplain ==> offscreenplain, same size */
2153 if(surf_offscreen64 && surf_offscreen_dest64) {
2154 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2155 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2157 if (hr == D3D_OK) {
2158 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2159 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2163 /* offscreenplain ==> rendertarget texture, same size */
2164 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2165 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2166 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2168 /* We can't lock rendertarget textures, so copy to our temp surface first */
2169 if (hr == D3D_OK) {
2170 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2171 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2174 if (hr == D3D_OK) {
2175 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2176 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2180 /* offscreenplain ==> rendertarget surface, same size */
2181 if(surf_offscreen64 && surf_rt_dest64) {
2182 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2183 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2185 if (hr == D3D_OK) {
2186 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2187 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2191 /* offscreenplain ==> texture, same size (should fail) */
2192 if(surf_offscreen64 && surf_tex_dest64) {
2193 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2194 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2197 /* Fill the smaller offscreen surface with red */
2198 fill_surface(surf_offscreen32, 0xffff0000);
2200 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2201 if(surf_offscreen32 && surf_offscreen64) {
2202 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2203 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2206 /* offscreenplain ==> rendertarget texture, scaling */
2207 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2208 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2209 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2211 /* We can't lock rendertarget textures, so copy to our temp surface first */
2212 if (hr == D3D_OK) {
2213 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2214 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2217 if (hr == D3D_OK) {
2218 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2219 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2223 /* offscreenplain ==> rendertarget surface, scaling */
2224 if(surf_offscreen32 && surf_rt_dest64) {
2225 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2226 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2228 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2229 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2232 /* offscreenplain ==> texture, scaling (should fail) */
2233 if(surf_offscreen32 && surf_tex_dest64) {
2234 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2235 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2238 /************************************************************
2239 * Tests for when the source parameter is a regular texture *
2240 ************************************************************/
2242 /* Fill the surface of the regular texture with blue */
2243 if (surf_tex64 && surf_temp64) {
2244 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2245 fill_surface(surf_temp64, 0xff0000ff);
2246 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2247 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2250 /* texture ==> offscreenplain, same size */
2251 if(surf_tex64 && surf_offscreen64) {
2252 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2253 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2256 /* texture ==> rendertarget texture, same size */
2257 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2258 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2259 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2261 /* We can't lock rendertarget textures, so copy to our temp surface first */
2262 if (hr == D3D_OK) {
2263 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2264 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2267 if (hr == D3D_OK) {
2268 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2269 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2273 /* texture ==> rendertarget surface, same size */
2274 if(surf_tex64 && surf_rt_dest64) {
2275 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2276 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2278 if (hr == D3D_OK) {
2279 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2280 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2284 /* texture ==> texture, same size (should fail) */
2285 if(surf_tex64 && surf_tex_dest64) {
2286 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2287 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2290 /* Fill the surface of the smaller regular texture with red */
2291 if (surf_tex32 && surf_temp32) {
2292 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2293 fill_surface(surf_temp32, 0xffff0000);
2294 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2295 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2298 /* texture ==> offscreenplain, scaling (should fail) */
2299 if(surf_tex32 && surf_offscreen64) {
2300 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2301 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2304 /* texture ==> rendertarget texture, scaling */
2305 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2306 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2307 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2309 /* We can't lock rendertarget textures, so copy to our temp surface first */
2310 if (hr == D3D_OK) {
2311 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2312 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2315 if (hr == D3D_OK) {
2316 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2317 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2321 /* texture ==> rendertarget surface, scaling */
2322 if(surf_tex32 && surf_rt_dest64) {
2323 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2324 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2326 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2327 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2330 /* texture ==> texture, scaling (should fail) */
2331 if(surf_tex32 && surf_tex_dest64) {
2332 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2333 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2336 /*****************************************************************
2337 * Tests for when the source parameter is a rendertarget texture *
2338 *****************************************************************/
2340 /* Fill the surface of the rendertarget texture with white */
2341 if (surf_tex_rt64 && surf_temp64) {
2342 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2343 fill_surface(surf_temp64, 0xffffffff);
2344 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2345 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2348 /* rendertarget texture ==> offscreenplain, same size */
2349 if(surf_tex_rt64 && surf_offscreen64) {
2350 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2351 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2354 /* rendertarget texture ==> rendertarget texture, same size */
2355 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2356 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2357 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2359 /* We can't lock rendertarget textures, so copy to our temp surface first */
2360 if (hr == D3D_OK) {
2361 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2362 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2365 if (hr == D3D_OK) {
2366 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2367 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2371 /* rendertarget texture ==> rendertarget surface, same size */
2372 if(surf_tex_rt64 && surf_rt_dest64) {
2373 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2374 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2376 if (hr == D3D_OK) {
2377 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2378 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2382 /* rendertarget texture ==> texture, same size (should fail) */
2383 if(surf_tex_rt64 && surf_tex_dest64) {
2384 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2385 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2388 /* Fill the surface of the smaller rendertarget texture with red */
2389 if (surf_tex_rt32 && surf_temp32) {
2390 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2391 fill_surface(surf_temp32, 0xffff0000);
2392 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2393 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2396 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2397 if(surf_tex_rt32 && surf_offscreen64) {
2398 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2399 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2402 /* rendertarget texture ==> rendertarget texture, scaling */
2403 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2404 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2405 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2407 /* We can't lock rendertarget textures, so copy to our temp surface first */
2408 if (hr == D3D_OK) {
2409 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2410 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2413 if (hr == D3D_OK) {
2414 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2415 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2419 /* rendertarget texture ==> rendertarget surface, scaling */
2420 if(surf_tex_rt32 && surf_rt_dest64) {
2421 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2422 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2424 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2425 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2428 /* rendertarget texture ==> texture, scaling (should fail) */
2429 if(surf_tex_rt32 && surf_tex_dest64) {
2430 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2431 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2434 /*****************************************************************
2435 * Tests for when the source parameter is a rendertarget surface *
2436 *****************************************************************/
2438 /* Fill the surface of the rendertarget surface with black */
2439 if (surf_rt64)
2440 fill_surface(surf_rt64, 0xff000000);
2442 /* rendertarget texture ==> offscreenplain, same size */
2443 if(surf_rt64 && surf_offscreen64) {
2444 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2445 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2448 /* rendertarget surface ==> rendertarget texture, same size */
2449 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2450 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2451 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2453 /* We can't lock rendertarget textures, so copy to our temp surface first */
2454 if (hr == D3D_OK) {
2455 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2456 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2459 if (hr == D3D_OK) {
2460 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2461 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2465 /* rendertarget surface ==> rendertarget surface, same size */
2466 if(surf_rt64 && surf_rt_dest64) {
2467 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2468 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2470 if (hr == D3D_OK) {
2471 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2472 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2476 /* rendertarget surface ==> texture, same size (should fail) */
2477 if(surf_rt64 && surf_tex_dest64) {
2478 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2479 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2482 /* Fill the surface of the smaller rendertarget texture with red */
2483 if (surf_rt32)
2484 fill_surface(surf_rt32, 0xffff0000);
2486 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2487 if(surf_rt32 && surf_offscreen64) {
2488 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2489 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2492 /* rendertarget surface ==> rendertarget texture, scaling */
2493 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2494 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2495 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2497 /* We can't lock rendertarget textures, so copy to our temp surface first */
2498 if (hr == D3D_OK) {
2499 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2500 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2503 if (hr == D3D_OK) {
2504 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2505 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2509 /* rendertarget surface ==> rendertarget surface, scaling */
2510 if(surf_rt32 && surf_rt_dest64) {
2511 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2512 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2514 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2515 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2518 /* rendertarget surface ==> texture, scaling (should fail) */
2519 if(surf_rt32 && surf_tex_dest64) {
2520 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2521 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2524 /* TODO: Test when source and destination RECT parameters are given... */
2525 /* TODO: Test format conversions */
2528 out:
2529 /* Clean up */
2530 if (surf_rt32)
2531 IDirect3DSurface9_Release(surf_rt32);
2532 if (surf_rt64)
2533 IDirect3DSurface9_Release(surf_rt64);
2534 if (surf_rt_dest64)
2535 IDirect3DSurface9_Release(surf_rt_dest64);
2536 if (surf_temp32)
2537 IDirect3DSurface9_Release(surf_temp32);
2538 if (surf_temp64)
2539 IDirect3DSurface9_Release(surf_temp64);
2540 if (surf_offscreen32)
2541 IDirect3DSurface9_Release(surf_offscreen32);
2542 if (surf_offscreen64)
2543 IDirect3DSurface9_Release(surf_offscreen64);
2544 if (surf_offscreen_dest64)
2545 IDirect3DSurface9_Release(surf_offscreen_dest64);
2547 if (tex_rt32) {
2548 if (surf_tex_rt32)
2549 IDirect3DSurface9_Release(surf_tex_rt32);
2550 IDirect3DTexture9_Release(tex_rt32);
2552 if (tex_rt64) {
2553 if (surf_tex_rt64)
2554 IDirect3DSurface9_Release(surf_tex_rt64);
2555 IDirect3DTexture9_Release(tex_rt64);
2557 if (tex_rt_dest64) {
2558 if (surf_tex_rt_dest64)
2559 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2560 IDirect3DTexture9_Release(tex_rt_dest64);
2562 if (tex32) {
2563 if (surf_tex32)
2564 IDirect3DSurface9_Release(surf_tex32);
2565 IDirect3DTexture9_Release(tex32);
2567 if (tex64) {
2568 if (surf_tex64)
2569 IDirect3DSurface9_Release(surf_tex64);
2570 IDirect3DTexture9_Release(tex64);
2572 if (tex_dest64) {
2573 if (surf_tex_dest64)
2574 IDirect3DSurface9_Release(surf_tex_dest64);
2575 IDirect3DTexture9_Release(tex_dest64);
2578 if (orig_rt) {
2579 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2580 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2581 IDirect3DSurface9_Release(orig_rt);
2585 static void maxmip_test(IDirect3DDevice9 *device)
2587 IDirect3DTexture9 *texture = NULL;
2588 IDirect3DSurface9 *surface = NULL;
2589 HRESULT hr;
2590 DWORD color;
2591 const float quads[] = {
2592 -1.0, -1.0, 0.0, 0.0, 0.0,
2593 -1.0, 0.0, 0.0, 0.0, 1.0,
2594 0.0, -1.0, 0.0, 1.0, 0.0,
2595 0.0, 0.0, 0.0, 1.0, 1.0,
2597 0.0, -1.0, 0.0, 0.0, 0.0,
2598 0.0, 0.0, 0.0, 0.0, 1.0,
2599 1.0, -1.0, 0.0, 1.0, 0.0,
2600 1.0, 0.0, 0.0, 1.0, 1.0,
2602 0.0, 0.0, 0.0, 0.0, 0.0,
2603 0.0, 1.0, 0.0, 0.0, 1.0,
2604 1.0, 0.0, 0.0, 1.0, 0.0,
2605 1.0, 1.0, 0.0, 1.0, 1.0,
2607 -1.0, 0.0, 0.0, 0.0, 0.0,
2608 -1.0, 1.0, 0.0, 0.0, 1.0,
2609 0.0, 0.0, 0.0, 1.0, 0.0,
2610 0.0, 1.0, 0.0, 1.0, 1.0,
2613 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2614 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2616 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2617 &texture, NULL);
2618 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2619 if(!texture)
2621 skip("Failed to create test texture\n");
2622 return;
2625 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2626 fill_surface(surface, 0xffff0000);
2627 IDirect3DSurface9_Release(surface);
2628 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2629 fill_surface(surface, 0xff00ff00);
2630 IDirect3DSurface9_Release(surface);
2631 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2632 fill_surface(surface, 0xff0000ff);
2633 IDirect3DSurface9_Release(surface);
2635 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2637 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2638 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2640 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2641 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2643 hr = IDirect3DDevice9_BeginScene(device);
2644 if(SUCCEEDED(hr))
2646 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2647 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2649 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2651 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2652 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2654 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2656 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2657 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2659 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2661 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2662 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2664 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2665 hr = IDirect3DDevice9_EndScene(device);
2668 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2669 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2670 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2671 color = getPixelColor(device, 160, 360);
2672 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2673 color = getPixelColor(device, 160, 120);
2674 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2675 color = getPixelColor(device, 480, 120);
2676 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2677 color = getPixelColor(device, 480, 360);
2678 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2680 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2681 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2683 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2684 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2686 hr = IDirect3DDevice9_BeginScene(device);
2687 if(SUCCEEDED(hr))
2689 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2690 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2692 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2694 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2695 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2697 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2699 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2700 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2701 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2702 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2704 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2705 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2707 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2708 hr = IDirect3DDevice9_EndScene(device);
2711 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2712 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2713 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2714 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2716 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2717 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2718 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2719 * samples from the highest level in the texture(level 2)
2721 color = getPixelColor(device, 160, 360);
2722 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2723 color = getPixelColor(device, 160, 120);
2724 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2725 color = getPixelColor(device, 480, 120);
2726 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2727 color = getPixelColor(device, 480, 360);
2728 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2730 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2731 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2732 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2733 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2734 IDirect3DTexture9_Release(texture);
2737 static void release_buffer_test(IDirect3DDevice9 *device)
2739 IDirect3DVertexBuffer9 *vb = NULL;
2740 IDirect3DIndexBuffer9 *ib = NULL;
2741 HRESULT hr;
2742 BYTE *data;
2743 long ref;
2745 static const struct vertex quad[] = {
2746 {-1.0, -1.0, 0.1, 0xffff0000},
2747 {-1.0, 1.0, 0.1, 0xffff0000},
2748 { 1.0, 1.0, 0.1, 0xffff0000},
2750 {-1.0, -1.0, 0.1, 0xff00ff00},
2751 {-1.0, 1.0, 0.1, 0xff00ff00},
2752 { 1.0, 1.0, 0.1, 0xff00ff00}
2754 short indices[] = {3, 4, 5};
2756 /* Index and vertex buffers should always be creatable */
2757 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2758 D3DPOOL_MANAGED, &vb, NULL);
2759 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2760 if(!vb) {
2761 skip("Failed to create a vertex buffer\n");
2762 return;
2764 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2765 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2766 if(!ib) {
2767 skip("Failed to create an index buffer\n");
2768 return;
2771 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2772 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2773 memcpy(data, quad, sizeof(quad));
2774 hr = IDirect3DVertexBuffer9_Unlock(vb);
2775 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2777 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2778 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2779 memcpy(data, indices, sizeof(indices));
2780 hr = IDirect3DIndexBuffer9_Unlock(ib);
2781 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2783 hr = IDirect3DDevice9_SetIndices(device, ib);
2784 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2785 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2786 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2787 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2788 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2790 /* Now destroy the bound index buffer and draw again */
2791 ref = IDirect3DIndexBuffer9_Release(ib);
2792 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2794 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2795 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2797 hr = IDirect3DDevice9_BeginScene(device);
2798 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2799 if(SUCCEEDED(hr))
2801 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2802 * making assumptions about the indices or vertices
2804 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2805 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2806 hr = IDirect3DDevice9_EndScene(device);
2807 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2810 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2811 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2813 hr = IDirect3DDevice9_SetIndices(device, NULL);
2814 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2815 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2816 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2818 /* Index buffer was already destroyed as part of the test */
2819 IDirect3DVertexBuffer9_Release(vb);
2822 static void float_texture_test(IDirect3DDevice9 *device)
2824 IDirect3D9 *d3d = NULL;
2825 HRESULT hr;
2826 IDirect3DTexture9 *texture = NULL;
2827 D3DLOCKED_RECT lr;
2828 float *data;
2829 DWORD color;
2830 float quad[] = {
2831 -1.0, -1.0, 0.1, 0.0, 0.0,
2832 -1.0, 1.0, 0.1, 0.0, 1.0,
2833 1.0, -1.0, 0.1, 1.0, 0.0,
2834 1.0, 1.0, 0.1, 1.0, 1.0,
2837 memset(&lr, 0, sizeof(lr));
2838 IDirect3DDevice9_GetDirect3D(device, &d3d);
2839 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2840 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2841 skip("D3DFMT_R32F textures not supported\n");
2842 goto out;
2845 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2846 D3DPOOL_MANAGED, &texture, NULL);
2847 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2848 if(!texture) {
2849 skip("Failed to create R32F texture\n");
2850 goto out;
2853 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2854 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2855 data = lr.pBits;
2856 *data = 0.0;
2857 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2858 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2860 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2861 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2863 hr = IDirect3DDevice9_BeginScene(device);
2864 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2865 if(SUCCEEDED(hr))
2867 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2868 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2871 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2873 hr = IDirect3DDevice9_EndScene(device);
2874 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2876 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2877 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2879 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2880 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2882 color = getPixelColor(device, 240, 320);
2883 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2885 out:
2886 if(texture) IDirect3DTexture9_Release(texture);
2887 IDirect3D9_Release(d3d);
2890 static void g16r16_texture_test(IDirect3DDevice9 *device)
2892 IDirect3D9 *d3d = NULL;
2893 HRESULT hr;
2894 IDirect3DTexture9 *texture = NULL;
2895 D3DLOCKED_RECT lr;
2896 DWORD *data;
2897 DWORD color, red, green, blue;
2898 float quad[] = {
2899 -1.0, -1.0, 0.1, 0.0, 0.0,
2900 -1.0, 1.0, 0.1, 0.0, 1.0,
2901 1.0, -1.0, 0.1, 1.0, 0.0,
2902 1.0, 1.0, 0.1, 1.0, 1.0,
2905 memset(&lr, 0, sizeof(lr));
2906 IDirect3DDevice9_GetDirect3D(device, &d3d);
2907 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2908 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2909 skip("D3DFMT_G16R16 textures not supported\n");
2910 goto out;
2913 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2914 D3DPOOL_MANAGED, &texture, NULL);
2915 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2916 if(!texture) {
2917 skip("Failed to create D3DFMT_G16R16 texture\n");
2918 goto out;
2921 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2922 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2923 data = lr.pBits;
2924 *data = 0x0f00f000;
2925 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2926 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2928 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2929 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2931 hr = IDirect3DDevice9_BeginScene(device);
2932 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2933 if(SUCCEEDED(hr))
2935 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2936 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2939 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2941 hr = IDirect3DDevice9_EndScene(device);
2942 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2944 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2945 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2947 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2948 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2950 color = getPixelColor(device, 240, 320);
2951 red = (color & 0x00ff0000) >> 16;
2952 green = (color & 0x0000ff00) >> 8;
2953 blue = (color & 0x000000ff) >> 0;
2954 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2955 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2957 out:
2958 if(texture) IDirect3DTexture9_Release(texture);
2959 IDirect3D9_Release(d3d);
2962 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2964 HRESULT hr;
2965 IDirect3D9 *d3d;
2966 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2967 D3DCAPS9 caps;
2968 IDirect3DTexture9 *texture = NULL;
2969 IDirect3DVolumeTexture9 *volume = NULL;
2970 unsigned int x, y, z;
2971 D3DLOCKED_RECT lr;
2972 D3DLOCKED_BOX lb;
2973 DWORD color;
2974 UINT w, h;
2975 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2976 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2977 0.0, 1.0, 0.0, 0.0,
2978 0.0, 0.0, 1.0, 0.0,
2979 0.0, 0.0, 0.0, 1.0};
2980 static const D3DVERTEXELEMENT9 decl_elements[] = {
2981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2983 D3DDECL_END()
2985 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2987 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2988 D3DDECL_END()
2990 static const D3DVERTEXELEMENT9 decl_elements3[] = {
2991 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2992 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2993 D3DDECL_END()
2995 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2996 0x00, 0xff, 0x00, 0x00,
2997 0x00, 0x00, 0x00, 0x00,
2998 0x00, 0x00, 0x00, 0x00};
3000 memset(&lr, 0, sizeof(lr));
3001 memset(&lb, 0, sizeof(lb));
3002 IDirect3DDevice9_GetDirect3D(device, &d3d);
3003 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3004 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3005 fmt = D3DFMT_A16B16G16R16;
3007 IDirect3D9_Release(d3d);
3009 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3010 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3011 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3012 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3013 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3015 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3016 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3017 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3018 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3019 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3020 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3021 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3022 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3023 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3024 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3025 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3026 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3027 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3028 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3030 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3034 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3035 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3036 w = min(1024, caps.MaxTextureWidth);
3037 h = min(1024, caps.MaxTextureHeight);
3038 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3039 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3040 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3041 if(!texture) {
3042 skip("Failed to create the test texture\n");
3043 return;
3046 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3047 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3048 * 1.0 in red and green for the x and y coords
3050 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3051 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3052 for(y = 0; y < h; y++) {
3053 for(x = 0; x < w; x++) {
3054 double r_f = (double) y / (double) h;
3055 double g_f = (double) x / (double) w;
3056 if(fmt == D3DFMT_A16B16G16R16) {
3057 unsigned short r, g;
3058 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3059 r = (unsigned short) (r_f * 65536.0);
3060 g = (unsigned short) (g_f * 65536.0);
3061 dst[0] = r;
3062 dst[1] = g;
3063 dst[2] = 0;
3064 dst[3] = 65535;
3065 } else {
3066 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3067 unsigned char r = (unsigned char) (r_f * 255.0);
3068 unsigned char g = (unsigned char) (g_f * 255.0);
3069 dst[0] = 0;
3070 dst[1] = g;
3071 dst[2] = r;
3072 dst[3] = 255;
3076 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3077 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3078 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3079 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3082 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3083 hr = IDirect3DDevice9_BeginScene(device);
3084 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3085 if(SUCCEEDED(hr))
3087 float quad1[] = {
3088 -1.0, -1.0, 0.1, 1.0, 1.0,
3089 -1.0, 0.0, 0.1, 1.0, 1.0,
3090 0.0, -1.0, 0.1, 1.0, 1.0,
3091 0.0, 0.0, 0.1, 1.0, 1.0,
3093 float quad2[] = {
3094 -1.0, 0.0, 0.1, 1.0, 1.0,
3095 -1.0, 1.0, 0.1, 1.0, 1.0,
3096 0.0, 0.0, 0.1, 1.0, 1.0,
3097 0.0, 1.0, 0.1, 1.0, 1.0,
3099 float quad3[] = {
3100 0.0, 0.0, 0.1, 0.5, 0.5,
3101 0.0, 1.0, 0.1, 0.5, 0.5,
3102 1.0, 0.0, 0.1, 0.5, 0.5,
3103 1.0, 1.0, 0.1, 0.5, 0.5,
3105 float quad4[] = {
3106 320, 480, 0.1, 1.0, 0.0, 1.0,
3107 320, 240, 0.1, 1.0, 0.0, 1.0,
3108 640, 480, 0.1, 1.0, 0.0, 1.0,
3109 640, 240, 0.1, 1.0, 0.0, 1.0,
3111 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3112 0.0, 0.0, 0.0, 0.0,
3113 0.0, 0.0, 0.0, 0.0,
3114 0.0, 0.0, 0.0, 0.0};
3116 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3117 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3118 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3119 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3120 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3122 /* What happens with transforms enabled? */
3123 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3124 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3126 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3128 /* What happens if 4 coords are used, but only 2 given ?*/
3129 mat[8] = 1.0;
3130 mat[13] = 1.0;
3131 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3133 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3134 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3136 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3138 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3139 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3140 * due to the coords in the vertices. (turns out red, indeed)
3142 memset(mat, 0, sizeof(mat));
3143 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3145 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3146 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3148 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3150 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3152 hr = IDirect3DDevice9_EndScene(device);
3153 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3156 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3157 color = getPixelColor(device, 160, 360);
3158 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3159 color = getPixelColor(device, 160, 120);
3160 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3161 color = getPixelColor(device, 480, 120);
3162 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3163 color = getPixelColor(device, 480, 360);
3164 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3166 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3167 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3169 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3170 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3171 hr = IDirect3DDevice9_BeginScene(device);
3172 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3173 if(SUCCEEDED(hr))
3175 float quad1[] = {
3176 -1.0, -1.0, 0.1, 0.8, 0.2,
3177 -1.0, 0.0, 0.1, 0.8, 0.2,
3178 0.0, -1.0, 0.1, 0.8, 0.2,
3179 0.0, 0.0, 0.1, 0.8, 0.2,
3181 float quad2[] = {
3182 -1.0, 0.0, 0.1, 0.5, 1.0,
3183 -1.0, 1.0, 0.1, 0.5, 1.0,
3184 0.0, 0.0, 0.1, 0.5, 1.0,
3185 0.0, 1.0, 0.1, 0.5, 1.0,
3187 float quad3[] = {
3188 0.0, 0.0, 0.1, 0.5, 1.0,
3189 0.0, 1.0, 0.1, 0.5, 1.0,
3190 1.0, 0.0, 0.1, 0.5, 1.0,
3191 1.0, 1.0, 0.1, 0.5, 1.0,
3193 float quad4[] = {
3194 0.0, -1.0, 0.1, 0.8, 0.2,
3195 0.0, 0.0, 0.1, 0.8, 0.2,
3196 1.0, -1.0, 0.1, 0.8, 0.2,
3197 1.0, 0.0, 0.1, 0.8, 0.2,
3199 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3200 0.0, 0.0, 0.0, 0.0,
3201 0.0, 1.0, 0.0, 0.0,
3202 0.0, 0.0, 0.0, 0.0};
3204 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3206 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3207 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3208 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3209 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3212 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3214 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3215 * it behaves like COUNT2 because normal textures require 2 coords
3217 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3218 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3220 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3222 /* Just to be sure, the same as quad2 above */
3223 memset(mat, 0, sizeof(mat));
3224 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3225 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3226 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3227 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3229 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3231 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3232 * used? And what happens to the first?
3234 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3237 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3239 hr = IDirect3DDevice9_EndScene(device);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3243 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3244 color = getPixelColor(device, 160, 360);
3245 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3246 color = getPixelColor(device, 160, 120);
3247 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3248 color = getPixelColor(device, 480, 120);
3249 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3250 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3251 color = getPixelColor(device, 480, 360);
3252 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3253 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3255 IDirect3DTexture9_Release(texture);
3257 /* Test projected textures, without any fancy matrices */
3258 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3259 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3260 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3262 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3264 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3265 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3267 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3268 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3269 for(x = 0; x < 4; x++) {
3270 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3272 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3273 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3277 hr = IDirect3DDevice9_BeginScene(device);
3278 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3279 if(SUCCEEDED(hr))
3281 const float proj_quads[] = {
3282 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3283 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3284 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3285 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3286 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3287 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3288 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3289 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3292 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3293 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3295 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3297 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3298 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3302 hr = IDirect3DDevice9_EndScene(device);
3303 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3306 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3307 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3308 IDirect3DTexture9_Release(texture);
3310 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3311 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3312 color = getPixelColor(device, 158, 118);
3313 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3314 color = getPixelColor(device, 162, 118);
3315 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3316 color = getPixelColor(device, 158, 122);
3317 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3318 color = getPixelColor(device, 162, 122);
3319 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3321 color = getPixelColor(device, 158, 178);
3322 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3323 color = getPixelColor(device, 162, 178);
3324 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3325 color = getPixelColor(device, 158, 182);
3326 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3327 color = getPixelColor(device, 162, 182);
3328 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3330 color = getPixelColor(device, 318, 118);
3331 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3332 color = getPixelColor(device, 322, 118);
3333 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3334 color = getPixelColor(device, 318, 122);
3335 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3336 color = getPixelColor(device, 322, 122);
3337 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3339 color = getPixelColor(device, 318, 178);
3340 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3341 color = getPixelColor(device, 322, 178);
3342 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3343 color = getPixelColor(device, 318, 182);
3344 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3345 color = getPixelColor(device, 322, 182);
3346 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3348 color = getPixelColor(device, 238, 298);
3349 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3350 color = getPixelColor(device, 242, 298);
3351 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3352 color = getPixelColor(device, 238, 302);
3353 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3354 color = getPixelColor(device, 242, 302);
3355 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3357 color = getPixelColor(device, 238, 388);
3358 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3359 color = getPixelColor(device, 242, 388);
3360 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3361 color = getPixelColor(device, 238, 392);
3362 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3363 color = getPixelColor(device, 242, 392);
3364 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3366 color = getPixelColor(device, 478, 298);
3367 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3368 color = getPixelColor(device, 482, 298);
3369 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3370 color = getPixelColor(device, 478, 302);
3371 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3372 color = getPixelColor(device, 482, 302);
3373 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3375 color = getPixelColor(device, 478, 388);
3376 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3377 color = getPixelColor(device, 482, 388);
3378 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3379 color = getPixelColor(device, 478, 392);
3380 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3381 color = getPixelColor(device, 482, 392);
3382 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3384 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3385 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3386 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3387 * Thus watch out if sampling from texels between 0 and 1.
3389 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3390 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3391 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3392 if(!volume) {
3393 skip("Failed to create a volume texture\n");
3394 goto out;
3397 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3398 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3399 for(z = 0; z < 32; z++) {
3400 for(y = 0; y < 32; y++) {
3401 for(x = 0; x < 32; x++) {
3402 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3403 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3404 float r_f = (float) x / 31.0;
3405 float g_f = (float) y / 31.0;
3406 float b_f = (float) z / 31.0;
3408 if(fmt == D3DFMT_A16B16G16R16) {
3409 unsigned short *mem_s = mem;
3410 mem_s[0] = r_f * 65535.0;
3411 mem_s[1] = g_f * 65535.0;
3412 mem_s[2] = b_f * 65535.0;
3413 mem_s[3] = 65535;
3414 } else {
3415 unsigned char *mem_c = mem;
3416 mem_c[0] = b_f * 255.0;
3417 mem_c[1] = g_f * 255.0;
3418 mem_c[2] = r_f * 255.0;
3419 mem_c[3] = 255;
3424 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3425 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3427 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3428 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3430 hr = IDirect3DDevice9_BeginScene(device);
3431 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3432 if(SUCCEEDED(hr))
3434 float quad1[] = {
3435 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3436 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3437 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3438 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3440 float quad2[] = {
3441 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3442 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3443 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3444 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3446 float quad3[] = {
3447 0.0, 0.0, 0.1, 0.0, 0.0,
3448 0.0, 1.0, 0.1, 0.0, 0.0,
3449 1.0, 0.0, 0.1, 0.0, 0.0,
3450 1.0, 1.0, 0.1, 0.0, 0.0
3452 float quad4[] = {
3453 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3454 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3455 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3456 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3458 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3459 0.0, 0.0, 1.0, 0.0,
3460 0.0, 1.0, 0.0, 0.0,
3461 0.0, 0.0, 0.0, 1.0};
3462 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3465 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3466 * values
3468 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3470 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3471 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3473 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3475 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3476 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3477 * otherwise the w will be missing(blue).
3478 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3479 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3481 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3482 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3484 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3486 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3487 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3489 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3490 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3491 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3492 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3494 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3496 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3497 * disable. ATI extends it up to the amount of values needed for the volume texture
3499 memset(mat, 0, sizeof(mat));
3500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3502 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3503 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3504 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3507 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3509 hr = IDirect3DDevice9_EndScene(device);
3510 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3512 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3513 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3515 color = getPixelColor(device, 160, 360);
3516 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3517 color = getPixelColor(device, 160, 120);
3518 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3519 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3520 color = getPixelColor(device, 480, 120);
3521 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3522 color = getPixelColor(device, 480, 360);
3523 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3525 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3526 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3527 hr = IDirect3DDevice9_BeginScene(device);
3528 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3529 if(SUCCEEDED(hr))
3531 float quad1[] = {
3532 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3533 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3534 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3535 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3537 float quad2[] = {
3538 -1.0, 0.0, 0.1,
3539 -1.0, 1.0, 0.1,
3540 0.0, 0.0, 0.1,
3541 0.0, 1.0, 0.1,
3543 float quad3[] = {
3544 0.0, 0.0, 0.1, 1.0,
3545 0.0, 1.0, 0.1, 1.0,
3546 1.0, 0.0, 0.1, 1.0,
3547 1.0, 1.0, 0.1, 1.0
3549 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3550 0.0, 0.0, 0.0, 0.0,
3551 0.0, 0.0, 0.0, 0.0,
3552 0.0, 1.0, 0.0, 0.0};
3553 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3554 1.0, 0.0, 0.0, 0.0,
3555 0.0, 1.0, 0.0, 0.0,
3556 0.0, 0.0, 1.0, 0.0};
3557 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3558 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3560 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3562 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3563 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3564 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3565 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3567 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3569 /* None passed */
3570 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3575 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3577 /* 4 used, 1 passed */
3578 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3580 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3581 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3583 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3585 hr = IDirect3DDevice9_EndScene(device);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3588 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3589 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3590 color = getPixelColor(device, 160, 360);
3591 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3592 color = getPixelColor(device, 160, 120);
3593 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3594 color = getPixelColor(device, 480, 120);
3595 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3596 /* Quad4: unused */
3598 IDirect3DVolumeTexture9_Release(volume);
3600 out:
3601 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3602 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3603 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3604 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3605 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3606 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3607 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3608 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3609 IDirect3DVertexDeclaration9_Release(decl);
3610 IDirect3DVertexDeclaration9_Release(decl2);
3611 IDirect3DVertexDeclaration9_Release(decl3);
3614 static void texdepth_test(IDirect3DDevice9 *device)
3616 IDirect3DPixelShader9 *shader;
3617 HRESULT hr;
3618 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3619 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3620 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3621 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3622 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3623 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3624 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3625 DWORD shader_code[] = {
3626 0xffff0104, /* ps_1_4 */
3627 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3628 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3629 0x0000fffd, /* phase */
3630 0x00000057, 0x800f0005, /* texdepth r5 */
3631 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3632 0x0000ffff /* end */
3634 DWORD color;
3635 float vertex[] = {
3636 -1.0, -1.0, 0.0,
3637 1.0, -1.0, 1.0,
3638 -1.0, 1.0, 0.0,
3639 1.0, 1.0, 1.0
3642 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3643 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3646 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3652 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3653 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3655 /* Fill the depth buffer with a gradient */
3656 hr = IDirect3DDevice9_BeginScene(device);
3657 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3658 if(SUCCEEDED(hr))
3660 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3661 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3662 hr = IDirect3DDevice9_EndScene(device);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3666 /* Now perform the actual tests. Same geometry, but with the shader */
3667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3670 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3671 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3674 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3676 hr = IDirect3DDevice9_BeginScene(device);
3677 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3678 if(SUCCEEDED(hr))
3680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3681 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3683 hr = IDirect3DDevice9_EndScene(device);
3684 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3687 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3688 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3689 color = getPixelColor(device, 158, 240);
3690 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3691 color = getPixelColor(device, 162, 240);
3692 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3696 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3697 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3698 hr = IDirect3DDevice9_BeginScene(device);
3699 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3700 if(SUCCEEDED(hr))
3702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3703 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3705 hr = IDirect3DDevice9_EndScene(device);
3706 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3709 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3710 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3711 color = getPixelColor(device, 318, 240);
3712 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3713 color = getPixelColor(device, 322, 240);
3714 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3718 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3720 hr = IDirect3DDevice9_BeginScene(device);
3721 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3722 if(SUCCEEDED(hr))
3724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3725 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3727 hr = IDirect3DDevice9_EndScene(device);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3730 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3733 color = getPixelColor(device, 1, 240);
3734 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3736 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3738 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3739 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3740 hr = IDirect3DDevice9_BeginScene(device);
3741 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3742 if(SUCCEEDED(hr))
3744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3745 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3747 hr = IDirect3DDevice9_EndScene(device);
3748 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3750 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3752 color = getPixelColor(device, 318, 240);
3753 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3754 color = getPixelColor(device, 322, 240);
3755 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3757 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3759 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3761 hr = IDirect3DDevice9_BeginScene(device);
3762 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3763 if(SUCCEEDED(hr))
3765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3766 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3768 hr = IDirect3DDevice9_EndScene(device);
3769 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3771 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3772 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3774 color = getPixelColor(device, 1, 240);
3775 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3779 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3781 hr = IDirect3DDevice9_BeginScene(device);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3783 if(SUCCEEDED(hr))
3785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3786 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3788 hr = IDirect3DDevice9_EndScene(device);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3791 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3792 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3794 color = getPixelColor(device, 638, 240);
3795 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3797 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3799 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3801 hr = IDirect3DDevice9_BeginScene(device);
3802 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3803 if(SUCCEEDED(hr))
3805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3806 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3808 hr = IDirect3DDevice9_EndScene(device);
3809 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3812 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3814 color = getPixelColor(device, 638, 240);
3815 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3817 /* Cleanup */
3818 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3819 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3820 IDirect3DPixelShader9_Release(shader);
3822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3823 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3825 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3828 static void texkill_test(IDirect3DDevice9 *device)
3830 IDirect3DPixelShader9 *shader;
3831 HRESULT hr;
3832 DWORD color;
3834 const float vertex[] = {
3835 /* bottom top right left */
3836 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3837 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3838 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3839 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3842 DWORD shader_code_11[] = {
3843 0xffff0101, /* ps_1_1 */
3844 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3845 0x00000041, 0xb00f0000, /* texkill t0 */
3846 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3847 0x0000ffff /* end */
3849 DWORD shader_code_20[] = {
3850 0xffff0200, /* ps_2_0 */
3851 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3852 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3853 0x01000041, 0xb00f0000, /* texkill t0 */
3854 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3855 0x0000ffff /* end */
3858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3859 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3860 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3863 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3865 hr = IDirect3DDevice9_BeginScene(device);
3866 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3867 if(SUCCEEDED(hr))
3869 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3870 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3872 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3873 hr = IDirect3DDevice9_EndScene(device);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3876 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3878 color = getPixelColor(device, 63, 46);
3879 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3880 color = getPixelColor(device, 66, 46);
3881 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3882 color = getPixelColor(device, 63, 49);
3883 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3884 color = getPixelColor(device, 66, 49);
3885 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3887 color = getPixelColor(device, 578, 46);
3888 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3889 color = getPixelColor(device, 575, 46);
3890 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3891 color = getPixelColor(device, 578, 49);
3892 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3893 color = getPixelColor(device, 575, 49);
3894 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3896 color = getPixelColor(device, 63, 430);
3897 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3898 color = getPixelColor(device, 63, 433);
3899 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3900 color = getPixelColor(device, 66, 433);
3901 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3902 color = getPixelColor(device, 66, 430);
3903 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3905 color = getPixelColor(device, 578, 430);
3906 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3907 color = getPixelColor(device, 578, 433);
3908 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3909 color = getPixelColor(device, 575, 433);
3910 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3911 color = getPixelColor(device, 575, 430);
3912 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3914 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3915 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3916 IDirect3DPixelShader9_Release(shader);
3918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3919 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3920 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3921 if(FAILED(hr)) {
3922 skip("Failed to create 2.0 test shader, most likely not supported\n");
3923 return;
3926 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3927 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3928 hr = IDirect3DDevice9_BeginScene(device);
3929 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3930 if(SUCCEEDED(hr))
3932 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3933 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3934 hr = IDirect3DDevice9_EndScene(device);
3935 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3937 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3939 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3940 color = getPixelColor(device, 63, 46);
3941 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3942 color = getPixelColor(device, 66, 46);
3943 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3944 color = getPixelColor(device, 63, 49);
3945 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3946 color = getPixelColor(device, 66, 49);
3947 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3949 color = getPixelColor(device, 578, 46);
3950 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3951 color = getPixelColor(device, 575, 46);
3952 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3953 color = getPixelColor(device, 578, 49);
3954 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3955 color = getPixelColor(device, 575, 49);
3956 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3958 color = getPixelColor(device, 63, 430);
3959 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3960 color = getPixelColor(device, 63, 433);
3961 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3962 color = getPixelColor(device, 66, 433);
3963 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3964 color = getPixelColor(device, 66, 430);
3965 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3967 color = getPixelColor(device, 578, 430);
3968 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3969 color = getPixelColor(device, 578, 433);
3970 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3971 color = getPixelColor(device, 575, 433);
3972 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3973 color = getPixelColor(device, 575, 430);
3974 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3976 /* Cleanup */
3977 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3978 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3979 IDirect3DPixelShader9_Release(shader);
3982 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3984 IDirect3D9 *d3d9;
3985 HRESULT hr;
3986 IDirect3DTexture9 *texture;
3987 IDirect3DPixelShader9 *shader;
3988 IDirect3DPixelShader9 *shader2;
3989 D3DLOCKED_RECT lr;
3990 DWORD color;
3991 DWORD shader_code[] = {
3992 0xffff0101, /* ps_1_1 */
3993 0x00000042, 0xb00f0000, /* tex t0 */
3994 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3995 0x0000ffff /* end */
3997 DWORD shader_code2[] = {
3998 0xffff0101, /* ps_1_1 */
3999 0x00000042, 0xb00f0000, /* tex t0 */
4000 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4001 0x0000ffff /* end */
4004 float quad[] = {
4005 -1.0, -1.0, 0.1, 0.5, 0.5,
4006 1.0, -1.0, 0.1, 0.5, 0.5,
4007 -1.0, 1.0, 0.1, 0.5, 0.5,
4008 1.0, 1.0, 0.1, 0.5, 0.5,
4011 memset(&lr, 0, sizeof(lr));
4012 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4013 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4014 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4015 IDirect3D9_Release(d3d9);
4016 if(FAILED(hr)) {
4017 skip("No D3DFMT_X8L8V8U8 support\n");
4020 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4023 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4025 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4026 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4027 *((DWORD *) lr.pBits) = 0x11ca3141;
4028 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4029 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4031 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4033 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4034 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4036 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4038 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4040 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4041 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4043 hr = IDirect3DDevice9_BeginScene(device);
4044 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4045 if(SUCCEEDED(hr))
4047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4048 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4050 hr = IDirect3DDevice9_EndScene(device);
4051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4053 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4054 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4055 color = getPixelColor(device, 578, 430);
4056 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4057 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4059 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4061 hr = IDirect3DDevice9_BeginScene(device);
4062 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4063 if(SUCCEEDED(hr))
4065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4066 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4068 hr = IDirect3DDevice9_EndScene(device);
4069 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4072 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4073 color = getPixelColor(device, 578, 430);
4074 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4076 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4077 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4078 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4079 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4080 IDirect3DPixelShader9_Release(shader);
4081 IDirect3DPixelShader9_Release(shader2);
4082 IDirect3DTexture9_Release(texture);
4085 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4087 HRESULT hr;
4088 IDirect3D9 *d3d;
4089 IDirect3DTexture9 *texture = NULL;
4090 IDirect3DSurface9 *surface;
4091 DWORD color;
4092 const RECT r1 = {256, 256, 512, 512};
4093 const RECT r2 = {512, 256, 768, 512};
4094 const RECT r3 = {256, 512, 512, 768};
4095 const RECT r4 = {512, 512, 768, 768};
4096 unsigned int x, y;
4097 D3DLOCKED_RECT lr;
4098 memset(&lr, 0, sizeof(lr));
4100 IDirect3DDevice9_GetDirect3D(device, &d3d);
4101 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4102 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4103 skip("No autogenmipmap support\n");
4104 IDirect3D9_Release(d3d);
4105 return;
4107 IDirect3D9_Release(d3d);
4109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4112 /* Make the mipmap big, so that a smaller mipmap is used
4114 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4115 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4118 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4119 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4120 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4121 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4122 for(y = 0; y < 1024; y++) {
4123 for(x = 0; x < 1024; x++) {
4124 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4125 POINT pt;
4127 pt.x = x;
4128 pt.y = y;
4129 if(PtInRect(&r1, pt)) {
4130 *dst = 0xffff0000;
4131 } else if(PtInRect(&r2, pt)) {
4132 *dst = 0xff00ff00;
4133 } else if(PtInRect(&r3, pt)) {
4134 *dst = 0xff0000ff;
4135 } else if(PtInRect(&r4, pt)) {
4136 *dst = 0xff000000;
4137 } else {
4138 *dst = 0xffffffff;
4142 hr = IDirect3DSurface9_UnlockRect(surface);
4143 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4144 IDirect3DSurface9_Release(surface);
4146 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4148 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4149 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4151 hr = IDirect3DDevice9_BeginScene(device);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4153 if(SUCCEEDED(hr)) {
4154 const float quad[] = {
4155 -0.5, -0.5, 0.1, 0.0, 0.0,
4156 -0.5, 0.5, 0.1, 0.0, 1.0,
4157 0.5, -0.5, 0.1, 1.0, 0.0,
4158 0.5, 0.5, 0.1, 1.0, 1.0
4161 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4164 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4165 hr = IDirect3DDevice9_EndScene(device);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4168 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4169 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4172 IDirect3DTexture9_Release(texture);
4174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4175 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4176 color = getPixelColor(device, 200, 200);
4177 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4178 color = getPixelColor(device, 280, 200);
4179 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4180 color = getPixelColor(device, 360, 200);
4181 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4182 color = getPixelColor(device, 440, 200);
4183 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4184 color = getPixelColor(device, 200, 270);
4185 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4186 color = getPixelColor(device, 280, 270);
4187 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4188 color = getPixelColor(device, 360, 270);
4189 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4190 color = getPixelColor(device, 440, 270);
4191 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4194 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4196 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4197 IDirect3DVertexDeclaration9 *decl;
4198 HRESULT hr;
4199 DWORD color;
4200 DWORD shader_code_11[] = {
4201 0xfffe0101, /* vs_1_1 */
4202 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4203 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4204 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4205 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4206 0x0000ffff /* end */
4208 DWORD shader_code_11_2[] = {
4209 0xfffe0101, /* vs_1_1 */
4210 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4211 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4212 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4213 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4214 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4215 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4216 0x0000ffff /* end */
4218 DWORD shader_code_20[] = {
4219 0xfffe0200, /* vs_2_0 */
4220 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4221 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4222 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4223 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4224 0x0000ffff /* end */
4226 DWORD shader_code_20_2[] = {
4227 0xfffe0200, /* vs_2_0 */
4228 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4229 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4230 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4231 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4232 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4233 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4234 0x0000ffff /* end */
4236 static const D3DVERTEXELEMENT9 decl_elements[] = {
4237 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4238 D3DDECL_END()
4240 float quad1[] = {
4241 -1.0, -1.0, 0.1,
4242 0.0, -1.0, 0.1,
4243 -1.0, 0.0, 0.1,
4244 0.0, 0.0, 0.1
4246 float quad2[] = {
4247 0.0, -1.0, 0.1,
4248 1.0, -1.0, 0.1,
4249 0.0, 0.0, 0.1,
4250 1.0, 0.0, 0.1
4252 float quad3[] = {
4253 0.0, 0.0, 0.1,
4254 1.0, 0.0, 0.1,
4255 0.0, 1.0, 0.1,
4256 1.0, 1.0, 0.1
4258 float quad4[] = {
4259 -1.0, 0.0, 0.1,
4260 0.0, 0.0, 0.1,
4261 -1.0, 1.0, 0.1,
4262 0.0, 1.0, 0.1
4264 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4265 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4267 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4270 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4272 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4273 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4274 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4275 if(FAILED(hr)) shader_20 = NULL;
4276 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4277 if(FAILED(hr)) shader_20_2 = NULL;
4278 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4279 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4281 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4283 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4284 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4285 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4286 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4288 hr = IDirect3DDevice9_BeginScene(device);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4290 if(SUCCEEDED(hr))
4292 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4293 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4295 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4297 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4298 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4300 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4302 if(shader_20) {
4303 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4306 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4309 if(shader_20_2) {
4310 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4312 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4313 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4316 hr = IDirect3DDevice9_EndScene(device);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4319 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4320 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4322 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4323 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4324 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4327 color = getPixelColor(device, 160, 360);
4328 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4330 color = getPixelColor(device, 480, 360);
4331 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4332 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4333 if(shader_20) {
4334 color = getPixelColor(device, 160, 120);
4335 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4336 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4338 if(shader_20_2) {
4339 color = getPixelColor(device, 480, 120);
4340 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4341 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4344 IDirect3DVertexDeclaration9_Release(decl);
4345 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4346 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4347 IDirect3DVertexShader9_Release(shader_11_2);
4348 IDirect3DVertexShader9_Release(shader_11);
4351 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4353 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4354 HRESULT hr;
4355 DWORD color;
4356 DWORD shader_code_11[] = {
4357 0xffff0101, /* ps_1_1 */
4358 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4359 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4360 0x0000ffff /* end */
4362 DWORD shader_code_12[] = {
4363 0xffff0102, /* ps_1_2 */
4364 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4365 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4366 0x0000ffff /* end */
4368 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4369 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4370 * During development of this test, 1.3 shaders were verified too
4372 DWORD shader_code_14[] = {
4373 0xffff0104, /* ps_1_4 */
4374 /* Try to make one constant local. It gets clamped too, although the binary contains
4375 * the bigger numbers
4377 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4378 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4379 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4380 0x0000ffff /* end */
4382 DWORD shader_code_20[] = {
4383 0xffff0200, /* ps_2_0 */
4384 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4385 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4386 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4387 0x0000ffff /* end */
4389 float quad1[] = {
4390 -1.0, -1.0, 0.1,
4391 0.0, -1.0, 0.1,
4392 -1.0, 0.0, 0.1,
4393 0.0, 0.0, 0.1
4395 float quad2[] = {
4396 0.0, -1.0, 0.1,
4397 1.0, -1.0, 0.1,
4398 0.0, 0.0, 0.1,
4399 1.0, 0.0, 0.1
4401 float quad3[] = {
4402 0.0, 0.0, 0.1,
4403 1.0, 0.0, 0.1,
4404 0.0, 1.0, 0.1,
4405 1.0, 1.0, 0.1
4407 float quad4[] = {
4408 -1.0, 0.0, 0.1,
4409 0.0, 0.0, 0.1,
4410 -1.0, 1.0, 0.1,
4411 0.0, 1.0, 0.1
4413 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4414 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4419 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4420 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4421 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4422 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4423 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4424 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4425 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4426 if(FAILED(hr)) shader_20 = NULL;
4428 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4429 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4430 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4431 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4435 hr = IDirect3DDevice9_BeginScene(device);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4437 if(SUCCEEDED(hr))
4439 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4440 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4442 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4444 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4445 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4447 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4449 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4450 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4452 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4454 if(shader_20) {
4455 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4456 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4458 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4461 hr = IDirect3DDevice9_EndScene(device);
4462 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4465 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4467 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4468 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4470 color = getPixelColor(device, 160, 360);
4471 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4472 "quad 1 has color %08x, expected 0x00808000\n", color);
4473 color = getPixelColor(device, 480, 360);
4474 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4475 "quad 2 has color %08x, expected 0x00808000\n", color);
4476 color = getPixelColor(device, 480, 120);
4477 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4478 "quad 3 has color %08x, expected 0x00808000\n", color);
4479 if(shader_20) {
4480 color = getPixelColor(device, 160, 120);
4481 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4482 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4485 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4486 IDirect3DPixelShader9_Release(shader_14);
4487 IDirect3DPixelShader9_Release(shader_12);
4488 IDirect3DPixelShader9_Release(shader_11);
4491 static void dp2add_ps_test(IDirect3DDevice9 *device)
4493 IDirect3DPixelShader9 *shader_dp2add = NULL;
4494 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4495 HRESULT hr;
4496 DWORD color;
4498 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4499 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4500 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4501 * r0 first.
4502 * The result here for the r,g,b components should be roughly 0.5:
4503 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4504 static const DWORD shader_code_dp2add[] = {
4505 0xffff0200, /* ps_2_0 */
4506 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4508 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4509 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4511 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4512 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4513 0x0000ffff /* end */
4516 /* Test the _sat modifier, too. Result here should be:
4517 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4518 * _SAT: ==> 1.0
4519 * ADD: (1.0 + -0.5) = 0.5
4521 static const DWORD shader_code_dp2add_sat[] = {
4522 0xffff0200, /* ps_2_0 */
4523 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4525 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4526 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4527 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4529 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4530 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4531 0x0000ffff /* end */
4534 const float quad[] = {
4535 -1.0, -1.0, 0.1,
4536 1.0, -1.0, 0.1,
4537 -1.0, 1.0, 0.1,
4538 1.0, 1.0, 0.1
4542 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4543 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4545 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4546 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4548 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4549 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4551 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4554 if (shader_dp2add) {
4556 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4559 hr = IDirect3DDevice9_BeginScene(device);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4561 if(SUCCEEDED(hr))
4563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4564 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4566 hr = IDirect3DDevice9_EndScene(device);
4567 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4569 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4572 color = getPixelColor(device, 360, 240);
4573 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4575 IDirect3DPixelShader9_Release(shader_dp2add);
4576 } else {
4577 skip("dp2add shader creation failed\n");
4580 if (shader_dp2add_sat) {
4582 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4583 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4585 hr = IDirect3DDevice9_BeginScene(device);
4586 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4587 if(SUCCEEDED(hr))
4589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4590 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4592 hr = IDirect3DDevice9_EndScene(device);
4593 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4596 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4598 color = getPixelColor(device, 360, 240);
4599 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4601 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4602 } else {
4603 skip("dp2add shader creation failed\n");
4606 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4607 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4610 static void cnd_test(IDirect3DDevice9 *device)
4612 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4613 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4614 HRESULT hr;
4615 DWORD color;
4616 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4617 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4618 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4620 DWORD shader_code_11[] = {
4621 0xffff0101, /* ps_1_1 */
4622 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4623 0x00000040, 0xb00f0000, /* texcoord t0 */
4624 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4625 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4626 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4627 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4628 0x0000ffff /* end */
4630 DWORD shader_code_12[] = {
4631 0xffff0102, /* ps_1_2 */
4632 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4633 0x00000040, 0xb00f0000, /* texcoord t0 */
4634 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4635 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4636 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4637 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4638 0x0000ffff /* end */
4640 DWORD shader_code_13[] = {
4641 0xffff0103, /* ps_1_3 */
4642 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4643 0x00000040, 0xb00f0000, /* texcoord t0 */
4644 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4645 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4646 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4647 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4648 0x0000ffff /* end */
4650 DWORD shader_code_14[] = {
4651 0xffff0104, /* ps_1_3 */
4652 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4653 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4654 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4655 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4656 0x0000ffff /* end */
4659 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4660 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4661 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4662 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4663 * native CreatePixelShader returns an error.
4665 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4666 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4667 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4668 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4670 DWORD shader_code_11_coissue[] = {
4671 0xffff0101, /* ps_1_1 */
4672 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4673 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4674 0x00000040, 0xb00f0000, /* texcoord t0 */
4675 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4676 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4677 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4678 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4679 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4680 /* 0x40000000 = D3DSI_COISSUE */
4681 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4682 0x0000ffff /* end */
4684 DWORD shader_code_12_coissue[] = {
4685 0xffff0102, /* ps_1_2 */
4686 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4687 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4688 0x00000040, 0xb00f0000, /* texcoord t0 */
4689 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4690 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4691 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4692 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4693 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4694 /* 0x40000000 = D3DSI_COISSUE */
4695 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4696 0x0000ffff /* end */
4698 DWORD shader_code_13_coissue[] = {
4699 0xffff0103, /* ps_1_3 */
4700 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4701 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4702 0x00000040, 0xb00f0000, /* texcoord t0 */
4703 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4704 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4705 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4706 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4707 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4708 /* 0x40000000 = D3DSI_COISSUE */
4709 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4710 0x0000ffff /* end */
4712 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4713 * compare against 0.5
4715 DWORD shader_code_14_coissue[] = {
4716 0xffff0104, /* ps_1_4 */
4717 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4718 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4719 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4720 /* 0x40000000 = D3DSI_COISSUE */
4721 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4722 0x0000ffff /* end */
4724 float quad1[] = {
4725 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4726 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4727 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4728 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4730 float quad2[] = {
4731 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4732 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4733 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4734 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4736 float quad3[] = {
4737 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4738 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4739 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4740 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4742 float quad4[] = {
4743 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4744 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4745 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4746 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4748 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4749 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4750 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4751 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4754 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4756 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4757 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4760 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4762 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4763 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4764 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4765 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4766 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4767 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4768 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4770 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4771 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4773 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4774 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4775 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4776 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4777 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4780 hr = IDirect3DDevice9_BeginScene(device);
4781 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4782 if(SUCCEEDED(hr))
4784 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4785 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4787 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4789 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4790 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4792 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4794 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4795 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4797 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4799 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4804 hr = IDirect3DDevice9_EndScene(device);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4807 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4810 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4811 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4813 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4814 color = getPixelColor(device, 158, 118);
4815 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4816 color = getPixelColor(device, 162, 118);
4817 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4818 color = getPixelColor(device, 158, 122);
4819 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4820 color = getPixelColor(device, 162, 122);
4821 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4823 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4824 color = getPixelColor(device, 158, 358);
4825 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4826 color = getPixelColor(device, 162, 358);
4827 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4828 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4829 color = getPixelColor(device, 158, 362);
4830 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4831 color = getPixelColor(device, 162, 362);
4832 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4833 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4835 /* 1.2 shader */
4836 color = getPixelColor(device, 478, 358);
4837 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4838 color = getPixelColor(device, 482, 358);
4839 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4840 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4841 color = getPixelColor(device, 478, 362);
4842 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4843 color = getPixelColor(device, 482, 362);
4844 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4845 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4847 /* 1.3 shader */
4848 color = getPixelColor(device, 478, 118);
4849 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4850 color = getPixelColor(device, 482, 118);
4851 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4852 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4853 color = getPixelColor(device, 478, 122);
4854 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4855 color = getPixelColor(device, 482, 122);
4856 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4857 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4860 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4861 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4863 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4866 hr = IDirect3DDevice9_BeginScene(device);
4867 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4868 if(SUCCEEDED(hr))
4870 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4871 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4873 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4875 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4876 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4878 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4880 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4883 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4885 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4886 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4887 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4888 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4890 hr = IDirect3DDevice9_EndScene(device);
4891 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4896 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4897 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4899 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4900 * that we swapped the values in c1 and c2 to make the other tests return some color
4902 color = getPixelColor(device, 158, 118);
4903 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4904 color = getPixelColor(device, 162, 118);
4905 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4906 color = getPixelColor(device, 158, 122);
4907 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4908 color = getPixelColor(device, 162, 122);
4909 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4911 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4912 color = getPixelColor(device, 158, 358);
4913 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4914 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4915 color = getPixelColor(device, 162, 358);
4916 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4917 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4918 color = getPixelColor(device, 158, 362);
4919 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4920 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4921 color = getPixelColor(device, 162, 362);
4922 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4923 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4925 /* 1.2 shader */
4926 color = getPixelColor(device, 478, 358);
4927 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4928 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4929 color = getPixelColor(device, 482, 358);
4930 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4931 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4932 color = getPixelColor(device, 478, 362);
4933 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4934 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4935 color = getPixelColor(device, 482, 362);
4936 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4937 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4939 /* 1.3 shader */
4940 color = getPixelColor(device, 478, 118);
4941 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4942 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4943 color = getPixelColor(device, 482, 118);
4944 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4945 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4946 color = getPixelColor(device, 478, 122);
4947 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4948 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4949 color = getPixelColor(device, 482, 122);
4950 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4951 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4953 IDirect3DPixelShader9_Release(shader_14_coissue);
4954 IDirect3DPixelShader9_Release(shader_13_coissue);
4955 IDirect3DPixelShader9_Release(shader_12_coissue);
4956 IDirect3DPixelShader9_Release(shader_11_coissue);
4957 IDirect3DPixelShader9_Release(shader_14);
4958 IDirect3DPixelShader9_Release(shader_13);
4959 IDirect3DPixelShader9_Release(shader_12);
4960 IDirect3DPixelShader9_Release(shader_11);
4963 static void nested_loop_test(IDirect3DDevice9 *device) {
4964 const DWORD shader_code[] = {
4965 0xffff0300, /* ps_3_0 */
4966 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4967 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4968 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
4969 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4970 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4971 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4972 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
4973 0x0000001d, /* endloop */
4974 0x0000001d, /* endloop */
4975 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4976 0x0000ffff /* end */
4978 IDirect3DPixelShader9 *shader;
4979 HRESULT hr;
4980 DWORD color;
4981 const float quad[] = {
4982 -1.0, -1.0, 0.1,
4983 1.0, -1.0, 0.1,
4984 -1.0, 1.0, 0.1,
4985 1.0, 1.0, 0.1
4988 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4989 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
4990 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
4992 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4993 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4994 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4995 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4997 hr = IDirect3DDevice9_BeginScene(device);
4998 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4999 if(SUCCEEDED(hr))
5001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5002 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5003 hr = IDirect3DDevice9_EndScene(device);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5007 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5009 color = getPixelColor(device, 360, 240);
5010 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5011 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5013 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5014 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5015 IDirect3DPixelShader9_Release(shader);
5018 struct varying_test_struct
5020 const DWORD *shader_code;
5021 IDirect3DPixelShader9 *shader;
5022 DWORD color, color_rhw;
5023 const char *name;
5024 BOOL todo, todo_rhw;
5027 struct hugeVertex
5029 float pos_x, pos_y, pos_z, rhw;
5030 float weight_1, weight_2, weight_3, weight_4;
5031 float index_1, index_2, index_3, index_4;
5032 float normal_1, normal_2, normal_3, normal_4;
5033 float fog_1, fog_2, fog_3, fog_4;
5034 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5035 float tangent_1, tangent_2, tangent_3, tangent_4;
5036 float binormal_1, binormal_2, binormal_3, binormal_4;
5037 float depth_1, depth_2, depth_3, depth_4;
5038 DWORD diffuse, specular;
5041 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5042 /* dcl_position: fails to compile */
5043 const DWORD blendweight_code[] = {
5044 0xffff0300, /* ps_3_0 */
5045 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5046 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5047 0x0000ffff /* end */
5049 const DWORD blendindices_code[] = {
5050 0xffff0300, /* ps_3_0 */
5051 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5052 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5053 0x0000ffff /* end */
5055 const DWORD normal_code[] = {
5056 0xffff0300, /* ps_3_0 */
5057 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5058 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5059 0x0000ffff /* end */
5061 /* psize: fails? */
5062 const DWORD texcoord0_code[] = {
5063 0xffff0300, /* ps_3_0 */
5064 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5065 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5066 0x0000ffff /* end */
5068 const DWORD tangent_code[] = {
5069 0xffff0300, /* ps_3_0 */
5070 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5071 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5072 0x0000ffff /* end */
5074 const DWORD binormal_code[] = {
5075 0xffff0300, /* ps_3_0 */
5076 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5077 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5078 0x0000ffff /* end */
5080 /* tessfactor: fails */
5081 /* positiont: fails */
5082 const DWORD color_code[] = {
5083 0xffff0300, /* ps_3_0 */
5084 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5085 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5086 0x0000ffff /* end */
5088 const DWORD fog_code[] = {
5089 0xffff0300, /* ps_3_0 */
5090 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5091 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5092 0x0000ffff /* end */
5094 const DWORD depth_code[] = {
5095 0xffff0300, /* ps_3_0 */
5096 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5097 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5098 0x0000ffff /* end */
5100 const DWORD specular_code[] = {
5101 0xffff0300, /* ps_3_0 */
5102 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5103 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5104 0x0000ffff /* end */
5106 /* sample: fails */
5108 struct varying_test_struct tests[] = {
5109 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5110 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5111 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5112 /* Why does dx not forward the texcoord? */
5113 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5114 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5115 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5116 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5117 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5118 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5119 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5121 /* Declare a monster vertex type :-) */
5122 static const D3DVERTEXELEMENT9 decl_elements[] = {
5123 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5124 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5125 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5126 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5127 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5128 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5129 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5130 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5131 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5132 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5133 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5134 D3DDECL_END()
5136 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5137 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5138 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5139 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5140 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5141 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5142 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5143 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5144 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5145 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5146 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5147 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5148 D3DDECL_END()
5150 struct hugeVertex data[4] = {
5152 -1.0, -1.0, 0.1, 1.0,
5153 0.1, 0.1, 0.1, 0.1,
5154 0.2, 0.2, 0.2, 0.2,
5155 0.3, 0.3, 0.3, 0.3,
5156 0.4, 0.4, 0.4, 0.4,
5157 0.50, 0.55, 0.55, 0.55,
5158 0.6, 0.6, 0.6, 0.7,
5159 0.7, 0.7, 0.7, 0.6,
5160 0.8, 0.8, 0.8, 0.8,
5161 0xe6e6e6e6, /* 0.9 * 256 */
5162 0x224488ff /* Nothing special */
5165 1.0, -1.0, 0.1, 1.0,
5166 0.1, 0.1, 0.1, 0.1,
5167 0.2, 0.2, 0.2, 0.2,
5168 0.3, 0.3, 0.3, 0.3,
5169 0.4, 0.4, 0.4, 0.4,
5170 0.50, 0.55, 0.55, 0.55,
5171 0.6, 0.6, 0.6, 0.7,
5172 0.7, 0.7, 0.7, 0.6,
5173 0.8, 0.8, 0.8, 0.8,
5174 0xe6e6e6e6, /* 0.9 * 256 */
5175 0x224488ff /* Nothing special */
5178 -1.0, 1.0, 0.1, 1.0,
5179 0.1, 0.1, 0.1, 0.1,
5180 0.2, 0.2, 0.2, 0.2,
5181 0.3, 0.3, 0.3, 0.3,
5182 0.4, 0.4, 0.4, 0.4,
5183 0.50, 0.55, 0.55, 0.55,
5184 0.6, 0.6, 0.6, 0.7,
5185 0.7, 0.7, 0.7, 0.6,
5186 0.8, 0.8, 0.8, 0.8,
5187 0xe6e6e6e6, /* 0.9 * 256 */
5188 0x224488ff /* Nothing special */
5191 1.0, 1.0, 0.1, 1.0,
5192 0.1, 0.1, 0.1, 0.1,
5193 0.2, 0.2, 0.2, 0.2,
5194 0.3, 0.3, 0.3, 0.3,
5195 0.4, 0.4, 0.4, 0.4,
5196 0.50, 0.55, 0.55, 0.55,
5197 0.6, 0.6, 0.6, 0.7,
5198 0.7, 0.7, 0.7, 0.6,
5199 0.8, 0.8, 0.8, 0.8,
5200 0xe6e6e6e6, /* 0.9 * 256 */
5201 0x224488ff /* Nothing special */
5204 struct hugeVertex data2[4];
5205 IDirect3DVertexDeclaration9 *decl;
5206 IDirect3DVertexDeclaration9 *decl2;
5207 HRESULT hr;
5208 unsigned int i;
5209 DWORD color, r, g, b, r_e, g_e, b_e;
5210 BOOL drawok;
5212 memcpy(data2, data, sizeof(data2));
5213 data2[0].pos_x = 0; data2[0].pos_y = 0;
5214 data2[1].pos_x = 640; data2[1].pos_y = 0;
5215 data2[2].pos_x = 0; data2[2].pos_y = 480;
5216 data2[3].pos_x = 640; data2[3].pos_y = 480;
5218 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5219 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5220 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5221 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5222 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5223 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5225 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5227 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5228 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5229 tests[i].name, hr);
5232 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5234 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5235 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5237 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5238 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5240 hr = IDirect3DDevice9_BeginScene(device);
5241 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5242 drawok = FALSE;
5243 if(SUCCEEDED(hr))
5245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5246 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5247 drawok = SUCCEEDED(hr);
5248 hr = IDirect3DDevice9_EndScene(device);
5249 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5251 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5254 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5255 * the failure and do not check the color if it failed
5257 if(!drawok) {
5258 continue;
5261 color = getPixelColor(device, 360, 240);
5262 r = color & 0x00ff0000 >> 16;
5263 g = color & 0x0000ff00 >> 8;
5264 b = color & 0x000000ff;
5265 r_e = tests[i].color & 0x00ff0000 >> 16;
5266 g_e = tests[i].color & 0x0000ff00 >> 8;
5267 b_e = tests[i].color & 0x000000ff;
5269 if(tests[i].todo) {
5270 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5271 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5272 tests[i].name, color, tests[i].color);
5273 } else {
5274 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5275 "Test %s returned color 0x%08x, expected 0x%08x\n",
5276 tests[i].name, color, tests[i].color);
5280 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5281 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5282 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5287 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5288 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5290 hr = IDirect3DDevice9_BeginScene(device);
5291 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5292 if(SUCCEEDED(hr))
5294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5295 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5296 hr = IDirect3DDevice9_EndScene(device);
5297 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5299 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5300 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5302 color = getPixelColor(device, 360, 240);
5303 r = color & 0x00ff0000 >> 16;
5304 g = color & 0x0000ff00 >> 8;
5305 b = color & 0x000000ff;
5306 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5307 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5308 b_e = tests[i].color_rhw & 0x000000ff;
5310 if(tests[i].todo_rhw) {
5311 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5312 * pipeline
5314 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5315 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5316 tests[i].name, color, tests[i].color_rhw);
5317 } else {
5318 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5319 "Test %s returned color 0x%08x, expected 0x%08x\n",
5320 tests[i].name, color, tests[i].color_rhw);
5324 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5326 IDirect3DPixelShader9_Release(tests[i].shader);
5329 IDirect3DVertexDeclaration9_Release(decl2);
5330 IDirect3DVertexDeclaration9_Release(decl);
5333 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5334 static const DWORD ps_code[] = {
5335 0xffff0300, /* ps_3_0 */
5336 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5337 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5338 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5339 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5340 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5341 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5342 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5343 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5344 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5346 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5347 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5348 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5349 0x0000001d, /* endloop */
5350 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5351 0x0000ffff /* end */
5353 static const DWORD vs_1_code[] = {
5354 0xfffe0101, /* vs_1_1 */
5355 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5356 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5357 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5358 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5359 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5360 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5361 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5362 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5363 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5364 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5365 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5366 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5367 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5368 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5369 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5370 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5371 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5372 0x0000ffff
5374 DWORD vs_2_code[] = {
5375 0xfffe0200, /* vs_2_0 */
5376 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5377 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5378 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5379 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5380 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5381 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5382 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5383 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5384 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5385 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5386 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5387 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5388 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5389 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5390 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5391 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5392 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5393 0x0000ffff /* end */
5395 /* TODO: Define normal, tangent, blendweight and depth here */
5396 static const DWORD vs_3_code[] = {
5397 0xfffe0300, /* vs_3_0 */
5398 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5399 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5400 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5401 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5402 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5403 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5404 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5405 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5406 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5407 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5408 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5409 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5410 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5411 0x0000ffff /* end */
5413 float quad1[] = {
5414 -1.0, -1.0, 0.1,
5415 0.0, -1.0, 0.1,
5416 -1.0, 0.0, 0.1,
5417 0.0, 0.0, 0.1
5419 float quad2[] = {
5420 0.0, -1.0, 0.1,
5421 1.0, -1.0, 0.1,
5422 0.0, 0.0, 0.1,
5423 1.0, 0.0, 0.1
5425 float quad3[] = {
5426 -1.0, 0.0, 0.1,
5427 0.0, 0.0, 0.1,
5428 -1.0, 1.0, 0.1,
5429 0.0, 1.0, 0.1
5432 HRESULT hr;
5433 DWORD color;
5434 IDirect3DPixelShader9 *pixelshader = NULL;
5435 IDirect3DVertexShader9 *vs_1_shader = NULL;
5436 IDirect3DVertexShader9 *vs_2_shader = NULL;
5437 IDirect3DVertexShader9 *vs_3_shader = NULL;
5439 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5441 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5442 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5443 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5444 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5445 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5446 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5447 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5448 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5449 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5450 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5451 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5453 hr = IDirect3DDevice9_BeginScene(device);
5454 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5455 if(SUCCEEDED(hr))
5457 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5458 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5460 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5462 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5465 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5467 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5468 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5470 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5472 hr = IDirect3DDevice9_EndScene(device);
5473 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5476 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5478 color = getPixelColor(device, 160, 120);
5479 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5480 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5481 color = getPixelColor(device, 160, 360);
5482 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5483 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5484 color = getPixelColor(device, 480, 360);
5485 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5486 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5488 /* cleanup */
5489 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5490 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5491 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5493 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5494 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5495 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5496 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5499 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5500 static const DWORD vs_code[] = {
5501 0xfffe0300, /* vs_3_0 */
5502 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5503 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5504 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5505 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5506 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5507 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5508 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5509 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5510 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5511 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5512 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5513 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5514 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5516 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5517 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5518 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5519 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5520 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5521 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5522 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5523 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5524 0x0000ffff /* end */
5526 static const DWORD ps_1_code[] = {
5527 0xffff0104, /* ps_1_4 */
5528 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5529 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5530 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5531 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5532 0x0000ffff /* end */
5534 static const DWORD ps_2_code[] = {
5535 0xffff0200, /* ps_2_0 */
5536 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5537 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5538 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5540 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5541 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5542 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5543 0x0000ffff /* end */
5545 static const DWORD ps_3_code[] = {
5546 0xffff0300, /* ps_3_0 */
5547 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5548 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5549 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5551 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5552 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5553 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5554 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5555 0x0000ffff /* end */
5558 float quad1[] = {
5559 -1.0, -1.0, 0.1,
5560 0.0, -1.0, 0.1,
5561 -1.0, 0.0, 0.1,
5562 0.0, 0.0, 0.1
5564 float quad2[] = {
5565 0.0, -1.0, 0.1,
5566 1.0, -1.0, 0.1,
5567 0.0, 0.0, 0.1,
5568 1.0, 0.0, 0.1
5570 float quad3[] = {
5571 -1.0, 0.0, 0.1,
5572 0.0, 0.0, 0.1,
5573 -1.0, 1.0, 0.1,
5574 0.0, 1.0, 0.1
5576 float quad4[] = {
5577 0.0, 0.0, 0.1,
5578 1.0, 0.0, 0.1,
5579 0.0, 1.0, 0.1,
5580 1.0, 1.0, 0.1
5583 HRESULT hr;
5584 DWORD color;
5585 IDirect3DVertexShader9 *vertexshader = NULL;
5586 IDirect3DPixelShader9 *ps_1_shader = NULL;
5587 IDirect3DPixelShader9 *ps_2_shader = NULL;
5588 IDirect3DPixelShader9 *ps_3_shader = NULL;
5589 IDirect3DTexture9 *texture = NULL;
5590 D3DLOCKED_RECT lr;
5591 unsigned int x, y;
5593 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5595 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5596 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5597 if(FAILED(hr)) {
5598 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5599 return;
5601 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5602 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5603 for(y = 0; y < 512; y++) {
5604 for(x = 0; x < 512; x++) {
5605 double r_f = (double) x / (double) 512;
5606 double g_f = (double) y / (double) 512;
5607 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5608 unsigned short r = (unsigned short) (r_f * 65535.0);
5609 unsigned short g = (unsigned short) (g_f * 65535.0);
5610 dst[0] = r;
5611 dst[1] = g;
5612 dst[2] = 0;
5613 dst[3] = 65535;
5616 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5617 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5619 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5620 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5621 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5622 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5623 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5625 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5626 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5627 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5628 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5629 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5631 hr = IDirect3DDevice9_BeginScene(device);
5632 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5633 if(SUCCEEDED(hr))
5635 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5636 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5638 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5640 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5641 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5643 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5645 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5646 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5648 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5650 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5651 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5652 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5653 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5654 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5655 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5656 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5657 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5659 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5661 hr = IDirect3DDevice9_EndScene(device);
5662 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5664 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5665 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5667 color = getPixelColor(device, 160, 120);
5668 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5669 (color & 0x0000ff00) == 0x0000ff00 &&
5670 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5671 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5672 color = getPixelColor(device, 160, 360);
5673 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5674 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5675 (color & 0x000000ff) == 0x00000000,
5676 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5677 color = getPixelColor(device, 480, 360);
5678 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5679 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5680 (color & 0x000000ff) == 0x00000000,
5681 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5682 color = getPixelColor(device, 480, 160);
5683 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5684 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5685 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5686 (color & 0x000000ff) == 0x00000000),
5687 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5689 /* cleanup */
5690 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5692 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5693 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5694 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5695 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5696 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5697 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5698 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5699 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5700 if(texture) IDirect3DTexture9_Release(texture);
5703 void test_compare_instructions(IDirect3DDevice9 *device)
5705 DWORD shader_sge_vec_code[] = {
5706 0xfffe0101, /* vs_1_1 */
5707 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5708 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5709 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5710 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5711 0x0000ffff /* end */
5713 DWORD shader_slt_vec_code[] = {
5714 0xfffe0101, /* vs_1_1 */
5715 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5716 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5717 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5718 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5719 0x0000ffff /* end */
5721 DWORD shader_sge_scalar_code[] = {
5722 0xfffe0101, /* vs_1_1 */
5723 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5724 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5725 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5726 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5727 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5728 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5729 0x0000ffff /* end */
5731 DWORD shader_slt_scalar_code[] = {
5732 0xfffe0101, /* vs_1_1 */
5733 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5734 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5735 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5736 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5737 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5738 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5739 0x0000ffff /* end */
5741 IDirect3DVertexShader9 *shader_sge_vec;
5742 IDirect3DVertexShader9 *shader_slt_vec;
5743 IDirect3DVertexShader9 *shader_sge_scalar;
5744 IDirect3DVertexShader9 *shader_slt_scalar;
5745 HRESULT hr, color;
5746 float quad1[] = {
5747 -1.0, -1.0, 0.1,
5748 0.0, -1.0, 0.1,
5749 -1.0, 0.0, 0.1,
5750 0.0, 0.0, 0.1
5752 float quad2[] = {
5753 0.0, -1.0, 0.1,
5754 1.0, -1.0, 0.1,
5755 0.0, 0.0, 0.1,
5756 1.0, 0.0, 0.1
5758 float quad3[] = {
5759 -1.0, 0.0, 0.1,
5760 0.0, 0.0, 0.1,
5761 -1.0, 1.0, 0.1,
5762 0.0, 1.0, 0.1
5764 float quad4[] = {
5765 0.0, 0.0, 0.1,
5766 1.0, 0.0, 0.1,
5767 0.0, 1.0, 0.1,
5768 1.0, 1.0, 0.1
5770 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5771 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5775 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5777 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5778 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5779 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5780 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5781 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5782 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5783 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5784 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5785 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5786 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5787 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5788 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5790 hr = IDirect3DDevice9_BeginScene(device);
5791 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5792 if(SUCCEEDED(hr))
5794 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5795 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5797 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5799 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5800 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5804 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5805 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5807 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5809 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5810 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5812 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5813 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5815 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5817 hr = IDirect3DDevice9_EndScene(device);
5818 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5821 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5822 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5823 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5824 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5826 color = getPixelColor(device, 160, 360);
5827 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5828 color = getPixelColor(device, 480, 360);
5829 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5830 color = getPixelColor(device, 160, 120);
5831 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5832 color = getPixelColor(device, 480, 160);
5833 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5835 IDirect3DVertexShader9_Release(shader_sge_vec);
5836 IDirect3DVertexShader9_Release(shader_slt_vec);
5837 IDirect3DVertexShader9_Release(shader_sge_scalar);
5838 IDirect3DVertexShader9_Release(shader_slt_scalar);
5841 void test_vshader_input(IDirect3DDevice9 *device)
5843 DWORD swapped_shader_code_3[] = {
5844 0xfffe0300, /* vs_3_0 */
5845 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5846 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5847 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5848 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5849 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5850 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5851 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5852 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5853 0x0000ffff /* end */
5855 DWORD swapped_shader_code_1[] = {
5856 0xfffe0101, /* vs_1_1 */
5857 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5858 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5859 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5860 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5861 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5862 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5863 0x0000ffff /* end */
5865 DWORD swapped_shader_code_2[] = {
5866 0xfffe0200, /* vs_2_0 */
5867 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5868 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5869 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5870 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5871 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5872 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5873 0x0000ffff /* end */
5875 DWORD texcoord_color_shader_code_3[] = {
5876 0xfffe0300, /* vs_3_0 */
5877 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5878 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5879 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5880 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5881 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5882 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5883 0x0000ffff /* end */
5885 DWORD texcoord_color_shader_code_2[] = {
5886 0xfffe0200, /* vs_2_0 */
5887 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5888 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5889 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5890 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5891 0x0000ffff /* end */
5893 DWORD texcoord_color_shader_code_1[] = {
5894 0xfffe0101, /* vs_1_1 */
5895 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5896 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5897 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5898 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5899 0x0000ffff /* end */
5901 DWORD color_color_shader_code_3[] = {
5902 0xfffe0300, /* vs_3_0 */
5903 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5904 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5905 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5906 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5907 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5908 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5909 0x0000ffff /* end */
5911 DWORD color_color_shader_code_2[] = {
5912 0xfffe0200, /* vs_2_0 */
5913 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5914 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5915 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5916 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5917 0x0000ffff /* end */
5919 DWORD color_color_shader_code_1[] = {
5920 0xfffe0101, /* vs_1_1 */
5921 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5922 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5923 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5924 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5925 0x0000ffff /* end */
5927 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5928 HRESULT hr;
5929 DWORD color;
5930 float quad1[] = {
5931 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5932 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5933 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5934 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5936 float quad2[] = {
5937 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5938 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5939 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5940 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5942 float quad3[] = {
5943 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5944 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5945 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5946 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5948 float quad4[] = {
5949 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5950 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5951 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5952 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5954 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5955 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5956 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5957 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5958 D3DDECL_END()
5960 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5961 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5962 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5963 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5964 D3DDECL_END()
5966 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5967 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5968 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5969 D3DDECL_END()
5971 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5972 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5973 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5974 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5975 D3DDECL_END()
5977 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5978 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5979 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5980 D3DDECL_END()
5982 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5983 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5984 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5985 D3DDECL_END()
5987 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5988 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5989 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5990 D3DDECL_END()
5992 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5993 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5994 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5995 D3DDECL_END()
5997 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5998 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5999 unsigned int i;
6000 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6001 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6003 struct vertex quad1_color[] = {
6004 {-1.0, -1.0, 0.1, 0x00ff8040},
6005 { 0.0, -1.0, 0.1, 0x00ff8040},
6006 {-1.0, 0.0, 0.1, 0x00ff8040},
6007 { 0.0, 0.0, 0.1, 0x00ff8040}
6009 struct vertex quad2_color[] = {
6010 { 0.0, -1.0, 0.1, 0x00ff8040},
6011 { 1.0, -1.0, 0.1, 0x00ff8040},
6012 { 0.0, 0.0, 0.1, 0x00ff8040},
6013 { 1.0, 0.0, 0.1, 0x00ff8040}
6015 struct vertex quad3_color[] = {
6016 {-1.0, 0.0, 0.1, 0x00ff8040},
6017 { 0.0, 0.0, 0.1, 0x00ff8040},
6018 {-1.0, 1.0, 0.1, 0x00ff8040},
6019 { 0.0, 1.0, 0.1, 0x00ff8040}
6021 float quad4_color[] = {
6022 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6023 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6024 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6025 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6028 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6030 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6032 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6033 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6034 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6037 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6039 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6040 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6041 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6042 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6043 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6044 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6046 for(i = 1; i <= 3; i++) {
6047 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6048 if(i == 3) {
6049 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6050 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6051 } else if(i == 2){
6052 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6053 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6054 } else if(i == 1) {
6055 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6056 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6059 hr = IDirect3DDevice9_BeginScene(device);
6060 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6061 if(SUCCEEDED(hr))
6063 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6064 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6066 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6067 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6069 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6071 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6072 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6074 if(i == 3 || i == 2) {
6075 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6076 } else if(i == 1) {
6077 /* Succeeds or fails, depending on SW or HW vertex processing */
6078 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6081 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6084 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6086 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6089 if(i == 3 || i == 2) {
6090 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6091 } else if(i == 1) {
6092 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6095 hr = IDirect3DDevice9_EndScene(device);
6096 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6100 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6102 if(i == 3 || i == 2) {
6103 color = getPixelColor(device, 160, 360);
6104 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6105 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6107 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6108 color = getPixelColor(device, 480, 360);
6109 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6110 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6111 color = getPixelColor(device, 160, 120);
6112 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6113 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6114 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6116 color = getPixelColor(device, 480, 160);
6117 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6118 } else if(i == 1) {
6119 color = getPixelColor(device, 160, 360);
6120 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6121 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6122 color = getPixelColor(device, 480, 360);
6123 /* Accept the clear color as well in this case, since SW VP returns an error */
6124 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6125 color = getPixelColor(device, 160, 120);
6126 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6127 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6128 color = getPixelColor(device, 480, 160);
6129 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6133 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6135 /* Now find out if the whole streams are re-read, or just the last active value for the
6136 * vertices is used.
6138 hr = IDirect3DDevice9_BeginScene(device);
6139 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6140 if(SUCCEEDED(hr))
6142 float quad1_modified[] = {
6143 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6144 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6145 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6146 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6148 float quad2_modified[] = {
6149 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6150 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6151 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6152 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6155 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6158 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6161 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6163 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6164 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6166 if(i == 3 || i == 2) {
6167 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6168 } else if(i == 1) {
6169 /* Succeeds or fails, depending on SW or HW vertex processing */
6170 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6173 hr = IDirect3DDevice9_EndScene(device);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6176 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6177 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6179 color = getPixelColor(device, 480, 350);
6180 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6181 * as well.
6183 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6184 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6185 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6186 * refrast's result.
6188 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6190 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6191 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6192 color = getPixelColor(device, 160, 120);
6194 IDirect3DDevice9_SetVertexShader(device, NULL);
6195 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6197 IDirect3DVertexShader9_Release(swapped_shader);
6200 for(i = 1; i <= 3; i++) {
6201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6202 if(i == 3) {
6203 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6205 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6207 } else if(i == 2){
6208 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6209 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6210 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6212 } else if(i == 1) {
6213 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6214 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6215 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6216 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6219 hr = IDirect3DDevice9_BeginScene(device);
6220 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6221 if(SUCCEEDED(hr))
6223 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6224 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6225 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6228 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6230 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6233 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6234 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6235 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6236 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6238 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6240 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6241 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6242 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6243 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6245 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6247 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6248 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6250 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6252 hr = IDirect3DDevice9_EndScene(device);
6253 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6255 IDirect3DDevice9_SetVertexShader(device, NULL);
6256 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6258 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6259 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6261 color = getPixelColor(device, 160, 360);
6262 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6263 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6264 color = getPixelColor(device, 480, 360);
6265 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6266 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6267 color = getPixelColor(device, 160, 120);
6268 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6269 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6270 color = getPixelColor(device, 480, 160);
6271 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6272 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6274 IDirect3DVertexShader9_Release(texcoord_color_shader);
6275 IDirect3DVertexShader9_Release(color_color_shader);
6278 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6279 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6280 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6281 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6283 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6284 IDirect3DVertexDeclaration9_Release(decl_color_color);
6285 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6286 IDirect3DVertexDeclaration9_Release(decl_color_float);
6289 static void srgbtexture_test(IDirect3DDevice9 *device)
6291 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6292 * texture stage state to render a quad using that texture. The resulting
6293 * color components should be 0x36 (~ 0.21), per this formula:
6294 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6295 * This is true where srgb_color > 0.04045.
6297 IDirect3D9 *d3d = NULL;
6298 HRESULT hr;
6299 LPDIRECT3DTEXTURE9 texture = NULL;
6300 LPDIRECT3DSURFACE9 surface = NULL;
6301 D3DLOCKED_RECT lr;
6302 DWORD color;
6303 float quad[] = {
6304 -1.0, 1.0, 0.0, 0.0, 0.0,
6305 1.0, 1.0, 0.0, 1.0, 0.0,
6306 -1.0, -1.0, 0.0, 0.0, 1.0,
6307 1.0, -1.0, 0.0, 1.0, 1.0,
6311 memset(&lr, 0, sizeof(lr));
6312 IDirect3DDevice9_GetDirect3D(device, &d3d);
6313 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6314 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6315 D3DFMT_A8R8G8B8) != D3D_OK) {
6316 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6317 goto out;
6320 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6321 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6322 &texture, NULL);
6323 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6324 if(!texture) {
6325 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6326 goto out;
6328 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6329 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6331 fill_surface(surface, 0xff7f7f7f);
6332 IDirect3DSurface9_Release(surface);
6334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6336 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6337 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6339 hr = IDirect3DDevice9_BeginScene(device);
6340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6341 if(SUCCEEDED(hr))
6343 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6346 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6353 hr = IDirect3DDevice9_EndScene(device);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6357 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6358 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6360 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6362 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6363 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6365 color = getPixelColor(device, 320, 240);
6366 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6368 out:
6369 if(texture) IDirect3DTexture9_Release(texture);
6370 IDirect3D9_Release(d3d);
6373 static void shademode_test(IDirect3DDevice9 *device)
6375 /* Render a quad and try all of the different fixed function shading models. */
6376 HRESULT hr;
6377 DWORD color0, color1;
6378 DWORD color0_gouraud = 0, color1_gouraud = 0;
6379 DWORD shademode = D3DSHADE_FLAT;
6380 DWORD primtype = D3DPT_TRIANGLESTRIP;
6381 LPVOID data = NULL;
6382 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6383 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6384 UINT i, j;
6385 struct vertex quad_strip[] =
6387 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6388 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6389 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6390 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6392 struct vertex quad_list[] =
6394 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6395 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6396 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6398 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6399 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6400 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6403 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6404 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6405 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6406 if (FAILED(hr)) goto bail;
6408 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6409 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6410 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6411 if (FAILED(hr)) goto bail;
6413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6414 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6416 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6417 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6419 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6420 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6421 memcpy(data, quad_strip, sizeof(quad_strip));
6422 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6423 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6425 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6426 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6427 memcpy(data, quad_list, sizeof(quad_list));
6428 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6429 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6431 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6432 * the color fixups we have to do for FLAT shading will be dependent on that. */
6433 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6434 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6436 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6437 for (j=0; j<2; j++) {
6439 /* Inner loop just changes the D3DRS_SHADEMODE */
6440 for (i=0; i<3; i++) {
6441 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6442 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6447 hr = IDirect3DDevice9_BeginScene(device);
6448 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6449 if(SUCCEEDED(hr))
6451 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6452 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6454 hr = IDirect3DDevice9_EndScene(device);
6455 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6458 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6459 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6461 /* Sample two spots from the output */
6462 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6463 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6464 switch(shademode) {
6465 case D3DSHADE_FLAT:
6466 /* Should take the color of the first vertex of each triangle */
6467 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6468 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6469 shademode = D3DSHADE_GOURAUD;
6470 break;
6471 case D3DSHADE_GOURAUD:
6472 /* Should be an interpolated blend */
6474 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6475 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6476 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6477 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6479 color0_gouraud = color0;
6480 color1_gouraud = color1;
6482 shademode = D3DSHADE_PHONG;
6483 break;
6484 case D3DSHADE_PHONG:
6485 /* Should be the same as GOURAUD, since no hardware implements this */
6486 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6487 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6488 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6489 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6491 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6492 color0_gouraud, color0);
6493 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6494 color1_gouraud, color1);
6495 break;
6498 /* Now, do it all over again with a TRIANGLELIST */
6499 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6500 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6501 primtype = D3DPT_TRIANGLELIST;
6502 shademode = D3DSHADE_FLAT;
6505 bail:
6506 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6507 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6509 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6511 if (vb_strip)
6512 IDirect3DVertexBuffer9_Release(vb_strip);
6513 if (vb_list)
6514 IDirect3DVertexBuffer9_Release(vb_list);
6518 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6520 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6521 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6522 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6523 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6524 * 0.73
6526 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6527 * so use shaders for this task
6529 IDirect3DPixelShader9 *pshader;
6530 IDirect3DVertexShader9 *vshader;
6531 IDirect3D9 *d3d;
6532 DWORD vshader_code[] = {
6533 0xfffe0101, /* vs_1_1 */
6534 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6535 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6536 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6537 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6538 0x0000ffff /* end */
6540 DWORD pshader_code[] = {
6541 0xffff0101, /* ps_1_1 */
6542 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6543 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6544 0x0000ffff /* end */
6546 const float quad[] = {
6547 -1.0, -1.0, 0.1,
6548 1.0, -1.0, 0.1,
6549 -1.0, 1.0, 0.1,
6550 1.0, 1.0, 0.1
6552 HRESULT hr;
6553 DWORD color;
6555 IDirect3DDevice9_GetDirect3D(device, &d3d);
6556 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6557 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6558 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6559 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6560 * works
6562 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6563 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6564 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6565 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6566 IDirect3D9_Release(d3d);
6567 return;
6569 IDirect3D9_Release(d3d);
6571 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6572 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6577 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6579 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6581 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6585 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6586 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6587 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6588 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6589 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6590 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6591 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6593 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6596 hr = IDirect3DDevice9_BeginScene(device);
6597 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6598 if(SUCCEEDED(hr)) {
6599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6600 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6602 hr = IDirect3DDevice9_EndScene(device);
6603 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6606 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6608 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6610 IDirect3DPixelShader9_Release(pshader);
6611 IDirect3DVertexShader9_Release(vshader);
6613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6614 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6616 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6619 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6620 color = getPixelColor(device, 160, 360);
6621 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6622 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6625 static void alpha_test(IDirect3DDevice9 *device)
6627 HRESULT hr;
6628 IDirect3DTexture9 *offscreenTexture;
6629 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6630 DWORD color;
6632 struct vertex quad1[] =
6634 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6635 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6636 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6637 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6639 struct vertex quad2[] =
6641 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6642 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6643 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6644 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6646 static const float composite_quad[][5] = {
6647 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6648 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6649 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6650 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6653 /* Clear the render target with alpha = 0.5 */
6654 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6655 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6657 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6658 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6660 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6661 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6662 if(!backbuffer) {
6663 goto out;
6666 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6667 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6668 if(!offscreen) {
6669 goto out;
6672 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6673 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6675 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6676 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6677 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6678 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6679 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6680 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6681 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6682 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6683 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6684 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6687 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6688 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6690 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6692 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6693 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6694 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6696 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6701 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6703 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6705 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6706 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6707 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6708 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6709 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6710 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6711 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6716 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6718 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6725 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6727 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6728 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6730 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6731 * Disable alpha blending for the final composition
6733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6734 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6735 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6738 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6739 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6741 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6742 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6745 hr = IDirect3DDevice9_EndScene(device);
6746 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6749 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6751 color = getPixelColor(device, 160, 360);
6752 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6753 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6755 color = getPixelColor(device, 160, 120);
6756 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6757 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6759 color = getPixelColor(device, 480, 360);
6760 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6761 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6763 color = getPixelColor(device, 480, 120);
6764 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6765 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6767 out:
6768 /* restore things */
6769 if(backbuffer) {
6770 IDirect3DSurface9_Release(backbuffer);
6772 if(offscreenTexture) {
6773 IDirect3DTexture9_Release(offscreenTexture);
6775 if(offscreen) {
6776 IDirect3DSurface9_Release(offscreen);
6780 struct vertex_shortcolor {
6781 float x, y, z;
6782 unsigned short r, g, b, a;
6784 struct vertex_floatcolor {
6785 float x, y, z;
6786 float r, g, b, a;
6789 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6791 HRESULT hr;
6792 BOOL s_ok, ub_ok, f_ok;
6793 DWORD color, size, i;
6794 void *data;
6795 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6796 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6797 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6798 D3DDECL_END()
6800 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6801 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6802 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6803 D3DDECL_END()
6805 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6806 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6807 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6808 D3DDECL_END()
6810 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6811 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6812 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6813 D3DDECL_END()
6815 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6816 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6817 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6818 D3DDECL_END()
6820 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6821 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6822 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6823 D3DDECL_END()
6825 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6826 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6827 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6828 D3DDECL_END()
6830 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6831 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6832 IDirect3DVertexBuffer9 *vb, *vb2;
6833 struct vertex quad1[] = /* D3DCOLOR */
6835 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6836 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6837 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6838 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6840 struct vertex quad2[] = /* UBYTE4N */
6842 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6843 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6844 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6845 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6847 struct vertex_shortcolor quad3[] = /* short */
6849 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6850 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6851 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6852 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6854 struct vertex_floatcolor quad4[] =
6856 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6857 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6858 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6859 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6861 DWORD colors[] = {
6862 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6863 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6864 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6865 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6866 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6867 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6868 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6869 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6870 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6871 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6872 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6873 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6874 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6875 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6876 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6877 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6879 float quads[] = {
6880 -1.0, -1.0, 0.1,
6881 -1.0, 0.0, 0.1,
6882 0.0, -1.0, 0.1,
6883 0.0, 0.0, 0.1,
6885 0.0, -1.0, 0.1,
6886 0.0, 0.0, 0.1,
6887 1.0, -1.0, 0.1,
6888 1.0, 0.0, 0.1,
6890 0.0, 0.0, 0.1,
6891 0.0, 1.0, 0.1,
6892 1.0, 0.0, 0.1,
6893 1.0, 1.0, 0.1,
6895 -1.0, 0.0, 0.1,
6896 -1.0, 1.0, 0.1,
6897 0.0, 0.0, 0.1,
6898 0.0, 1.0, 0.1
6900 struct tvertex quad_transformed[] = {
6901 { 90, 110, 0.1, 2.0, 0x00ffff00},
6902 { 570, 110, 0.1, 2.0, 0x00ffff00},
6903 { 90, 300, 0.1, 2.0, 0x00ffff00},
6904 { 570, 300, 0.1, 2.0, 0x00ffff00}
6906 D3DCAPS9 caps;
6908 memset(&caps, 0, sizeof(caps));
6909 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6910 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6913 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6915 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6916 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6917 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6918 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6919 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6920 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6921 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6922 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6923 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6924 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6925 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6926 } else {
6927 trace("D3DDTCAPS_UBYTE4N not supported\n");
6928 dcl_ubyte_2 = NULL;
6929 dcl_ubyte = NULL;
6931 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6932 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6933 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6934 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6936 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6937 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6938 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6939 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6941 hr = IDirect3DDevice9_BeginScene(device);
6942 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6943 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6944 if(SUCCEEDED(hr)) {
6945 if(dcl_color) {
6946 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6947 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6949 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6952 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6953 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6954 * using software vertex processing. Doh!
6956 if(dcl_ubyte) {
6957 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6958 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6960 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6961 ub_ok = SUCCEEDED(hr);
6964 if(dcl_short) {
6965 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6966 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6968 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6969 s_ok = SUCCEEDED(hr);
6972 if(dcl_float) {
6973 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6974 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6976 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6977 f_ok = SUCCEEDED(hr);
6980 hr = IDirect3DDevice9_EndScene(device);
6981 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6984 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6985 if(dcl_short) {
6986 color = getPixelColor(device, 480, 360);
6987 ok(color == 0x000000ff || !s_ok,
6988 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6990 if(dcl_ubyte) {
6991 color = getPixelColor(device, 160, 120);
6992 ok(color == 0x0000ffff || !ub_ok,
6993 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6995 if(dcl_color) {
6996 color = getPixelColor(device, 160, 360);
6997 ok(color == 0x00ffff00,
6998 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7000 if(dcl_float) {
7001 color = getPixelColor(device, 480, 120);
7002 ok(color == 0x00ff0000 || !f_ok,
7003 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7006 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7007 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7008 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7009 * whether the immediate mode code works
7011 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7012 hr = IDirect3DDevice9_BeginScene(device);
7013 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7014 if(SUCCEEDED(hr)) {
7015 if(dcl_color) {
7016 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7017 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7018 memcpy(data, quad1, sizeof(quad1));
7019 hr = IDirect3DVertexBuffer9_Unlock(vb);
7020 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7021 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7022 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7024 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7025 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7026 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7029 if(dcl_ubyte) {
7030 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7031 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7032 memcpy(data, quad2, sizeof(quad2));
7033 hr = IDirect3DVertexBuffer9_Unlock(vb);
7034 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7035 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7036 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7037 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7038 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7039 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7040 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7041 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7042 ub_ok = SUCCEEDED(hr);
7045 if(dcl_short) {
7046 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7047 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7048 memcpy(data, quad3, sizeof(quad3));
7049 hr = IDirect3DVertexBuffer9_Unlock(vb);
7050 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7051 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7052 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7053 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7054 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7055 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7056 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7057 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7058 s_ok = SUCCEEDED(hr);
7061 if(dcl_float) {
7062 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7063 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7064 memcpy(data, quad4, sizeof(quad4));
7065 hr = IDirect3DVertexBuffer9_Unlock(vb);
7066 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7067 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7068 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7069 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7070 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7071 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7072 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7073 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7074 f_ok = SUCCEEDED(hr);
7077 hr = IDirect3DDevice9_EndScene(device);
7078 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7081 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7083 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7084 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7086 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7087 if(dcl_short) {
7088 color = getPixelColor(device, 480, 360);
7089 ok(color == 0x000000ff || !s_ok,
7090 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7092 if(dcl_ubyte) {
7093 color = getPixelColor(device, 160, 120);
7094 ok(color == 0x0000ffff || !ub_ok,
7095 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7097 if(dcl_color) {
7098 color = getPixelColor(device, 160, 360);
7099 ok(color == 0x00ffff00,
7100 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7102 if(dcl_float) {
7103 color = getPixelColor(device, 480, 120);
7104 ok(color == 0x00ff0000 || !f_ok,
7105 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7108 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7109 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7111 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7112 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7113 memcpy(data, quad_transformed, sizeof(quad_transformed));
7114 hr = IDirect3DVertexBuffer9_Unlock(vb);
7115 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7117 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7118 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7120 hr = IDirect3DDevice9_BeginScene(device);
7121 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7122 if(SUCCEEDED(hr)) {
7123 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7124 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7125 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7126 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7128 hr = IDirect3DDevice9_EndScene(device);
7129 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7132 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7133 color = getPixelColor(device, 88, 108);
7134 ok(color == 0x000000ff,
7135 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7136 color = getPixelColor(device, 92, 108);
7137 ok(color == 0x000000ff,
7138 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7139 color = getPixelColor(device, 88, 112);
7140 ok(color == 0x000000ff,
7141 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7142 color = getPixelColor(device, 92, 112);
7143 ok(color == 0x00ffff00,
7144 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7146 color = getPixelColor(device, 568, 108);
7147 ok(color == 0x000000ff,
7148 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7149 color = getPixelColor(device, 572, 108);
7150 ok(color == 0x000000ff,
7151 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7152 color = getPixelColor(device, 568, 112);
7153 ok(color == 0x00ffff00,
7154 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7155 color = getPixelColor(device, 572, 112);
7156 ok(color == 0x000000ff,
7157 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7159 color = getPixelColor(device, 88, 298);
7160 ok(color == 0x000000ff,
7161 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7162 color = getPixelColor(device, 92, 298);
7163 ok(color == 0x00ffff00,
7164 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7165 color = getPixelColor(device, 88, 302);
7166 ok(color == 0x000000ff,
7167 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7168 color = getPixelColor(device, 92, 302);
7169 ok(color == 0x000000ff,
7170 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7172 color = getPixelColor(device, 568, 298);
7173 ok(color == 0x00ffff00,
7174 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7175 color = getPixelColor(device, 572, 298);
7176 ok(color == 0x000000ff,
7177 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7178 color = getPixelColor(device, 568, 302);
7179 ok(color == 0x000000ff,
7180 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7181 color = getPixelColor(device, 572, 302);
7182 ok(color == 0x000000ff,
7183 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7185 /* This test is pointless without those two declarations: */
7186 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7187 skip("color-ubyte switching test declarations aren't supported\n");
7188 goto out;
7191 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7192 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7193 memcpy(data, quads, sizeof(quads));
7194 hr = IDirect3DVertexBuffer9_Unlock(vb);
7195 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7196 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7197 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7198 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7199 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7200 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7201 memcpy(data, colors, sizeof(colors));
7202 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7203 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7205 for(i = 0; i < 2; i++) {
7206 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7207 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7209 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7210 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7211 if(i == 0) {
7212 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7213 } else {
7214 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7216 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7218 hr = IDirect3DDevice9_BeginScene(device);
7219 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7220 ub_ok = FALSE;
7221 if(SUCCEEDED(hr)) {
7222 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7223 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7224 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7225 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7226 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7227 ub_ok = SUCCEEDED(hr);
7229 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7230 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7231 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7232 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7234 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7235 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7236 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7237 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7238 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7239 ub_ok = (SUCCEEDED(hr) && ub_ok);
7241 hr = IDirect3DDevice9_EndScene(device);
7242 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7245 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7246 if(i == 0) {
7247 color = getPixelColor(device, 480, 360);
7248 ok(color == 0x00ff0000,
7249 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7250 color = getPixelColor(device, 160, 120);
7251 ok(color == 0x00ffffff,
7252 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7253 color = getPixelColor(device, 160, 360);
7254 ok(color == 0x000000ff || !ub_ok,
7255 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7256 color = getPixelColor(device, 480, 120);
7257 ok(color == 0x000000ff || !ub_ok,
7258 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7259 } else {
7260 color = getPixelColor(device, 480, 360);
7261 ok(color == 0x000000ff,
7262 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7263 color = getPixelColor(device, 160, 120);
7264 ok(color == 0x00ffffff,
7265 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7266 color = getPixelColor(device, 160, 360);
7267 ok(color == 0x00ff0000 || !ub_ok,
7268 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7269 color = getPixelColor(device, 480, 120);
7270 ok(color == 0x00ff0000 || !ub_ok,
7271 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7275 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7276 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7277 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7278 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7279 IDirect3DVertexBuffer9_Release(vb2);
7281 out:
7282 IDirect3DVertexBuffer9_Release(vb);
7283 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7284 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7285 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7286 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7287 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7288 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7289 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7292 struct vertex_float16color {
7293 float x, y, z;
7294 DWORD c1, c2;
7297 static void test_vshader_float16(IDirect3DDevice9 *device)
7299 HRESULT hr;
7300 DWORD color;
7301 void *data;
7302 static const D3DVERTEXELEMENT9 decl_elements[] = {
7303 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7304 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7305 D3DDECL_END()
7307 IDirect3DVertexDeclaration9 *vdecl = NULL;
7308 IDirect3DVertexBuffer9 *buffer = NULL;
7309 IDirect3DVertexShader9 *shader;
7310 DWORD shader_code[] = {
7311 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7312 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7313 0x90e40001, 0x0000ffff
7315 struct vertex_float16color quad[] = {
7316 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7317 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7318 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7319 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7321 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7322 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7323 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7324 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7326 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7327 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7328 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7329 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7331 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7332 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7333 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7334 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7338 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7340 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7341 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7342 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7343 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7344 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7345 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7347 hr = IDirect3DDevice9_BeginScene(device);
7348 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7349 if(SUCCEEDED(hr)) {
7350 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7351 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7353 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7355 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7356 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7357 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7359 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7361 hr = IDirect3DDevice9_EndScene(device);
7362 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7364 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7365 color = getPixelColor(device, 480, 360);
7366 ok(color == 0x00ff0000,
7367 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7368 color = getPixelColor(device, 160, 120);
7369 ok(color == 0x00000000,
7370 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7371 color = getPixelColor(device, 160, 360);
7372 ok(color == 0x0000ff00,
7373 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7374 color = getPixelColor(device, 480, 120);
7375 ok(color == 0x000000ff,
7376 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7378 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7379 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7381 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7382 D3DPOOL_MANAGED, &buffer, NULL);
7383 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7384 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7385 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7386 memcpy(data, quad, sizeof(quad));
7387 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7388 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7389 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7390 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7392 hr = IDirect3DDevice9_BeginScene(device);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7394 if(SUCCEEDED(hr)) {
7395 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7396 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7397 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7398 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7399 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7400 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7401 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7402 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7404 hr = IDirect3DDevice9_EndScene(device);
7405 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7408 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7409 color = getPixelColor(device, 480, 360);
7410 ok(color == 0x00ff0000,
7411 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7412 color = getPixelColor(device, 160, 120);
7413 ok(color == 0x00000000,
7414 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7415 color = getPixelColor(device, 160, 360);
7416 ok(color == 0x0000ff00,
7417 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7418 color = getPixelColor(device, 480, 120);
7419 ok(color == 0x000000ff,
7420 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7422 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7423 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7424 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7425 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7426 IDirect3DDevice9_SetVertexShader(device, NULL);
7427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7429 IDirect3DVertexDeclaration9_Release(vdecl);
7430 IDirect3DVertexShader9_Release(shader);
7431 IDirect3DVertexBuffer9_Release(buffer);
7434 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7436 D3DCAPS9 caps;
7437 IDirect3DTexture9 *texture;
7438 HRESULT hr;
7439 D3DLOCKED_RECT rect;
7440 unsigned int x, y;
7441 DWORD *dst, color;
7442 const float quad[] = {
7443 -1.0, -1.0, 0.1, -0.2, -0.2,
7444 1.0, -1.0, 0.1, 1.2, -0.2,
7445 -1.0, 1.0, 0.1, -0.2, 1.2,
7446 1.0, 1.0, 0.1, 1.2, 1.2
7448 memset(&caps, 0, sizeof(caps));
7450 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7451 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7452 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7453 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7454 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7455 "Card has conditional NP2 support without power of two restriction set\n");
7456 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7457 return;
7458 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7459 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7460 return;
7463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7466 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7467 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7469 memset(&rect, 0, sizeof(rect));
7470 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7471 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7472 for(y = 0; y < 10; y++) {
7473 for(x = 0; x < 10; x++) {
7474 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7475 if(x == 0 || x == 9 || y == 0 || y == 9) {
7476 *dst = 0x00ff0000;
7477 } else {
7478 *dst = 0x000000ff;
7482 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7483 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7485 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7486 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7487 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7489 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7490 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7491 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7494 hr = IDirect3DDevice9_BeginScene(device);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7496 if(SUCCEEDED(hr)) {
7497 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7498 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7500 hr = IDirect3DDevice9_EndScene(device);
7501 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7504 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7506 color = getPixelColor(device, 1, 1);
7507 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7508 color = getPixelColor(device, 639, 479);
7509 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7511 color = getPixelColor(device, 135, 101);
7512 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7513 color = getPixelColor(device, 140, 101);
7514 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7515 color = getPixelColor(device, 135, 105);
7516 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7517 color = getPixelColor(device, 140, 105);
7518 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7520 color = getPixelColor(device, 135, 376);
7521 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7522 color = getPixelColor(device, 140, 376);
7523 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7524 color = getPixelColor(device, 135, 379);
7525 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7526 color = getPixelColor(device, 140, 379);
7527 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7529 color = getPixelColor(device, 500, 101);
7530 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7531 color = getPixelColor(device, 504, 101);
7532 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7533 color = getPixelColor(device, 500, 105);
7534 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7535 color = getPixelColor(device, 504, 105);
7536 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7538 color = getPixelColor(device, 500, 376);
7539 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7540 color = getPixelColor(device, 504, 376);
7541 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7542 color = getPixelColor(device, 500, 380);
7543 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7544 color = getPixelColor(device, 504, 380);
7545 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7547 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7548 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7549 IDirect3DTexture9_Release(texture);
7552 static void vFace_register_test(IDirect3DDevice9 *device)
7554 HRESULT hr;
7555 DWORD color;
7556 const DWORD shader_code[] = {
7557 0xffff0300, /* ps_3_0 */
7558 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7559 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7560 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7561 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7562 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7563 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7564 0x0000ffff /* END */
7566 IDirect3DPixelShader9 *shader;
7567 IDirect3DTexture9 *texture;
7568 IDirect3DSurface9 *surface, *backbuffer;
7569 const float quad[] = {
7570 -1.0, -1.0, 0.1,
7571 1.0, -1.0, 0.1,
7572 -1.0, 0.0, 0.1,
7574 1.0, -1.0, 0.1,
7575 1.0, 0.0, 0.1,
7576 -1.0, 0.0, 0.1,
7578 -1.0, 0.0, 0.1,
7579 -1.0, 1.0, 0.1,
7580 1.0, 0.0, 0.1,
7582 1.0, 0.0, 0.1,
7583 -1.0, 1.0, 0.1,
7584 1.0, 1.0, 0.1,
7586 const float blit[] = {
7587 0.0, -1.0, 0.1, 0.0, 0.0,
7588 1.0, -1.0, 0.1, 1.0, 0.0,
7589 0.0, 1.0, 0.1, 0.0, 1.0,
7590 1.0, 1.0, 0.1, 1.0, 1.0,
7593 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7594 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7595 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7596 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7597 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7598 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7599 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7600 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7601 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7602 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7603 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7604 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7607 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7609 hr = IDirect3DDevice9_BeginScene(device);
7610 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7611 if(SUCCEEDED(hr)) {
7612 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7613 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7614 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7616 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7618 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7619 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7622 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7624 /* Blit the texture onto the back buffer to make it visible */
7625 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7626 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7627 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7628 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7629 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7630 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7631 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7632 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7633 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7637 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7639 hr = IDirect3DDevice9_EndScene(device);
7640 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7643 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7644 color = getPixelColor(device, 160, 360);
7645 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7646 color = getPixelColor(device, 160, 120);
7647 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7648 color = getPixelColor(device, 480, 360);
7649 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7650 color = getPixelColor(device, 480, 120);
7651 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7653 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7654 IDirect3DDevice9_SetTexture(device, 0, NULL);
7655 IDirect3DPixelShader9_Release(shader);
7656 IDirect3DSurface9_Release(surface);
7657 IDirect3DSurface9_Release(backbuffer);
7658 IDirect3DTexture9_Release(texture);
7661 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7663 HRESULT hr;
7664 DWORD color;
7665 int i;
7666 D3DCAPS9 caps;
7667 BOOL L6V5U5_supported = FALSE;
7668 IDirect3DTexture9 *tex1, *tex2;
7669 D3DLOCKED_RECT locked_rect;
7671 static const float quad[][7] = {
7672 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7673 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7674 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7675 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7678 static const D3DVERTEXELEMENT9 decl_elements[] = {
7679 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7680 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7681 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7682 D3DDECL_END()
7685 /* use asymmetric matrix to test loading */
7686 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7687 float scale, offset;
7689 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7690 IDirect3DTexture9 *texture = NULL;
7692 memset(&caps, 0, sizeof(caps));
7693 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7694 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7695 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7696 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7697 return;
7698 } else {
7699 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7700 * They report that it is not supported, but after that bump mapping works properly. So just test
7701 * if the format is generally supported, and check the BUMPENVMAP flag
7703 IDirect3D9 *d3d9;
7705 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7706 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7707 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7708 L6V5U5_supported = SUCCEEDED(hr);
7709 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7710 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7711 IDirect3D9_Release(d3d9);
7712 if(FAILED(hr)) {
7713 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7714 return;
7718 /* Generate the textures */
7719 generate_bumpmap_textures(device);
7721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7722 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7723 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7724 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7725 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7726 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7727 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7728 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7730 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7731 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7732 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7733 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7734 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7735 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7737 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7738 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7739 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7740 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7741 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7742 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7744 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7745 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7747 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7748 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7750 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7751 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7754 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7755 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7756 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7757 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7759 hr = IDirect3DDevice9_BeginScene(device);
7760 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7763 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7765 hr = IDirect3DDevice9_EndScene(device);
7766 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7768 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7769 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7771 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7772 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7773 * But since testing the color match is not the purpose of the test don't be too picky
7775 color = getPixelColor(device, 320-32, 240);
7776 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7777 color = getPixelColor(device, 320+32, 240);
7778 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7779 color = getPixelColor(device, 320, 240-32);
7780 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7781 color = getPixelColor(device, 320, 240+32);
7782 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7783 color = getPixelColor(device, 320, 240);
7784 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7785 color = getPixelColor(device, 320+32, 240+32);
7786 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7787 color = getPixelColor(device, 320-32, 240+32);
7788 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7789 color = getPixelColor(device, 320+32, 240-32);
7790 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7791 color = getPixelColor(device, 320-32, 240-32);
7792 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7794 for(i = 0; i < 2; i++) {
7795 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7796 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7797 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7798 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7799 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7800 IDirect3DTexture9_Release(texture); /* To destroy it */
7803 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7804 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7805 goto cleanup;
7807 if(L6V5U5_supported == FALSE) {
7808 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7809 goto cleanup;
7812 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7813 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7814 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7815 * would only make this test more complicated
7817 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7818 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7819 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7820 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7822 memset(&locked_rect, 0, sizeof(locked_rect));
7823 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7824 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7825 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7826 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7827 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7829 memset(&locked_rect, 0, sizeof(locked_rect));
7830 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7831 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7832 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7833 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7834 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7836 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7837 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7838 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7839 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7841 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7842 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7843 scale = 2.0;
7844 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7845 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7846 offset = 0.1;
7847 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7848 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7850 hr = IDirect3DDevice9_BeginScene(device);
7851 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7852 if(SUCCEEDED(hr)) {
7853 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7854 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7855 hr = IDirect3DDevice9_EndScene(device);
7856 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7859 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7860 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7861 color = getPixelColor(device, 320, 240);
7862 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7863 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7864 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7866 ok(color_match(color, 0x00994c72, 3), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7868 /* Check a result scale factor > 1.0 */
7869 scale = 10;
7870 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7871 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7872 offset = 10;
7873 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7874 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7876 hr = IDirect3DDevice9_BeginScene(device);
7877 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7878 if(SUCCEEDED(hr)) {
7879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7880 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7881 hr = IDirect3DDevice9_EndScene(device);
7882 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7885 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7886 color = getPixelColor(device, 320, 240);
7887 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7889 /* Check clamping in the scale factor calculation */
7890 scale = 1000;
7891 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7892 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7893 offset = -1;
7894 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7895 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7897 hr = IDirect3DDevice9_BeginScene(device);
7898 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7899 if(SUCCEEDED(hr)) {
7900 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7901 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7902 hr = IDirect3DDevice9_EndScene(device);
7903 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7905 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7906 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7907 color = getPixelColor(device, 320, 240);
7908 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7910 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7912 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7915 IDirect3DTexture9_Release(tex1);
7916 IDirect3DTexture9_Release(tex2);
7918 cleanup:
7919 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7920 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7922 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7924 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7925 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7926 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7929 static void stencil_cull_test(IDirect3DDevice9 *device) {
7930 HRESULT hr;
7931 IDirect3DSurface9 *depthstencil = NULL;
7932 D3DSURFACE_DESC desc;
7933 float quad1[] = {
7934 -1.0, -1.0, 0.1,
7935 0.0, -1.0, 0.1,
7936 -1.0, 0.0, 0.1,
7937 0.0, 0.0, 0.1,
7939 float quad2[] = {
7940 0.0, -1.0, 0.1,
7941 1.0, -1.0, 0.1,
7942 0.0, 0.0, 0.1,
7943 1.0, 0.0, 0.1,
7945 float quad3[] = {
7946 0.0, 0.0, 0.1,
7947 1.0, 0.0, 0.1,
7948 0.0, 1.0, 0.1,
7949 1.0, 1.0, 0.1,
7951 float quad4[] = {
7952 -1.0, 0.0, 0.1,
7953 0.0, 0.0, 0.1,
7954 -1.0, 1.0, 0.1,
7955 0.0, 1.0, 0.1,
7957 struct vertex painter[] = {
7958 {-1.0, -1.0, 0.0, 0x00000000},
7959 { 1.0, -1.0, 0.0, 0x00000000},
7960 {-1.0, 1.0, 0.0, 0x00000000},
7961 { 1.0, 1.0, 0.0, 0x00000000},
7963 WORD indices_cw[] = {0, 1, 3};
7964 WORD indices_ccw[] = {0, 2, 3};
7965 unsigned int i;
7966 DWORD color;
7968 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7969 if(depthstencil == NULL) {
7970 skip("No depth stencil buffer\n");
7971 return;
7973 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7974 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
7975 IDirect3DSurface9_Release(depthstencil);
7976 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7977 skip("No 4 or 8 bit stencil surface\n");
7978 return;
7981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7982 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7983 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7986 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7988 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7990 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7992 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7995 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7997 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7999 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8002 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8004 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8006 /* First pass: Fill the stencil buffer with some values... */
8007 hr = IDirect3DDevice9_BeginScene(device);
8008 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8009 if(SUCCEEDED(hr))
8011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8012 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8013 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8014 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8015 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8016 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8019 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8021 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8022 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8023 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8024 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8025 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8028 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8029 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8030 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8031 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8032 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8034 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8035 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8037 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8038 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8039 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8041 hr = IDirect3DDevice9_EndScene(device);
8042 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8045 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8047 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8049 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8051 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8053 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8055 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8057 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8059 /* 2nd pass: Make the stencil values visible */
8060 hr = IDirect3DDevice9_BeginScene(device);
8061 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8062 if(SUCCEEDED(hr))
8064 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8065 for(i = 0; i < 16; i++) {
8066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8067 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8070 painter[1].diffuse = (i * 16);
8071 painter[2].diffuse = (i * 16);
8072 painter[3].diffuse = (i * 16);
8073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8074 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8076 hr = IDirect3DDevice9_EndScene(device);
8077 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8081 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8084 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8086 color = getPixelColor(device, 160, 420);
8087 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8088 color = getPixelColor(device, 160, 300);
8089 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8091 color = getPixelColor(device, 480, 420);
8092 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8093 color = getPixelColor(device, 480, 300);
8094 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8096 color = getPixelColor(device, 160, 180);
8097 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8098 color = getPixelColor(device, 160, 60);
8099 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8101 color = getPixelColor(device, 480, 180);
8102 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8103 color = getPixelColor(device, 480, 60);
8104 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8107 static void vpos_register_test(IDirect3DDevice9 *device)
8109 HRESULT hr;
8110 DWORD color;
8111 const DWORD shader_code[] = {
8112 0xffff0300, /* ps_3_0 */
8113 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8114 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8115 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8116 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8117 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8118 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8119 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8120 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8121 0x0000ffff /* end */
8123 const DWORD shader_frac_code[] = {
8124 0xffff0300, /* ps_3_0 */
8125 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8126 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8127 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8128 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8129 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8130 0x0000ffff /* end */
8132 IDirect3DPixelShader9 *shader, *shader_frac;
8133 IDirect3DSurface9 *surface = NULL, *backbuffer;
8134 const float quad[] = {
8135 -1.0, -1.0, 0.1, 0.0, 0.0,
8136 1.0, -1.0, 0.1, 1.0, 0.0,
8137 -1.0, 1.0, 0.1, 0.0, 1.0,
8138 1.0, 1.0, 0.1, 1.0, 1.0,
8140 D3DLOCKED_RECT lr;
8141 float constant[4] = {1.0, 0.0, 320, 240};
8142 DWORD *pos;
8144 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8145 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8146 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8147 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8148 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8149 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8150 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8152 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8153 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8154 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8157 hr = IDirect3DDevice9_BeginScene(device);
8158 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8159 if(SUCCEEDED(hr)) {
8160 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8161 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8163 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8164 hr = IDirect3DDevice9_EndScene(device);
8165 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8168 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8169 /* This has to be pixel exact */
8170 color = getPixelColor(device, 319, 239);
8171 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8172 color = getPixelColor(device, 320, 239);
8173 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8174 color = getPixelColor(device, 319, 240);
8175 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8176 color = getPixelColor(device, 320, 240);
8177 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8179 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8180 &surface, NULL);
8181 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8182 hr = IDirect3DDevice9_BeginScene(device);
8183 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8184 if(SUCCEEDED(hr)) {
8185 constant[2] = 16; constant[3] = 16;
8186 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8187 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8188 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8189 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8191 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8192 hr = IDirect3DDevice9_EndScene(device);
8193 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8195 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8196 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8198 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8199 color = *pos & 0x00ffffff;
8200 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8201 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8202 color = *pos & 0x00ffffff;
8203 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8204 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8205 color = *pos & 0x00ffffff;
8206 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8207 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8208 color = *pos & 0x00ffffff;
8209 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8211 hr = IDirect3DSurface9_UnlockRect(surface);
8212 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8214 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8215 * have full control over the multisampling setting inside this test
8217 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8218 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8219 hr = IDirect3DDevice9_BeginScene(device);
8220 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8221 if(SUCCEEDED(hr)) {
8222 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8223 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8225 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8226 hr = IDirect3DDevice9_EndScene(device);
8227 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8229 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8230 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8232 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8233 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8235 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8236 color = *pos & 0x00ffffff;
8237 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8239 hr = IDirect3DSurface9_UnlockRect(surface);
8240 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8242 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8243 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8244 IDirect3DPixelShader9_Release(shader);
8245 IDirect3DPixelShader9_Release(shader_frac);
8246 if(surface) IDirect3DSurface9_Release(surface);
8247 IDirect3DSurface9_Release(backbuffer);
8250 static void pointsize_test(IDirect3DDevice9 *device)
8252 HRESULT hr;
8253 D3DCAPS9 caps;
8254 D3DMATRIX matrix;
8255 D3DMATRIX identity;
8256 float ptsize, ptsize_orig;
8257 DWORD color;
8259 const float vertices[] = {
8260 64, 64, 0.1,
8261 128, 64, 0.1,
8262 192, 64, 0.1,
8263 256, 64, 0.1,
8264 320, 64, 0.1,
8265 384, 64, 0.1
8268 /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */
8269 U(matrix).m[0][0] = 2.0/640.0; U(matrix).m[1][0] = 0.0; U(matrix).m[2][0] = 0.0; U(matrix).m[3][0] =-1.0;
8270 U(matrix).m[0][1] = 0.0; U(matrix).m[1][1] =-2.0/480.0; U(matrix).m[2][1] = 0.0; U(matrix).m[3][1] = 1.0;
8271 U(matrix).m[0][2] = 0.0; U(matrix).m[1][2] = 0.0; U(matrix).m[2][2] = 1.0; U(matrix).m[3][2] = 0.0;
8272 U(matrix).m[0][3] = 0.0; U(matrix).m[1][3] = 0.0; U(matrix).m[2][3] = 0.0; U(matrix).m[3][3] = 1.0;
8274 U(identity).m[0][0] = 1.0; U(identity).m[1][0] = 0.0; U(identity).m[2][0] = 0.0; U(identity).m[3][0] = 0.0;
8275 U(identity).m[0][1] = 0.0; U(identity).m[1][1] = 1.0; U(identity).m[2][1] = 0.0; U(identity).m[3][1] = 0.0;
8276 U(identity).m[0][2] = 0.0; U(identity).m[1][2] = 0.0; U(identity).m[2][2] = 1.0; U(identity).m[3][2] = 0.0;
8277 U(identity).m[0][3] = 0.0; U(identity).m[1][3] = 0.0; U(identity).m[2][3] = 0.0; U(identity).m[3][3] = 1.0;
8279 memset(&caps, 0, sizeof(caps));
8280 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8281 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8282 if(caps.MaxPointSize < 32.0) {
8283 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8284 return;
8287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8288 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8289 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8291 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8292 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8293 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8296 hr = IDirect3DDevice9_BeginScene(device);
8297 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8298 if(SUCCEEDED(hr)) {
8299 ptsize = 16.0;
8300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8305 ptsize = 32.0;
8306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8308 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8309 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8311 ptsize = 31.5;
8312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8315 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8317 if(caps.MaxPointSize >= 64.0) {
8318 ptsize = 64.0;
8319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8320 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8322 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8324 ptsize = 63.75;
8325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8326 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8331 ptsize = 1.0;
8332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8335 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8337 hr = IDirect3DDevice9_EndScene(device);
8338 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8340 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8341 color = getPixelColor(device, 64-9, 64-9);
8342 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8343 color = getPixelColor(device, 64-8, 64-8);
8344 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8345 color = getPixelColor(device, 64-7, 64-7);
8346 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8347 color = getPixelColor(device, 64+7, 64+7);
8348 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8349 color = getPixelColor(device, 64+8, 64+8);
8350 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8351 color = getPixelColor(device, 64+9, 64+9);
8352 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8354 color = getPixelColor(device, 128-17, 64-17);
8355 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8356 color = getPixelColor(device, 128-16, 64-16);
8357 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8358 color = getPixelColor(device, 128-15, 64-15);
8359 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8360 color = getPixelColor(device, 128+15, 64+15);
8361 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8362 color = getPixelColor(device, 128+16, 64+16);
8363 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8364 color = getPixelColor(device, 128+17, 64+17);
8365 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8367 color = getPixelColor(device, 192-17, 64-17);
8368 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8369 color = getPixelColor(device, 192-16, 64-16);
8370 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8371 color = getPixelColor(device, 192-15, 64-15);
8372 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8373 color = getPixelColor(device, 192+15, 64+15);
8374 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8375 color = getPixelColor(device, 192+16, 64+16);
8376 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8377 color = getPixelColor(device, 192+17, 64+17);
8378 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8380 if(caps.MaxPointSize >= 64.0) {
8381 color = getPixelColor(device, 256-33, 64-33);
8382 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8383 color = getPixelColor(device, 256-32, 64-32);
8384 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8385 color = getPixelColor(device, 256-31, 64-31);
8386 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8387 color = getPixelColor(device, 256+31, 64+31);
8388 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8389 color = getPixelColor(device, 256+32, 64+32);
8390 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8391 color = getPixelColor(device, 256+33, 64+33);
8392 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8394 color = getPixelColor(device, 384-33, 64-33);
8395 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8396 color = getPixelColor(device, 384-32, 64-32);
8397 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8398 color = getPixelColor(device, 384-31, 64-31);
8399 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8400 color = getPixelColor(device, 384+31, 64+31);
8401 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8402 color = getPixelColor(device, 384+32, 64+32);
8403 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8404 color = getPixelColor(device, 384+33, 64+33);
8405 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8408 color = getPixelColor(device, 320-1, 64-1);
8409 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8410 color = getPixelColor(device, 320-0, 64-0);
8411 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8412 color = getPixelColor(device, 320+1, 64+1);
8413 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8417 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8418 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8421 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8423 HRESULT hr;
8424 IDirect3DPixelShader9 *ps;
8425 IDirect3DTexture9 *tex1, *tex2;
8426 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8427 D3DCAPS9 caps;
8428 DWORD color;
8429 DWORD shader_code[] = {
8430 0xffff0300, /* ps_3_0 */
8431 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8432 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8433 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8434 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8435 0x0000ffff /* END */
8437 float quad[] = {
8438 -1.0, -1.0, 0.1,
8439 1.0, -1.0, 0.1,
8440 -1.0, 1.0, 0.1,
8441 1.0, 1.0, 0.1,
8443 float texquad[] = {
8444 -1.0, -1.0, 0.1, 0.0, 0.0,
8445 0.0, -1.0, 0.1, 1.0, 0.0,
8446 -1.0, 1.0, 0.1, 0.0, 1.0,
8447 0.0, 1.0, 0.1, 1.0, 1.0,
8449 0.0, -1.0, 0.1, 0.0, 0.0,
8450 1.0, -1.0, 0.1, 1.0, 0.0,
8451 0.0, 1.0, 0.1, 0.0, 1.0,
8452 1.0, 1.0, 0.1, 1.0, 1.0,
8455 memset(&caps, 0, sizeof(caps));
8456 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8457 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8458 if(caps.NumSimultaneousRTs < 2) {
8459 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8460 return;
8463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8466 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8468 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8469 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8470 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8471 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8473 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8474 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8475 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8476 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8477 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8478 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8480 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8481 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8482 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8483 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8484 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8485 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8486 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8487 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8489 hr = IDirect3DDevice9_BeginScene(device);
8490 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8491 if(SUCCEEDED(hr)) {
8492 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8493 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8495 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8497 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8498 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8499 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8500 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8501 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8504 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8505 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8507 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8509 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8510 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8511 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8512 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8514 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8517 hr = IDirect3DDevice9_EndScene(device);
8518 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8521 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8522 color = getPixelColor(device, 160, 240);
8523 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8524 color = getPixelColor(device, 480, 240);
8525 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8527 IDirect3DPixelShader9_Release(ps);
8528 IDirect3DTexture9_Release(tex1);
8529 IDirect3DTexture9_Release(tex2);
8530 IDirect3DSurface9_Release(surf1);
8531 IDirect3DSurface9_Release(surf2);
8532 IDirect3DSurface9_Release(backbuf);
8535 struct formats {
8536 const char *fmtName;
8537 D3DFORMAT textureFormat;
8538 DWORD resultColorBlending;
8539 DWORD resultColorNoBlending;
8542 const struct formats test_formats[] = {
8543 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8544 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8545 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8546 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8547 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8548 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8549 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8550 { NULL, 0 }
8553 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8555 HRESULT hr;
8556 IDirect3DTexture9 *offscreenTexture = NULL;
8557 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8558 IDirect3D9 *d3d = NULL;
8559 DWORD color;
8560 DWORD r0, g0, b0, r1, g1, b1;
8561 int fmt_index;
8563 static const float quad[][5] = {
8564 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8565 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8566 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8567 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8570 /* Quad with R=0x10, G=0x20 */
8571 static const struct vertex quad1[] = {
8572 {-1.0f, -1.0f, 0.1f, 0x80102000},
8573 {-1.0f, 1.0f, 0.1f, 0x80102000},
8574 { 1.0f, -1.0f, 0.1f, 0x80102000},
8575 { 1.0f, 1.0f, 0.1f, 0x80102000},
8578 /* Quad with R=0x20, G=0x10 */
8579 static const struct vertex quad2[] = {
8580 {-1.0f, -1.0f, 0.1f, 0x80201000},
8581 {-1.0f, 1.0f, 0.1f, 0x80201000},
8582 { 1.0f, -1.0f, 0.1f, 0x80201000},
8583 { 1.0f, 1.0f, 0.1f, 0x80201000},
8586 IDirect3DDevice9_GetDirect3D(device, &d3d);
8588 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8589 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8590 if(!backbuffer) {
8591 goto out;
8594 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8596 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8597 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8598 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8599 continue;
8602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8603 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8605 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8606 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8607 if(!offscreenTexture) {
8608 continue;
8611 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8612 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8613 if(!offscreen) {
8614 continue;
8617 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8618 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8620 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8621 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8622 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8623 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8624 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8625 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8626 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8627 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8629 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8631 /* Below we will draw two quads with different colors and try to blend them together.
8632 * The result color is compared with the expected outcome.
8634 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8635 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8636 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8638 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8640 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8641 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8643 /* Draw a quad using color 0x0010200 */
8644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8649 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8651 /* Draw a quad using color 0x0020100 */
8652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8653 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8655 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8657 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8659 /* We don't want to blend the result on the backbuffer */
8660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8661 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8663 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8664 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8665 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8666 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8667 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8669 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8670 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8672 /* This time with the texture */
8673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8674 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8676 IDirect3DDevice9_EndScene(device);
8678 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8681 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8682 /* Compare the color of the center quad with our expectation */
8683 color = getPixelColor(device, 320, 240);
8684 r0 = (color & 0x00ff0000) >> 16;
8685 g0 = (color & 0x0000ff00) >> 8;
8686 b0 = (color & 0x000000ff) >> 0;
8688 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8689 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8690 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8692 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8693 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8694 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8695 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8696 } else {
8697 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8698 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8699 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8700 color = getPixelColor(device, 320, 240);
8701 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
8704 IDirect3DDevice9_SetTexture(device, 0, NULL);
8705 if(offscreenTexture) {
8706 IDirect3DTexture9_Release(offscreenTexture);
8708 if(offscreen) {
8709 IDirect3DSurface9_Release(offscreen);
8713 out:
8714 /* restore things */
8715 if(backbuffer) {
8716 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8717 IDirect3DSurface9_Release(backbuffer);
8721 static void tssargtemp_test(IDirect3DDevice9 *device)
8723 HRESULT hr;
8724 DWORD color;
8725 static const struct vertex quad[] = {
8726 {-1.0, -1.0, 0.1, 0x00ff0000},
8727 { 1.0, -1.0, 0.1, 0x00ff0000},
8728 {-1.0, 1.0, 0.1, 0x00ff0000},
8729 { 1.0, 1.0, 0.1, 0x00ff0000}
8731 D3DCAPS9 caps;
8733 memset(&caps, 0, sizeof(caps));
8734 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8735 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8736 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8737 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8738 return;
8741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8744 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8745 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8746 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8747 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8749 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8750 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8751 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8752 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8753 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8754 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8756 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8757 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8758 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8759 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8760 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8761 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8763 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8764 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8767 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8768 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8769 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8771 hr = IDirect3DDevice9_BeginScene(device);
8772 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8773 if(SUCCEEDED(hr)) {
8775 hr = IDirect3DDevice9_EndScene(device);
8776 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8778 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8780 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8781 color = getPixelColor(device, 320, 240);
8782 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8784 /* Set stage 1 back to default */
8785 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8786 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8787 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8788 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8789 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8790 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8791 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8792 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8793 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8794 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8797 struct testdata
8799 DWORD idxVertex; /* number of instances in the first stream */
8800 DWORD idxColor; /* number of instances in the second stream */
8801 DWORD idxInstance; /* should be 1 ?? */
8802 DWORD color1; /* color 1 instance */
8803 DWORD color2; /* color 2 instance */
8804 DWORD color3; /* color 3 instance */
8805 DWORD color4; /* color 4 instance */
8806 WORD strVertex; /* specify which stream to use 0-2*/
8807 WORD strColor;
8808 WORD strInstance;
8811 static const struct testdata testcases[]=
8813 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8814 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8815 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8816 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8817 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8818 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8819 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8820 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8821 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8822 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8823 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8824 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8825 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8826 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8827 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8829 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8830 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8834 /* Drawing Indexed Geometry with instances*/
8835 static void stream_test(IDirect3DDevice9 *device)
8837 IDirect3DVertexBuffer9 *vb = NULL;
8838 IDirect3DVertexBuffer9 *vb2 = NULL;
8839 IDirect3DVertexBuffer9 *vb3 = NULL;
8840 IDirect3DIndexBuffer9 *ib = NULL;
8841 IDirect3DVertexDeclaration9 *pDecl = NULL;
8842 IDirect3DVertexShader9 *shader = NULL;
8843 HRESULT hr;
8844 BYTE *data;
8845 DWORD color;
8846 DWORD ind;
8847 unsigned i;
8849 const DWORD shader_code[] =
8851 0xfffe0101, /* vs_1_1 */
8852 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8853 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8854 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8855 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8856 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8857 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8858 0x0000ffff
8861 const float quad[][3] =
8863 {-0.5f, -0.5f, 1.1f}, /*0 */
8864 {-0.5f, 0.5f, 1.1f}, /*1 */
8865 { 0.5f, -0.5f, 1.1f}, /*2 */
8866 { 0.5f, 0.5f, 1.1f}, /*3 */
8869 const float vertcolor[][4] =
8871 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8872 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8873 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8874 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8877 /* 4 position for 4 instances */
8878 const float instancepos[][3] =
8880 {-0.6f,-0.6f, 0.0f},
8881 { 0.6f,-0.6f, 0.0f},
8882 { 0.6f, 0.6f, 0.0f},
8883 {-0.6f, 0.6f, 0.0f},
8886 short indices[] = {0, 1, 2, 1, 2, 3};
8888 D3DVERTEXELEMENT9 decl[] =
8890 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8891 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8892 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8893 D3DDECL_END()
8896 /* set the default value because it isn't done in wine? */
8897 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8898 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8900 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8901 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8902 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8904 /* check wrong cases */
8905 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8906 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8907 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8908 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8909 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8910 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8911 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8912 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8913 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8914 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8915 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8916 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8917 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8918 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8919 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8920 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8921 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8922 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8923 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8924 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8926 /* set the default value back */
8927 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8930 /* create all VertexBuffers*/
8931 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8932 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8933 if(!vb) {
8934 skip("Failed to create a vertex buffer\n");
8935 return;
8937 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8938 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8939 if(!vb2) {
8940 skip("Failed to create a vertex buffer\n");
8941 goto out;
8943 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8944 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8945 if(!vb3) {
8946 skip("Failed to create a vertex buffer\n");
8947 goto out;
8950 /* create IndexBuffer*/
8951 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8952 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
8953 if(!ib) {
8954 skip("Failed to create a index buffer\n");
8955 goto out;
8958 /* copy all Buffers (Vertex + Index)*/
8959 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8960 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8961 memcpy(data, quad, sizeof(quad));
8962 hr = IDirect3DVertexBuffer9_Unlock(vb);
8963 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8964 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8965 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8966 memcpy(data, vertcolor, sizeof(vertcolor));
8967 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8968 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8969 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8970 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8971 memcpy(data, instancepos, sizeof(instancepos));
8972 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8973 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8974 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8975 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
8976 memcpy(data, indices, sizeof(indices));
8977 hr = IDirect3DIndexBuffer9_Unlock(ib);
8978 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8980 /* create VertexShader */
8981 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8982 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8983 if(!shader) {
8984 skip("Failed to create a vetex shader\n");
8985 goto out;
8988 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8989 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8991 hr = IDirect3DDevice9_SetIndices(device, ib);
8992 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8994 /* run all tests */
8995 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8997 struct testdata act = testcases[i];
8998 decl[0].Stream = act.strVertex;
8999 decl[1].Stream = act.strColor;
9000 decl[2].Stream = act.strInstance;
9001 /* create VertexDeclarations */
9002 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9003 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9006 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9008 hr = IDirect3DDevice9_BeginScene(device);
9009 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9010 if(SUCCEEDED(hr))
9012 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9013 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9015 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9016 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9017 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9018 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9020 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9021 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9022 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9023 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9025 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9026 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9027 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9028 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9030 /* don't know if this is right (1*3 and 4*1)*/
9031 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9033 hr = IDirect3DDevice9_EndScene(device);
9034 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9036 /* set all StreamSource && StreamSourceFreq back to default */
9037 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9038 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9039 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9041 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9042 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9043 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9045 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9047 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9052 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9054 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9055 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9057 color = getPixelColor(device, 160, 360);
9058 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9059 color = getPixelColor(device, 480, 360);
9060 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9061 color = getPixelColor(device, 480, 120);
9062 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9063 color = getPixelColor(device, 160, 120);
9064 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9067 hr = IDirect3DDevice9_SetIndices(device, NULL);
9068 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9070 out:
9071 if(vb) IDirect3DVertexBuffer9_Release(vb);
9072 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9073 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9074 if(ib)IDirect3DIndexBuffer9_Release(ib);
9075 if(shader)IDirect3DVertexShader9_Release(shader);
9078 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9079 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9080 IDirect3DTexture9 *dsttex = NULL;
9081 HRESULT hr;
9082 DWORD color;
9083 D3DRECT r1 = {0, 0, 50, 50 };
9084 D3DRECT r2 = {50, 0, 100, 50 };
9085 D3DRECT r3 = {50, 50, 100, 100};
9086 D3DRECT r4 = {0, 50, 50, 100};
9087 const float quad[] = {
9088 -1.0, -1.0, 0.1, 0.0, 0.0,
9089 1.0, -1.0, 0.1, 1.0, 0.0,
9090 -1.0, 1.0, 0.1, 0.0, 1.0,
9091 1.0, 1.0, 0.1, 1.0, 1.0,
9094 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9095 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9097 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9098 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9099 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9100 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9102 if(!src || !dsttex) {
9103 skip("One or more test resources could not be created\n");
9104 goto cleanup;
9107 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9108 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9110 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9111 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9113 /* Clear the StretchRect destination for debugging */
9114 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9116 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9117 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9119 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9122 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9123 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9124 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9125 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9126 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9127 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9128 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9129 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9131 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9132 * the target -> texture GL blit path
9134 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9135 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9136 IDirect3DSurface9_Release(dst);
9138 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9141 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9142 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9143 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9144 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9145 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9146 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9147 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9148 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9150 hr = IDirect3DDevice9_BeginScene(device);
9151 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9152 if(SUCCEEDED(hr)) {
9153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9154 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9155 hr = IDirect3DDevice9_EndScene(device);
9156 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9159 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9160 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9161 color = getPixelColor(device, 160, 360);
9162 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9163 color = getPixelColor(device, 480, 360);
9164 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9165 color = getPixelColor(device, 480, 120);
9166 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9167 color = getPixelColor(device, 160, 120);
9168 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9170 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9171 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9172 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9173 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9175 cleanup:
9176 if(src) IDirect3DSurface9_Release(src);
9177 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9178 if(dsttex) IDirect3DTexture9_Release(dsttex);
9181 static void texop_test(IDirect3DDevice9 *device)
9183 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9184 IDirect3DTexture9 *texture = NULL;
9185 D3DLOCKED_RECT locked_rect;
9186 D3DCOLOR color;
9187 D3DCAPS9 caps;
9188 HRESULT hr;
9189 unsigned i;
9191 static const struct {
9192 float x, y, z;
9193 float s, t;
9194 D3DCOLOR diffuse;
9195 } quad[] = {
9196 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9197 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9198 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9199 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9202 static const D3DVERTEXELEMENT9 decl_elements[] = {
9203 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9204 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9205 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9206 D3DDECL_END()
9209 static const struct {
9210 D3DTEXTUREOP op;
9211 const char *name;
9212 DWORD caps_flag;
9213 D3DCOLOR result;
9214 } test_data[] = {
9215 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9216 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9217 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9218 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9219 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9220 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9221 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9222 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9223 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9224 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9225 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9226 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9227 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9228 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9229 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9230 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9231 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9232 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9233 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9234 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9235 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9236 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9237 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9240 memset(&caps, 0, sizeof(caps));
9241 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9242 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9244 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9245 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9246 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9247 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9249 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9250 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9251 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9252 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9253 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9254 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9255 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9256 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9257 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9259 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9260 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9261 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9262 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9263 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9264 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9266 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9267 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9270 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9272 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9274 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9277 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9279 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9281 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9283 skip("tex operation %s not supported\n", test_data[i].name);
9284 continue;
9287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9288 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9290 hr = IDirect3DDevice9_BeginScene(device);
9291 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9294 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9296 hr = IDirect3DDevice9_EndScene(device);
9297 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9299 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9300 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9302 color = getPixelColor(device, 320, 240);
9303 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9304 test_data[i].name, color, test_data[i].result);
9307 if (texture) IDirect3DTexture9_Release(texture);
9308 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9311 static void yuv_color_test(IDirect3DDevice9 *device) {
9312 HRESULT hr;
9313 IDirect3DSurface9 *surface = NULL, *target = NULL;
9314 unsigned int fmt, i;
9315 D3DFORMAT format;
9316 const char *fmt_string;
9317 D3DLOCKED_RECT lr;
9318 IDirect3D9 *d3d;
9319 HRESULT color;
9320 DWORD ref_color_left, ref_color_right;
9322 struct {
9323 DWORD in; /* The input color */
9324 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9325 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9326 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9327 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9328 } test_data[] = {
9329 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9330 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9331 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9332 * that
9334 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9335 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9336 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9337 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9338 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9339 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9340 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9341 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9342 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9343 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9344 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9345 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9346 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9347 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9349 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9350 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9351 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9352 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9355 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9356 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9357 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9358 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9360 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9361 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9363 for(fmt = 0; fmt < 2; fmt++) {
9364 if(fmt == 0) {
9365 format = D3DFMT_UYVY;
9366 fmt_string = "D3DFMT_UYVY";
9367 } else {
9368 format = D3DFMT_YUY2;
9369 fmt_string = "D3DFMT_YUY2";
9372 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9373 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9375 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9376 D3DRTYPE_SURFACE, format) != D3D_OK) {
9377 skip("%s is not supported\n", fmt_string);
9378 continue;
9381 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9382 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9383 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9385 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9386 if(fmt == 0) {
9387 ref_color_left = test_data[i].uyvy_left;
9388 ref_color_right = test_data[i].uyvy_right;
9389 } else {
9390 ref_color_left = test_data[i].yuy2_left;
9391 ref_color_right = test_data[i].yuy2_right;
9394 memset(&lr, 0, sizeof(lr));
9395 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9396 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9397 *((DWORD *) lr.pBits) = test_data[i].in;
9398 hr = IDirect3DSurface9_UnlockRect(surface);
9399 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9403 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9404 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9405 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9406 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9408 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9409 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9410 * want to add tests for the filtered pixels as well.
9412 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9413 * differently, so we need a max diff of 16
9415 color = getPixelColor(device, 40, 240);
9416 ok(color_match(color, ref_color_left, 16),
9417 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9418 test_data[i].in, color, ref_color_left, fmt_string);
9419 color = getPixelColor(device, 600, 240);
9420 ok(color_match(color, ref_color_right, 16),
9421 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9422 test_data[i].in, color, ref_color_left, fmt_string);
9424 IDirect3DSurface9_Release(surface);
9426 IDirect3DSurface9_Release(target);
9427 IDirect3D9_Release(d3d);
9430 static void texop_range_test(IDirect3DDevice9 *device)
9432 static const struct {
9433 float x, y, z;
9434 D3DCOLOR diffuse;
9435 } quad[] = {
9436 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9437 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9438 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9439 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9441 HRESULT hr;
9442 IDirect3DTexture9 *texture;
9443 D3DLOCKED_RECT locked_rect;
9444 D3DCAPS9 caps;
9445 DWORD color;
9447 /* We need ADD and SUBTRACT operations */
9448 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9449 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9450 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9451 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9453 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9454 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9457 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9458 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9459 /* Stage 1: result = diffuse(=1.0) + diffuse
9460 * stage 2: result = result - tfactor(= 0.5)
9462 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9463 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9464 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9465 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9466 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9467 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9468 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9469 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9470 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9471 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9472 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9473 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9474 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9475 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9477 hr = IDirect3DDevice9_BeginScene(device);
9478 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9480 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9481 hr = IDirect3DDevice9_EndScene(device);
9482 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9483 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9484 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9486 color = getPixelColor(device, 320, 240);
9487 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9488 color);
9490 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9491 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9492 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9493 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9494 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9495 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9496 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9497 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9498 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9500 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9501 * stage 2: result = result + diffuse(1.0)
9503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9504 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9505 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9506 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9507 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9508 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9509 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9510 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9511 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9512 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9513 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9514 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9515 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9516 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9518 hr = IDirect3DDevice9_BeginScene(device);
9519 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9520 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9521 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9522 hr = IDirect3DDevice9_EndScene(device);
9523 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9524 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9525 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9527 color = getPixelColor(device, 320, 240);
9528 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9529 color);
9531 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9532 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9533 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9534 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9535 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)NULL);
9536 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9537 IDirect3DTexture9_Release(texture);
9540 static void alphareplicate_test(IDirect3DDevice9 *device) {
9541 struct vertex quad[] = {
9542 { -1.0, -1.0, 0.1, 0x80ff00ff },
9543 { 1.0, -1.0, 0.1, 0x80ff00ff },
9544 { -1.0, 1.0, 0.1, 0x80ff00ff },
9545 { 1.0, 1.0, 0.1, 0x80ff00ff },
9547 HRESULT hr;
9548 DWORD color;
9550 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9551 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9553 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9554 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9556 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9557 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9558 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9559 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9561 hr = IDirect3DDevice9_BeginScene(device);
9562 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9563 if(SUCCEEDED(hr)) {
9564 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9565 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9566 hr = IDirect3DDevice9_EndScene(device);
9567 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9570 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9571 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9573 color = getPixelColor(device, 320, 240);
9574 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9575 color);
9577 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9582 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9583 HRESULT hr;
9584 D3DCAPS9 caps;
9585 DWORD color;
9586 struct vertex quad[] = {
9587 { -1.0, -1.0, 0.1, 0x408080c0 },
9588 { 1.0, -1.0, 0.1, 0x408080c0 },
9589 { -1.0, 1.0, 0.1, 0x408080c0 },
9590 { 1.0, 1.0, 0.1, 0x408080c0 },
9593 memset(&caps, 0, sizeof(caps));
9594 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9595 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9596 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9597 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9598 return;
9601 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9602 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9604 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9605 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9607 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9608 * mov r0.a, diffuse.a
9609 * mov r0, r0.a
9611 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9612 * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
9613 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9615 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9616 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9617 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9618 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9619 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9620 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9621 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9622 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9623 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9624 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9625 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9626 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9627 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9628 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9629 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9630 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9632 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9634 hr = IDirect3DDevice9_BeginScene(device);
9635 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9636 if(SUCCEEDED(hr)) {
9637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9638 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9639 hr = IDirect3DDevice9_EndScene(device);
9640 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9643 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9644 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9646 color = getPixelColor(device, 320, 240);
9647 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9648 color);
9650 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9651 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9652 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9653 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9654 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9655 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9658 static void zwriteenable_test(IDirect3DDevice9 *device) {
9659 HRESULT hr;
9660 DWORD color;
9661 struct vertex quad1[] = {
9662 { -1.0, -1.0, 0.1, 0x00ff0000},
9663 { -1.0, 1.0, 0.1, 0x00ff0000},
9664 { 1.0, -1.0, 0.1, 0x00ff0000},
9665 { 1.0, 1.0, 0.1, 0x00ff0000},
9667 struct vertex quad2[] = {
9668 { -1.0, -1.0, 0.9, 0x0000ff00},
9669 { -1.0, 1.0, 0.9, 0x0000ff00},
9670 { 1.0, -1.0, 0.9, 0x0000ff00},
9671 { 1.0, 1.0, 0.9, 0x0000ff00},
9674 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9675 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9677 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9678 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9680 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9681 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9682 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9683 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9684 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9686 hr = IDirect3DDevice9_BeginScene(device);
9687 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9688 if(SUCCEEDED(hr)) {
9689 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9690 * The red color is written because the z test is disabled. The question is wether the z = 0.1 values
9691 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9692 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9693 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9694 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9697 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9701 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9703 hr = IDirect3DDevice9_EndScene(device);
9704 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9707 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9708 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9709 color = getPixelColor(device, 320, 240);
9710 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9711 color);
9713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9717 START_TEST(visual)
9719 IDirect3DDevice9 *device_ptr;
9720 D3DCAPS9 caps;
9721 HRESULT hr;
9722 DWORD color;
9724 d3d9_handle = LoadLibraryA("d3d9.dll");
9725 if (!d3d9_handle)
9727 skip("Could not load d3d9.dll\n");
9728 return;
9731 device_ptr = init_d3d9();
9732 if (!device_ptr)
9734 skip("Creating the device failed\n");
9735 return;
9738 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9740 /* Check for the reliability of the returned data */
9741 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9742 if(FAILED(hr))
9744 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9745 goto cleanup;
9747 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9749 color = getPixelColor(device_ptr, 1, 1);
9750 if(color !=0x00ff0000)
9752 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9753 goto cleanup;
9756 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9757 if(FAILED(hr))
9759 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9760 goto cleanup;
9762 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9764 color = getPixelColor(device_ptr, 639, 479);
9765 if(color != 0x0000ddee)
9767 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9768 goto cleanup;
9771 /* Now execute the real tests */
9772 stretchrect_test(device_ptr);
9773 lighting_test(device_ptr);
9774 clear_test(device_ptr);
9775 fog_test(device_ptr);
9776 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9778 test_cube_wrap(device_ptr);
9779 } else {
9780 skip("No cube texture support\n");
9782 z_range_test(device_ptr);
9783 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9785 maxmip_test(device_ptr);
9787 else
9789 skip("No mipmap support\n");
9791 offscreen_test(device_ptr);
9792 alpha_test(device_ptr);
9793 shademode_test(device_ptr);
9794 srgbtexture_test(device_ptr);
9795 release_buffer_test(device_ptr);
9796 float_texture_test(device_ptr);
9797 g16r16_texture_test(device_ptr);
9798 pixelshader_blending_test(device_ptr);
9799 texture_transform_flags_test(device_ptr);
9800 autogen_mipmap_test(device_ptr);
9801 fixed_function_decl_test(device_ptr);
9802 conditional_np2_repeat_test(device_ptr);
9803 fixed_function_bumpmap_test(device_ptr);
9804 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9805 stencil_cull_test(device_ptr);
9806 } else {
9807 skip("No two sided stencil support\n");
9809 pointsize_test(device_ptr);
9810 tssargtemp_test(device_ptr);
9811 np2_stretch_rect_test(device_ptr);
9812 yuv_color_test(device_ptr);
9813 zwriteenable_test(device_ptr);
9815 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9817 test_constant_clamp_vs(device_ptr);
9818 test_compare_instructions(device_ptr);
9820 else skip("No vs_1_1 support\n");
9822 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9824 test_mova(device_ptr);
9825 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9826 test_vshader_input(device_ptr);
9827 test_vshader_float16(device_ptr);
9828 stream_test(device_ptr);
9829 } else {
9830 skip("No vs_3_0 support\n");
9833 else skip("No vs_2_0 support\n");
9835 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9837 fog_with_shader_test(device_ptr);
9838 fog_srgbwrite_test(device_ptr);
9840 else skip("No vs_1_1 and ps_1_1 support\n");
9842 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9844 texbem_test(device_ptr);
9845 texdepth_test(device_ptr);
9846 texkill_test(device_ptr);
9847 x8l8v8u8_test(device_ptr);
9848 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9849 constant_clamp_ps_test(device_ptr);
9850 cnd_test(device_ptr);
9851 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9852 dp2add_ps_test(device_ptr);
9853 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9854 nested_loop_test(device_ptr);
9855 fixed_function_varying_test(device_ptr);
9856 vFace_register_test(device_ptr);
9857 vpos_register_test(device_ptr);
9858 multiple_rendertargets_test(device_ptr);
9859 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9860 vshader_version_varying_test(device_ptr);
9861 pshader_version_varying_test(device_ptr);
9862 } else {
9863 skip("No vs_3_0 support\n");
9865 } else {
9866 skip("No ps_3_0 support\n");
9868 } else {
9869 skip("No ps_2_0 support\n");
9873 else skip("No ps_1_1 support\n");
9875 texop_test(device_ptr);
9876 texop_range_test(device_ptr);
9877 alphareplicate_test(device_ptr);
9878 dp3_alpha_test(device_ptr);
9880 cleanup:
9881 if(device_ptr) {
9882 ULONG ref;
9884 D3DPRESENT_PARAMETERS present_parameters;
9885 IDirect3DSwapChain9 *swapchain;
9886 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9887 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9888 IDirect3DSwapChain9_Release(swapchain);
9889 ref = IDirect3DDevice9_Release(device_ptr);
9890 DestroyWindow(present_parameters.hDeviceWindow);
9891 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);