push 18e7434c914c4b496a7d961dbc3fc7a912612215
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blobc889e7e1cda30c47316e1b3d7041008447fc0017
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 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2975 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2976 0.0, 1.0, 0.0, 0.0,
2977 0.0, 0.0, 1.0, 0.0,
2978 0.0, 0.0, 0.0, 1.0};
2979 static const D3DVERTEXELEMENT9 decl_elements[] = {
2980 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2981 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2982 D3DDECL_END()
2984 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2985 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2986 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2987 D3DDECL_END()
2989 static const D3DVERTEXELEMENT9 decl_elements3[] = {
2990 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2991 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2992 D3DDECL_END()
2994 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2995 0x00, 0xff, 0x00, 0x00,
2996 0x00, 0x00, 0x00, 0x00,
2997 0x00, 0x00, 0x00, 0x00};
2999 memset(&lr, 0, sizeof(lr));
3000 memset(&lb, 0, sizeof(lb));
3001 IDirect3DDevice9_GetDirect3D(device, &d3d);
3002 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3003 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3004 fmt = D3DFMT_A16B16G16R16;
3006 IDirect3D9_Release(d3d);
3008 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3009 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3010 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3011 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3012 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3013 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3014 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3015 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3016 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3017 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3018 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3019 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3020 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3021 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3022 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3023 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3024 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3025 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3026 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3027 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3028 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3029 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3031 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3033 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3034 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3035 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3036 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3038 if(!texture) {
3039 skip("Failed to create the test texture\n");
3040 return;
3043 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3044 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3045 * 1.0 in red and green for the x and y coords
3047 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3048 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3049 for(y = 0; y < caps.MaxTextureHeight; y++) {
3050 for(x = 0; x < caps.MaxTextureWidth; x++) {
3051 double r_f = (double) y / (double) caps.MaxTextureHeight;
3052 double g_f = (double) x / (double) caps.MaxTextureWidth;
3053 if(fmt == D3DFMT_A16B16G16R16) {
3054 unsigned short r, g;
3055 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3056 r = (unsigned short) (r_f * 65536.0);
3057 g = (unsigned short) (g_f * 65536.0);
3058 dst[0] = r;
3059 dst[1] = g;
3060 dst[2] = 0;
3061 dst[3] = 65535;
3062 } else {
3063 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3064 unsigned char r = (unsigned char) (r_f * 255.0);
3065 unsigned char g = (unsigned char) (g_f * 255.0);
3066 dst[0] = 0;
3067 dst[1] = g;
3068 dst[2] = r;
3069 dst[3] = 255;
3073 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3074 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3075 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3076 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3078 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3079 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3080 hr = IDirect3DDevice9_BeginScene(device);
3081 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3082 if(SUCCEEDED(hr))
3084 float quad1[] = {
3085 -1.0, -1.0, 0.1, 1.0, 1.0,
3086 -1.0, 0.0, 0.1, 1.0, 1.0,
3087 0.0, -1.0, 0.1, 1.0, 1.0,
3088 0.0, 0.0, 0.1, 1.0, 1.0,
3090 float quad2[] = {
3091 -1.0, 0.0, 0.1, 1.0, 1.0,
3092 -1.0, 1.0, 0.1, 1.0, 1.0,
3093 0.0, 0.0, 0.1, 1.0, 1.0,
3094 0.0, 1.0, 0.1, 1.0, 1.0,
3096 float quad3[] = {
3097 0.0, 0.0, 0.1, 0.5, 0.5,
3098 0.0, 1.0, 0.1, 0.5, 0.5,
3099 1.0, 0.0, 0.1, 0.5, 0.5,
3100 1.0, 1.0, 0.1, 0.5, 0.5,
3102 float quad4[] = {
3103 320, 480, 0.1, 1.0, 0.0, 1.0,
3104 320, 240, 0.1, 1.0, 0.0, 1.0,
3105 640, 480, 0.1, 1.0, 0.0, 1.0,
3106 640, 240, 0.1, 1.0, 0.0, 1.0,
3108 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3109 0.0, 0.0, 0.0, 0.0,
3110 0.0, 0.0, 0.0, 0.0,
3111 0.0, 0.0, 0.0, 0.0};
3113 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3114 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3115 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3116 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3117 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3119 /* What happens with transforms enabled? */
3120 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3121 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3123 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3125 /* What happens if 4 coords are used, but only 2 given ?*/
3126 mat[8] = 1.0;
3127 mat[13] = 1.0;
3128 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3129 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3130 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3131 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3135 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3136 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3137 * due to the coords in the vertices. (turns out red, indeed)
3139 memset(mat, 0, sizeof(mat));
3140 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3141 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3142 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3143 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3144 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3145 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3147 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3149 hr = IDirect3DDevice9_EndScene(device);
3150 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3152 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3153 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3154 color = getPixelColor(device, 160, 360);
3155 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3156 color = getPixelColor(device, 160, 120);
3157 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3158 color = getPixelColor(device, 480, 120);
3159 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3160 color = getPixelColor(device, 480, 360);
3161 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3164 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3166 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3167 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3168 hr = IDirect3DDevice9_BeginScene(device);
3169 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3170 if(SUCCEEDED(hr))
3172 float quad1[] = {
3173 -1.0, -1.0, 0.1, 0.8, 0.2,
3174 -1.0, 0.0, 0.1, 0.8, 0.2,
3175 0.0, -1.0, 0.1, 0.8, 0.2,
3176 0.0, 0.0, 0.1, 0.8, 0.2,
3178 float quad2[] = {
3179 -1.0, 0.0, 0.1, 0.5, 1.0,
3180 -1.0, 1.0, 0.1, 0.5, 1.0,
3181 0.0, 0.0, 0.1, 0.5, 1.0,
3182 0.0, 1.0, 0.1, 0.5, 1.0,
3184 float quad3[] = {
3185 0.0, 0.0, 0.1, 0.5, 1.0,
3186 0.0, 1.0, 0.1, 0.5, 1.0,
3187 1.0, 0.0, 0.1, 0.5, 1.0,
3188 1.0, 1.0, 0.1, 0.5, 1.0,
3190 float quad4[] = {
3191 0.0, -1.0, 0.1, 0.8, 0.2,
3192 0.0, 0.0, 0.1, 0.8, 0.2,
3193 1.0, -1.0, 0.1, 0.8, 0.2,
3194 1.0, 0.0, 0.1, 0.8, 0.2,
3196 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3197 0.0, 0.0, 0.0, 0.0,
3198 0.0, 1.0, 0.0, 0.0,
3199 0.0, 0.0, 0.0, 0.0};
3201 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3203 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3204 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3205 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3206 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3209 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3211 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3212 * it behaves like COUNT2 because normal textures require 2 coords
3214 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3217 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3219 /* Just to be sure, the same as quad2 above */
3220 memset(mat, 0, sizeof(mat));
3221 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3222 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3223 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3226 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3228 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3229 * used? And what happens to the first?
3231 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3232 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3234 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3236 hr = IDirect3DDevice9_EndScene(device);
3237 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3239 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3241 color = getPixelColor(device, 160, 360);
3242 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3243 color = getPixelColor(device, 160, 120);
3244 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3245 color = getPixelColor(device, 480, 120);
3246 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3247 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3248 color = getPixelColor(device, 480, 360);
3249 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3250 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3252 IDirect3DTexture9_Release(texture);
3254 /* Test projected textures, without any fancy matrices */
3255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3256 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3257 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3258 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3259 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3260 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3261 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3262 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3264 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3265 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3266 for(x = 0; x < 4; x++) {
3267 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3269 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3270 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3271 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3272 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3274 hr = IDirect3DDevice9_BeginScene(device);
3275 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3276 if(SUCCEEDED(hr))
3278 const float proj_quads[] = {
3279 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3280 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3281 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3282 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3283 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3284 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3285 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3286 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3289 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3290 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3292 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3294 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3295 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3297 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3299 hr = IDirect3DDevice9_EndScene(device);
3300 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3303 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3304 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3305 IDirect3DTexture9_Release(texture);
3307 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3308 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3309 color = getPixelColor(device, 158, 118);
3310 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3311 color = getPixelColor(device, 162, 118);
3312 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3313 color = getPixelColor(device, 158, 122);
3314 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3315 color = getPixelColor(device, 162, 122);
3316 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3318 color = getPixelColor(device, 158, 178);
3319 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3320 color = getPixelColor(device, 162, 178);
3321 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3322 color = getPixelColor(device, 158, 182);
3323 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3324 color = getPixelColor(device, 162, 182);
3325 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3327 color = getPixelColor(device, 318, 118);
3328 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3329 color = getPixelColor(device, 322, 118);
3330 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3331 color = getPixelColor(device, 318, 122);
3332 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3333 color = getPixelColor(device, 322, 122);
3334 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3336 color = getPixelColor(device, 318, 178);
3337 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3338 color = getPixelColor(device, 322, 178);
3339 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3340 color = getPixelColor(device, 318, 182);
3341 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3342 color = getPixelColor(device, 322, 182);
3343 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3345 color = getPixelColor(device, 238, 298);
3346 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3347 color = getPixelColor(device, 242, 298);
3348 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3349 color = getPixelColor(device, 238, 302);
3350 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3351 color = getPixelColor(device, 242, 302);
3352 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3354 color = getPixelColor(device, 238, 388);
3355 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3356 color = getPixelColor(device, 242, 388);
3357 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3358 color = getPixelColor(device, 238, 392);
3359 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3360 color = getPixelColor(device, 242, 392);
3361 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3363 color = getPixelColor(device, 478, 298);
3364 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3365 color = getPixelColor(device, 482, 298);
3366 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3367 color = getPixelColor(device, 478, 302);
3368 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3369 color = getPixelColor(device, 482, 302);
3370 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3372 color = getPixelColor(device, 478, 388);
3373 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3374 color = getPixelColor(device, 482, 388);
3375 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3376 color = getPixelColor(device, 478, 392);
3377 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3378 color = getPixelColor(device, 482, 392);
3379 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3383 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3384 * Thus watch out if sampling from texels between 0 and 1.
3386 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3387 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3388 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3389 if(!volume) {
3390 skip("Failed to create a volume texture\n");
3391 goto out;
3394 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3395 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3396 for(z = 0; z < 32; z++) {
3397 for(y = 0; y < 32; y++) {
3398 for(x = 0; x < 32; x++) {
3399 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3400 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3401 float r_f = (float) x / 31.0;
3402 float g_f = (float) y / 31.0;
3403 float b_f = (float) z / 31.0;
3405 if(fmt == D3DFMT_A16B16G16R16) {
3406 unsigned short *mem_s = mem;
3407 mem_s[0] = r_f * 65535.0;
3408 mem_s[1] = g_f * 65535.0;
3409 mem_s[2] = b_f * 65535.0;
3410 mem_s[3] = 65535;
3411 } else {
3412 unsigned char *mem_c = mem;
3413 mem_c[0] = b_f * 255.0;
3414 mem_c[1] = g_f * 255.0;
3415 mem_c[2] = r_f * 255.0;
3416 mem_c[3] = 255;
3421 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3422 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3424 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3425 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3427 hr = IDirect3DDevice9_BeginScene(device);
3428 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3429 if(SUCCEEDED(hr))
3431 float quad1[] = {
3432 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3433 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3434 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3435 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3437 float quad2[] = {
3438 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3439 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3440 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3441 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3443 float quad3[] = {
3444 0.0, 0.0, 0.1, 0.0, 0.0,
3445 0.0, 1.0, 0.1, 0.0, 0.0,
3446 1.0, 0.0, 0.1, 0.0, 0.0,
3447 1.0, 1.0, 0.1, 0.0, 0.0
3449 float quad4[] = {
3450 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3451 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3452 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3453 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3455 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3456 0.0, 0.0, 1.0, 0.0,
3457 0.0, 1.0, 0.0, 0.0,
3458 0.0, 0.0, 0.0, 1.0};
3459 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3460 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3462 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3463 * values
3465 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3466 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3467 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3468 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3470 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3472 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3473 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3474 * otherwise the w will be missing(blue).
3475 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3476 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3478 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3479 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3481 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3483 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3484 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3485 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3486 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3487 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3488 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3489 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3490 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3491 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3493 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3494 * disable. ATI extends it up to the amount of values needed for the volume texture
3496 memset(mat, 0, sizeof(mat));
3497 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3498 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3499 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3500 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3501 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3502 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3504 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3506 hr = IDirect3DDevice9_EndScene(device);
3507 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3509 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3510 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3512 color = getPixelColor(device, 160, 360);
3513 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3514 color = getPixelColor(device, 160, 120);
3515 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3516 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3517 color = getPixelColor(device, 480, 120);
3518 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3519 color = getPixelColor(device, 480, 360);
3520 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3523 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3524 hr = IDirect3DDevice9_BeginScene(device);
3525 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3526 if(SUCCEEDED(hr))
3528 float quad1[] = {
3529 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3530 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3531 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3532 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3534 float quad2[] = {
3535 -1.0, 0.0, 0.1,
3536 -1.0, 1.0, 0.1,
3537 0.0, 0.0, 0.1,
3538 0.0, 1.0, 0.1,
3540 float quad3[] = {
3541 0.0, 0.0, 0.1, 1.0,
3542 0.0, 1.0, 0.1, 1.0,
3543 1.0, 0.0, 0.1, 1.0,
3544 1.0, 1.0, 0.1, 1.0
3546 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3547 0.0, 0.0, 0.0, 0.0,
3548 0.0, 0.0, 0.0, 0.0,
3549 0.0, 1.0, 0.0, 0.0};
3550 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3551 1.0, 0.0, 0.0, 0.0,
3552 0.0, 1.0, 0.0, 0.0,
3553 0.0, 0.0, 1.0, 0.0};
3554 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3555 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3557 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3559 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3560 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3561 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3562 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3564 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3566 /* None passed */
3567 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3568 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3569 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3570 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3572 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3574 /* 4 used, 1 passed */
3575 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3576 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3577 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3578 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3579 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3580 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3582 hr = IDirect3DDevice9_EndScene(device);
3583 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3587 color = getPixelColor(device, 160, 360);
3588 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3589 color = getPixelColor(device, 160, 120);
3590 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3591 color = getPixelColor(device, 480, 120);
3592 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3593 /* Quad4: unused */
3595 IDirect3DVolumeTexture9_Release(volume);
3597 out:
3598 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3599 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3600 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3601 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3602 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3603 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3604 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3605 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3606 IDirect3DVertexDeclaration9_Release(decl);
3607 IDirect3DVertexDeclaration9_Release(decl2);
3608 IDirect3DVertexDeclaration9_Release(decl3);
3611 static void texdepth_test(IDirect3DDevice9 *device)
3613 IDirect3DPixelShader9 *shader;
3614 HRESULT hr;
3615 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3616 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3617 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3618 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3619 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3620 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3621 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3622 DWORD shader_code[] = {
3623 0xffff0104, /* ps_1_4 */
3624 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3625 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3626 0x0000fffd, /* phase */
3627 0x00000057, 0x800f0005, /* texdepth r5 */
3628 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3629 0x0000ffff /* end */
3631 DWORD color;
3632 float vertex[] = {
3633 -1.0, -1.0, 0.0,
3634 1.0, -1.0, 1.0,
3635 -1.0, 1.0, 0.0,
3636 1.0, 1.0, 1.0
3639 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3640 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3643 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3649 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3650 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3652 /* Fill the depth buffer with a gradient */
3653 hr = IDirect3DDevice9_BeginScene(device);
3654 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3655 if(SUCCEEDED(hr))
3657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3658 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3659 hr = IDirect3DDevice9_EndScene(device);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3663 /* Now perform the actual tests. Same geometry, but with the shader */
3664 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3665 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3668 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3669 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3671 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3673 hr = IDirect3DDevice9_BeginScene(device);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3675 if(SUCCEEDED(hr))
3677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3678 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3680 hr = IDirect3DDevice9_EndScene(device);
3681 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3684 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3685 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3686 color = getPixelColor(device, 158, 240);
3687 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3688 color = getPixelColor(device, 162, 240);
3689 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3691 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3693 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3694 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3695 hr = IDirect3DDevice9_BeginScene(device);
3696 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3697 if(SUCCEEDED(hr))
3699 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3700 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3702 hr = IDirect3DDevice9_EndScene(device);
3703 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3706 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3707 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3708 color = getPixelColor(device, 318, 240);
3709 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3710 color = getPixelColor(device, 322, 240);
3711 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3713 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3715 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3717 hr = IDirect3DDevice9_BeginScene(device);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3719 if(SUCCEEDED(hr))
3721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3722 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3724 hr = IDirect3DDevice9_EndScene(device);
3725 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3727 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3730 color = getPixelColor(device, 1, 240);
3731 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3733 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3735 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3736 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3737 hr = IDirect3DDevice9_BeginScene(device);
3738 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3739 if(SUCCEEDED(hr))
3741 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3742 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3744 hr = IDirect3DDevice9_EndScene(device);
3745 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3747 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3748 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3749 color = getPixelColor(device, 318, 240);
3750 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3751 color = getPixelColor(device, 322, 240);
3752 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3754 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3756 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3757 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3758 hr = IDirect3DDevice9_BeginScene(device);
3759 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3760 if(SUCCEEDED(hr))
3762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3763 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3765 hr = IDirect3DDevice9_EndScene(device);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3768 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3769 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3771 color = getPixelColor(device, 1, 240);
3772 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3774 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3776 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3778 hr = IDirect3DDevice9_BeginScene(device);
3779 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3780 if(SUCCEEDED(hr))
3782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3783 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3785 hr = IDirect3DDevice9_EndScene(device);
3786 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3791 color = getPixelColor(device, 638, 240);
3792 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3794 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3796 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3797 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3798 hr = IDirect3DDevice9_BeginScene(device);
3799 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3800 if(SUCCEEDED(hr))
3802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3803 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3805 hr = IDirect3DDevice9_EndScene(device);
3806 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3809 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3811 color = getPixelColor(device, 638, 240);
3812 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3814 /* Cleanup */
3815 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3816 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3817 IDirect3DPixelShader9_Release(shader);
3819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3820 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3825 static void texkill_test(IDirect3DDevice9 *device)
3827 IDirect3DPixelShader9 *shader;
3828 HRESULT hr;
3829 DWORD color;
3831 const float vertex[] = {
3832 /* bottom top right left */
3833 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3834 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3835 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3836 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3839 DWORD shader_code_11[] = {
3840 0xffff0101, /* ps_1_1 */
3841 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3842 0x00000041, 0xb00f0000, /* texkill t0 */
3843 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3844 0x0000ffff /* end */
3846 DWORD shader_code_20[] = {
3847 0xffff0200, /* ps_2_0 */
3848 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3849 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3850 0x01000041, 0xb00f0000, /* texkill t0 */
3851 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3852 0x0000ffff /* end */
3855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3856 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3857 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3858 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3860 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3862 hr = IDirect3DDevice9_BeginScene(device);
3863 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3864 if(SUCCEEDED(hr))
3866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3867 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3868 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3869 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3870 hr = IDirect3DDevice9_EndScene(device);
3871 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3873 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3875 color = getPixelColor(device, 63, 46);
3876 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3877 color = getPixelColor(device, 66, 46);
3878 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3879 color = getPixelColor(device, 63, 49);
3880 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3881 color = getPixelColor(device, 66, 49);
3882 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3884 color = getPixelColor(device, 578, 46);
3885 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3886 color = getPixelColor(device, 575, 46);
3887 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3888 color = getPixelColor(device, 578, 49);
3889 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3890 color = getPixelColor(device, 575, 49);
3891 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3893 color = getPixelColor(device, 63, 430);
3894 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3895 color = getPixelColor(device, 63, 433);
3896 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3897 color = getPixelColor(device, 66, 433);
3898 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3899 color = getPixelColor(device, 66, 430);
3900 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3902 color = getPixelColor(device, 578, 430);
3903 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3904 color = getPixelColor(device, 578, 433);
3905 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3906 color = getPixelColor(device, 575, 433);
3907 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3908 color = getPixelColor(device, 575, 430);
3909 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3911 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3912 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3913 IDirect3DPixelShader9_Release(shader);
3915 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3916 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3917 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3918 if(FAILED(hr)) {
3919 skip("Failed to create 2.0 test shader, most likely not supported\n");
3920 return;
3923 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3924 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3925 hr = IDirect3DDevice9_BeginScene(device);
3926 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3927 if(SUCCEEDED(hr))
3929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3930 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3931 hr = IDirect3DDevice9_EndScene(device);
3932 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3934 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3936 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3937 color = getPixelColor(device, 63, 46);
3938 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3939 color = getPixelColor(device, 66, 46);
3940 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3941 color = getPixelColor(device, 63, 49);
3942 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3943 color = getPixelColor(device, 66, 49);
3944 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3946 color = getPixelColor(device, 578, 46);
3947 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3948 color = getPixelColor(device, 575, 46);
3949 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3950 color = getPixelColor(device, 578, 49);
3951 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3952 color = getPixelColor(device, 575, 49);
3953 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3955 color = getPixelColor(device, 63, 430);
3956 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3957 color = getPixelColor(device, 63, 433);
3958 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3959 color = getPixelColor(device, 66, 433);
3960 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3961 color = getPixelColor(device, 66, 430);
3962 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3964 color = getPixelColor(device, 578, 430);
3965 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3966 color = getPixelColor(device, 578, 433);
3967 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3968 color = getPixelColor(device, 575, 433);
3969 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3970 color = getPixelColor(device, 575, 430);
3971 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3973 /* Cleanup */
3974 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3975 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3976 IDirect3DPixelShader9_Release(shader);
3979 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3981 IDirect3D9 *d3d9;
3982 HRESULT hr;
3983 IDirect3DTexture9 *texture;
3984 IDirect3DPixelShader9 *shader;
3985 IDirect3DPixelShader9 *shader2;
3986 D3DLOCKED_RECT lr;
3987 DWORD color;
3988 DWORD shader_code[] = {
3989 0xffff0101, /* ps_1_1 */
3990 0x00000042, 0xb00f0000, /* tex t0 */
3991 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3992 0x0000ffff /* end */
3994 DWORD shader_code2[] = {
3995 0xffff0101, /* ps_1_1 */
3996 0x00000042, 0xb00f0000, /* tex t0 */
3997 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
3998 0x0000ffff /* end */
4001 float quad[] = {
4002 -1.0, -1.0, 0.1, 0.5, 0.5,
4003 1.0, -1.0, 0.1, 0.5, 0.5,
4004 -1.0, 1.0, 0.1, 0.5, 0.5,
4005 1.0, 1.0, 0.1, 0.5, 0.5,
4008 memset(&lr, 0, sizeof(lr));
4009 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4010 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4011 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4012 IDirect3D9_Release(d3d9);
4013 if(FAILED(hr)) {
4014 skip("No D3DFMT_X8L8V8U8 support\n");
4017 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4020 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4022 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4023 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4024 *((DWORD *) lr.pBits) = 0x11ca3141;
4025 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4026 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4028 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4030 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4033 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4034 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4035 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4036 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4037 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4038 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4040 hr = IDirect3DDevice9_BeginScene(device);
4041 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4042 if(SUCCEEDED(hr))
4044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4045 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4047 hr = IDirect3DDevice9_EndScene(device);
4048 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4050 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4051 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4052 color = getPixelColor(device, 578, 430);
4053 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4054 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4056 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4057 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4058 hr = IDirect3DDevice9_BeginScene(device);
4059 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4060 if(SUCCEEDED(hr))
4062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4063 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4065 hr = IDirect3DDevice9_EndScene(device);
4066 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4068 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4069 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4070 color = getPixelColor(device, 578, 430);
4071 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4073 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4074 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4075 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4076 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4077 IDirect3DPixelShader9_Release(shader);
4078 IDirect3DPixelShader9_Release(shader2);
4079 IDirect3DTexture9_Release(texture);
4082 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4084 HRESULT hr;
4085 IDirect3D9 *d3d;
4086 IDirect3DTexture9 *texture = NULL;
4087 IDirect3DSurface9 *surface;
4088 DWORD color;
4089 const RECT r1 = {256, 256, 512, 512};
4090 const RECT r2 = {512, 256, 768, 512};
4091 const RECT r3 = {256, 512, 512, 768};
4092 const RECT r4 = {512, 512, 768, 768};
4093 unsigned int x, y;
4094 D3DLOCKED_RECT lr;
4095 memset(&lr, 0, sizeof(lr));
4097 IDirect3DDevice9_GetDirect3D(device, &d3d);
4098 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4099 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4100 skip("No autogenmipmap support\n");
4101 IDirect3D9_Release(d3d);
4102 return;
4104 IDirect3D9_Release(d3d);
4106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4107 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4109 /* Make the mipmap big, so that a smaller mipmap is used
4111 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4112 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4113 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4115 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4116 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4117 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4118 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4119 for(y = 0; y < 1024; y++) {
4120 for(x = 0; x < 1024; x++) {
4121 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4122 POINT pt;
4124 pt.x = x;
4125 pt.y = y;
4126 if(PtInRect(&r1, pt)) {
4127 *dst = 0xffff0000;
4128 } else if(PtInRect(&r2, pt)) {
4129 *dst = 0xff00ff00;
4130 } else if(PtInRect(&r3, pt)) {
4131 *dst = 0xff0000ff;
4132 } else if(PtInRect(&r4, pt)) {
4133 *dst = 0xff000000;
4134 } else {
4135 *dst = 0xffffffff;
4139 hr = IDirect3DSurface9_UnlockRect(surface);
4140 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4141 IDirect3DSurface9_Release(surface);
4143 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4145 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4146 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4148 hr = IDirect3DDevice9_BeginScene(device);
4149 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4150 if(SUCCEEDED(hr)) {
4151 const float quad[] = {
4152 -0.5, -0.5, 0.1, 0.0, 0.0,
4153 -0.5, 0.5, 0.1, 0.0, 1.0,
4154 0.5, -0.5, 0.1, 1.0, 0.0,
4155 0.5, 0.5, 0.1, 1.0, 1.0
4158 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4159 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4161 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4162 hr = IDirect3DDevice9_EndScene(device);
4163 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4165 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4168 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4169 IDirect3DTexture9_Release(texture);
4171 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4172 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4173 color = getPixelColor(device, 200, 200);
4174 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4175 color = getPixelColor(device, 280, 200);
4176 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4177 color = getPixelColor(device, 360, 200);
4178 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4179 color = getPixelColor(device, 440, 200);
4180 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4181 color = getPixelColor(device, 200, 270);
4182 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4183 color = getPixelColor(device, 280, 270);
4184 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4185 color = getPixelColor(device, 360, 270);
4186 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4187 color = getPixelColor(device, 440, 270);
4188 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4191 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4193 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4194 IDirect3DVertexDeclaration9 *decl;
4195 HRESULT hr;
4196 DWORD color;
4197 DWORD shader_code_11[] = {
4198 0xfffe0101, /* vs_1_1 */
4199 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4200 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4201 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4202 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4203 0x0000ffff /* end */
4205 DWORD shader_code_11_2[] = {
4206 0xfffe0101, /* vs_1_1 */
4207 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4208 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4209 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4210 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4211 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4212 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4213 0x0000ffff /* end */
4215 DWORD shader_code_20[] = {
4216 0xfffe0200, /* vs_2_0 */
4217 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4218 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4219 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4220 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4221 0x0000ffff /* end */
4223 DWORD shader_code_20_2[] = {
4224 0xfffe0200, /* vs_2_0 */
4225 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4226 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4227 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4228 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4229 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4230 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4231 0x0000ffff /* end */
4233 static const D3DVERTEXELEMENT9 decl_elements[] = {
4234 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4235 D3DDECL_END()
4237 float quad1[] = {
4238 -1.0, -1.0, 0.1,
4239 0.0, -1.0, 0.1,
4240 -1.0, 0.0, 0.1,
4241 0.0, 0.0, 0.1
4243 float quad2[] = {
4244 0.0, -1.0, 0.1,
4245 1.0, -1.0, 0.1,
4246 0.0, 0.0, 0.1,
4247 1.0, 0.0, 0.1
4249 float quad3[] = {
4250 0.0, 0.0, 0.1,
4251 1.0, 0.0, 0.1,
4252 0.0, 1.0, 0.1,
4253 1.0, 1.0, 0.1
4255 float quad4[] = {
4256 -1.0, 0.0, 0.1,
4257 0.0, 0.0, 0.1,
4258 -1.0, 1.0, 0.1,
4259 0.0, 1.0, 0.1
4261 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4262 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4264 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4265 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4267 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4269 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4271 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4272 if(FAILED(hr)) shader_20 = NULL;
4273 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4274 if(FAILED(hr)) shader_20_2 = NULL;
4275 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4276 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4278 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4279 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4280 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4281 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4282 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4283 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4285 hr = IDirect3DDevice9_BeginScene(device);
4286 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4287 if(SUCCEEDED(hr))
4289 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4290 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4292 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4294 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4295 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4297 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4299 if(shader_20) {
4300 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4301 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4303 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4306 if(shader_20_2) {
4307 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4310 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4313 hr = IDirect3DDevice9_EndScene(device);
4314 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4316 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4319 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4321 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4322 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4324 color = getPixelColor(device, 160, 360);
4325 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4326 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4327 color = getPixelColor(device, 480, 360);
4328 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4330 if(shader_20) {
4331 color = getPixelColor(device, 160, 120);
4332 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4333 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4335 if(shader_20_2) {
4336 color = getPixelColor(device, 480, 120);
4337 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4338 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4341 IDirect3DVertexDeclaration9_Release(decl);
4342 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4343 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4344 IDirect3DVertexShader9_Release(shader_11_2);
4345 IDirect3DVertexShader9_Release(shader_11);
4348 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4350 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4351 HRESULT hr;
4352 DWORD color;
4353 DWORD shader_code_11[] = {
4354 0xffff0101, /* ps_1_1 */
4355 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4356 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4357 0x0000ffff /* end */
4359 DWORD shader_code_12[] = {
4360 0xffff0102, /* ps_1_2 */
4361 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4362 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4363 0x0000ffff /* end */
4365 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4366 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4367 * During development of this test, 1.3 shaders were verified too
4369 DWORD shader_code_14[] = {
4370 0xffff0104, /* ps_1_4 */
4371 /* Try to make one constant local. It gets clamped too, although the binary contains
4372 * the bigger numbers
4374 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4375 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4376 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4377 0x0000ffff /* end */
4379 DWORD shader_code_20[] = {
4380 0xffff0200, /* ps_2_0 */
4381 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4382 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4383 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4384 0x0000ffff /* end */
4386 float quad1[] = {
4387 -1.0, -1.0, 0.1,
4388 0.0, -1.0, 0.1,
4389 -1.0, 0.0, 0.1,
4390 0.0, 0.0, 0.1
4392 float quad2[] = {
4393 0.0, -1.0, 0.1,
4394 1.0, -1.0, 0.1,
4395 0.0, 0.0, 0.1,
4396 1.0, 0.0, 0.1
4398 float quad3[] = {
4399 0.0, 0.0, 0.1,
4400 1.0, 0.0, 0.1,
4401 0.0, 1.0, 0.1,
4402 1.0, 1.0, 0.1
4404 float quad4[] = {
4405 -1.0, 0.0, 0.1,
4406 0.0, 0.0, 0.1,
4407 -1.0, 1.0, 0.1,
4408 0.0, 1.0, 0.1
4410 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4411 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4414 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4416 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4418 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4419 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4420 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4421 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4422 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4423 if(FAILED(hr)) shader_20 = NULL;
4425 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4426 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4427 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4428 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4429 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4430 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4432 hr = IDirect3DDevice9_BeginScene(device);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4434 if(SUCCEEDED(hr))
4436 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4437 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4439 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4441 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4442 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4444 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4446 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4447 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4448 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4449 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4451 if(shader_20) {
4452 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4453 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4455 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4458 hr = IDirect3DDevice9_EndScene(device);
4459 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4461 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4462 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4464 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4465 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4467 color = getPixelColor(device, 160, 360);
4468 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4469 "quad 1 has color %08x, expected 0x00808000\n", color);
4470 color = getPixelColor(device, 480, 360);
4471 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4472 "quad 2 has color %08x, expected 0x00808000\n", color);
4473 color = getPixelColor(device, 480, 120);
4474 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4475 "quad 3 has color %08x, expected 0x00808000\n", color);
4476 if(shader_20) {
4477 color = getPixelColor(device, 160, 120);
4478 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4479 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4482 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4483 IDirect3DPixelShader9_Release(shader_14);
4484 IDirect3DPixelShader9_Release(shader_12);
4485 IDirect3DPixelShader9_Release(shader_11);
4488 static void dp2add_ps_test(IDirect3DDevice9 *device)
4490 IDirect3DPixelShader9 *shader_dp2add = NULL;
4491 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4492 HRESULT hr;
4493 DWORD color;
4495 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4496 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4497 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4498 * r0 first.
4499 * The result here for the r,g,b components should be roughly 0.5:
4500 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4501 static const DWORD shader_code_dp2add[] = {
4502 0xffff0200, /* ps_2_0 */
4503 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4505 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4506 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4508 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4509 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4510 0x0000ffff /* end */
4513 /* Test the _sat modifier, too. Result here should be:
4514 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4515 * _SAT: ==> 1.0
4516 * ADD: (1.0 + -0.5) = 0.5
4518 static const DWORD shader_code_dp2add_sat[] = {
4519 0xffff0200, /* ps_2_0 */
4520 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4522 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4523 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4524 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4526 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4527 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4528 0x0000ffff /* end */
4531 const float quad[] = {
4532 -1.0, -1.0, 0.1,
4533 1.0, -1.0, 0.1,
4534 -1.0, 1.0, 0.1,
4535 1.0, 1.0, 0.1
4539 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4540 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4542 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4543 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4545 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4546 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4548 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4549 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4551 if (shader_dp2add) {
4553 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4554 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4556 hr = IDirect3DDevice9_BeginScene(device);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4558 if(SUCCEEDED(hr))
4560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4561 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4563 hr = IDirect3DDevice9_EndScene(device);
4564 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4566 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4567 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4569 color = getPixelColor(device, 360, 240);
4570 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4572 IDirect3DPixelShader9_Release(shader_dp2add);
4573 } else {
4574 skip("dp2add shader creation failed\n");
4577 if (shader_dp2add_sat) {
4579 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4580 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4582 hr = IDirect3DDevice9_BeginScene(device);
4583 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4584 if(SUCCEEDED(hr))
4586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4587 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4589 hr = IDirect3DDevice9_EndScene(device);
4590 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4592 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4593 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4595 color = getPixelColor(device, 360, 240);
4596 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4598 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4599 } else {
4600 skip("dp2add shader creation failed\n");
4603 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4604 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4607 static void cnd_test(IDirect3DDevice9 *device)
4609 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4610 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4611 HRESULT hr;
4612 DWORD color;
4613 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4614 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4615 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4617 DWORD shader_code_11[] = {
4618 0xffff0101, /* ps_1_1 */
4619 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4620 0x00000040, 0xb00f0000, /* texcoord t0 */
4621 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4622 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4623 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4624 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4625 0x0000ffff /* end */
4627 DWORD shader_code_12[] = {
4628 0xffff0102, /* ps_1_2 */
4629 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4630 0x00000040, 0xb00f0000, /* texcoord t0 */
4631 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4632 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4633 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4634 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4635 0x0000ffff /* end */
4637 DWORD shader_code_13[] = {
4638 0xffff0103, /* ps_1_3 */
4639 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4640 0x00000040, 0xb00f0000, /* texcoord t0 */
4641 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4642 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4643 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4644 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4645 0x0000ffff /* end */
4647 DWORD shader_code_14[] = {
4648 0xffff0104, /* ps_1_3 */
4649 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4650 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4651 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4652 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4653 0x0000ffff /* end */
4656 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4657 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4658 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4659 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4660 * native CreatePixelShader returns an error.
4662 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4663 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4664 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4665 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4667 DWORD shader_code_11_coissue[] = {
4668 0xffff0101, /* ps_1_1 */
4669 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4670 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4671 0x00000040, 0xb00f0000, /* texcoord t0 */
4672 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4673 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4674 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4675 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4676 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4677 /* 0x40000000 = D3DSI_COISSUE */
4678 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4679 0x0000ffff /* end */
4681 DWORD shader_code_12_coissue[] = {
4682 0xffff0102, /* ps_1_2 */
4683 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4684 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4685 0x00000040, 0xb00f0000, /* texcoord t0 */
4686 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4687 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4688 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4689 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4690 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4691 /* 0x40000000 = D3DSI_COISSUE */
4692 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4693 0x0000ffff /* end */
4695 DWORD shader_code_13_coissue[] = {
4696 0xffff0103, /* ps_1_3 */
4697 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4698 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4699 0x00000040, 0xb00f0000, /* texcoord t0 */
4700 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4701 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4702 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4703 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4704 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4705 /* 0x40000000 = D3DSI_COISSUE */
4706 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4707 0x0000ffff /* end */
4709 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4710 * compare against 0.5
4712 DWORD shader_code_14_coissue[] = {
4713 0xffff0104, /* ps_1_4 */
4714 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4715 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4716 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4717 /* 0x40000000 = D3DSI_COISSUE */
4718 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4719 0x0000ffff /* end */
4721 float quad1[] = {
4722 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4723 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4724 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4725 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4727 float quad2[] = {
4728 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4729 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4730 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4731 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4733 float quad3[] = {
4734 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4735 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4736 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4737 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4739 float quad4[] = {
4740 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4741 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4742 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4743 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4745 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4746 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4747 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4748 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4750 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4753 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4754 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4755 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4756 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4757 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4758 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4759 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4760 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4761 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4763 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4764 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4765 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4766 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4767 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4768 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4770 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4771 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4772 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4773 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4774 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4775 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4777 hr = IDirect3DDevice9_BeginScene(device);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4779 if(SUCCEEDED(hr))
4781 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4782 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4784 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4786 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4787 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4789 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4792 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4794 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4796 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4797 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4799 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4801 hr = IDirect3DDevice9_EndScene(device);
4802 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4807 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4810 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4811 color = getPixelColor(device, 158, 118);
4812 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4813 color = getPixelColor(device, 162, 118);
4814 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4815 color = getPixelColor(device, 158, 122);
4816 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4817 color = getPixelColor(device, 162, 122);
4818 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4820 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4821 color = getPixelColor(device, 158, 358);
4822 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4823 color = getPixelColor(device, 162, 358);
4824 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4825 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4826 color = getPixelColor(device, 158, 362);
4827 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4828 color = getPixelColor(device, 162, 362);
4829 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4830 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4832 /* 1.2 shader */
4833 color = getPixelColor(device, 478, 358);
4834 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4835 color = getPixelColor(device, 482, 358);
4836 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4837 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4838 color = getPixelColor(device, 478, 362);
4839 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4840 color = getPixelColor(device, 482, 362);
4841 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4842 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4844 /* 1.3 shader */
4845 color = getPixelColor(device, 478, 118);
4846 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4847 color = getPixelColor(device, 482, 118);
4848 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4849 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4850 color = getPixelColor(device, 478, 122);
4851 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4852 color = getPixelColor(device, 482, 122);
4853 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4854 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4857 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4858 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4860 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4861 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4863 hr = IDirect3DDevice9_BeginScene(device);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4865 if(SUCCEEDED(hr))
4867 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4868 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4870 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4872 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4873 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4874 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4875 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4877 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4878 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4880 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4882 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4885 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4887 hr = IDirect3DDevice9_EndScene(device);
4888 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4890 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4891 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4893 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4896 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4897 * that we swapped the values in c1 and c2 to make the other tests return some color
4899 color = getPixelColor(device, 158, 118);
4900 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4901 color = getPixelColor(device, 162, 118);
4902 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4903 color = getPixelColor(device, 158, 122);
4904 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4905 color = getPixelColor(device, 162, 122);
4906 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4908 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4909 color = getPixelColor(device, 158, 358);
4910 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4911 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4912 color = getPixelColor(device, 162, 358);
4913 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4914 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4915 color = getPixelColor(device, 158, 362);
4916 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4917 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4918 color = getPixelColor(device, 162, 362);
4919 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4920 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4922 /* 1.2 shader */
4923 color = getPixelColor(device, 478, 358);
4924 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4925 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4926 color = getPixelColor(device, 482, 358);
4927 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4928 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4929 color = getPixelColor(device, 478, 362);
4930 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4931 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4932 color = getPixelColor(device, 482, 362);
4933 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4934 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4936 /* 1.3 shader */
4937 color = getPixelColor(device, 478, 118);
4938 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4939 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4940 color = getPixelColor(device, 482, 118);
4941 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4942 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4943 color = getPixelColor(device, 478, 122);
4944 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4945 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4946 color = getPixelColor(device, 482, 122);
4947 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4948 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4950 IDirect3DPixelShader9_Release(shader_14_coissue);
4951 IDirect3DPixelShader9_Release(shader_13_coissue);
4952 IDirect3DPixelShader9_Release(shader_12_coissue);
4953 IDirect3DPixelShader9_Release(shader_11_coissue);
4954 IDirect3DPixelShader9_Release(shader_14);
4955 IDirect3DPixelShader9_Release(shader_13);
4956 IDirect3DPixelShader9_Release(shader_12);
4957 IDirect3DPixelShader9_Release(shader_11);
4960 static void nested_loop_test(IDirect3DDevice9 *device) {
4961 const DWORD shader_code[] = {
4962 0xffff0300, /* ps_3_0 */
4963 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4964 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4965 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
4966 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4967 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4968 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4969 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
4970 0x0000001d, /* endloop */
4971 0x0000001d, /* endloop */
4972 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4973 0x0000ffff /* end */
4975 IDirect3DPixelShader9 *shader;
4976 HRESULT hr;
4977 DWORD color;
4978 const float quad[] = {
4979 -1.0, -1.0, 0.1,
4980 1.0, -1.0, 0.1,
4981 -1.0, 1.0, 0.1,
4982 1.0, 1.0, 0.1
4985 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
4987 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
4989 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4990 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4994 hr = IDirect3DDevice9_BeginScene(device);
4995 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4996 if(SUCCEEDED(hr))
4998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4999 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5000 hr = IDirect3DDevice9_EndScene(device);
5001 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5003 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5006 color = getPixelColor(device, 360, 240);
5007 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5008 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5010 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5011 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5012 IDirect3DPixelShader9_Release(shader);
5015 struct varying_test_struct
5017 const DWORD *shader_code;
5018 IDirect3DPixelShader9 *shader;
5019 DWORD color, color_rhw;
5020 const char *name;
5021 BOOL todo, todo_rhw;
5024 struct hugeVertex
5026 float pos_x, pos_y, pos_z, rhw;
5027 float weight_1, weight_2, weight_3, weight_4;
5028 float index_1, index_2, index_3, index_4;
5029 float normal_1, normal_2, normal_3, normal_4;
5030 float fog_1, fog_2, fog_3, fog_4;
5031 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5032 float tangent_1, tangent_2, tangent_3, tangent_4;
5033 float binormal_1, binormal_2, binormal_3, binormal_4;
5034 float depth_1, depth_2, depth_3, depth_4;
5035 DWORD diffuse, specular;
5038 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5039 /* dcl_position: fails to compile */
5040 const DWORD blendweight_code[] = {
5041 0xffff0300, /* ps_3_0 */
5042 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5043 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5044 0x0000ffff /* end */
5046 const DWORD blendindices_code[] = {
5047 0xffff0300, /* ps_3_0 */
5048 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5049 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5050 0x0000ffff /* end */
5052 const DWORD normal_code[] = {
5053 0xffff0300, /* ps_3_0 */
5054 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5055 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5056 0x0000ffff /* end */
5058 /* psize: fails? */
5059 const DWORD texcoord0_code[] = {
5060 0xffff0300, /* ps_3_0 */
5061 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5062 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5063 0x0000ffff /* end */
5065 const DWORD tangent_code[] = {
5066 0xffff0300, /* ps_3_0 */
5067 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5068 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5069 0x0000ffff /* end */
5071 const DWORD binormal_code[] = {
5072 0xffff0300, /* ps_3_0 */
5073 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5074 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5075 0x0000ffff /* end */
5077 /* tessfactor: fails */
5078 /* positiont: fails */
5079 const DWORD color_code[] = {
5080 0xffff0300, /* ps_3_0 */
5081 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5082 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5083 0x0000ffff /* end */
5085 const DWORD fog_code[] = {
5086 0xffff0300, /* ps_3_0 */
5087 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5088 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5089 0x0000ffff /* end */
5091 const DWORD depth_code[] = {
5092 0xffff0300, /* ps_3_0 */
5093 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5094 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5095 0x0000ffff /* end */
5097 const DWORD specular_code[] = {
5098 0xffff0300, /* ps_3_0 */
5099 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5100 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5101 0x0000ffff /* end */
5103 /* sample: fails */
5105 struct varying_test_struct tests[] = {
5106 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5107 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5108 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5109 /* Why does dx not forward the texcoord? */
5110 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5111 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5112 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5113 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5114 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5115 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5116 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5118 /* Declare a monster vertex type :-) */
5119 static const D3DVERTEXELEMENT9 decl_elements[] = {
5120 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5121 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5122 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5123 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5124 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5125 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5126 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5127 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5128 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5129 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5130 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5131 D3DDECL_END()
5133 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5134 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5135 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5136 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5137 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5138 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5139 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5140 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5141 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5142 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5143 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5144 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5145 D3DDECL_END()
5147 struct hugeVertex data[4] = {
5149 -1.0, -1.0, 0.1, 1.0,
5150 0.1, 0.1, 0.1, 0.1,
5151 0.2, 0.2, 0.2, 0.2,
5152 0.3, 0.3, 0.3, 0.3,
5153 0.4, 0.4, 0.4, 0.4,
5154 0.50, 0.55, 0.55, 0.55,
5155 0.6, 0.6, 0.6, 0.7,
5156 0.7, 0.7, 0.7, 0.6,
5157 0.8, 0.8, 0.8, 0.8,
5158 0xe6e6e6e6, /* 0.9 * 256 */
5159 0x224488ff /* Nothing special */
5162 1.0, -1.0, 0.1, 1.0,
5163 0.1, 0.1, 0.1, 0.1,
5164 0.2, 0.2, 0.2, 0.2,
5165 0.3, 0.3, 0.3, 0.3,
5166 0.4, 0.4, 0.4, 0.4,
5167 0.50, 0.55, 0.55, 0.55,
5168 0.6, 0.6, 0.6, 0.7,
5169 0.7, 0.7, 0.7, 0.6,
5170 0.8, 0.8, 0.8, 0.8,
5171 0xe6e6e6e6, /* 0.9 * 256 */
5172 0x224488ff /* Nothing special */
5175 -1.0, 1.0, 0.1, 1.0,
5176 0.1, 0.1, 0.1, 0.1,
5177 0.2, 0.2, 0.2, 0.2,
5178 0.3, 0.3, 0.3, 0.3,
5179 0.4, 0.4, 0.4, 0.4,
5180 0.50, 0.55, 0.55, 0.55,
5181 0.6, 0.6, 0.6, 0.7,
5182 0.7, 0.7, 0.7, 0.6,
5183 0.8, 0.8, 0.8, 0.8,
5184 0xe6e6e6e6, /* 0.9 * 256 */
5185 0x224488ff /* Nothing special */
5188 1.0, 1.0, 0.1, 1.0,
5189 0.1, 0.1, 0.1, 0.1,
5190 0.2, 0.2, 0.2, 0.2,
5191 0.3, 0.3, 0.3, 0.3,
5192 0.4, 0.4, 0.4, 0.4,
5193 0.50, 0.55, 0.55, 0.55,
5194 0.6, 0.6, 0.6, 0.7,
5195 0.7, 0.7, 0.7, 0.6,
5196 0.8, 0.8, 0.8, 0.8,
5197 0xe6e6e6e6, /* 0.9 * 256 */
5198 0x224488ff /* Nothing special */
5201 struct hugeVertex data2[4];
5202 IDirect3DVertexDeclaration9 *decl;
5203 IDirect3DVertexDeclaration9 *decl2;
5204 HRESULT hr;
5205 unsigned int i;
5206 DWORD color, r, g, b, r_e, g_e, b_e;
5207 BOOL drawok;
5209 memcpy(data2, data, sizeof(data2));
5210 data2[0].pos_x = 0; data2[0].pos_y = 0;
5211 data2[1].pos_x = 640; data2[1].pos_y = 0;
5212 data2[2].pos_x = 0; data2[2].pos_y = 480;
5213 data2[3].pos_x = 640; data2[3].pos_y = 480;
5215 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5216 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5217 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5218 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5219 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5220 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5222 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5224 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5225 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5226 tests[i].name, hr);
5229 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5232 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5234 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5235 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5237 hr = IDirect3DDevice9_BeginScene(device);
5238 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5239 drawok = FALSE;
5240 if(SUCCEEDED(hr))
5242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5243 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5244 drawok = SUCCEEDED(hr);
5245 hr = IDirect3DDevice9_EndScene(device);
5246 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5248 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5249 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5251 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5252 * the failure and do not check the color if it failed
5254 if(!drawok) {
5255 continue;
5258 color = getPixelColor(device, 360, 240);
5259 r = color & 0x00ff0000 >> 16;
5260 g = color & 0x0000ff00 >> 8;
5261 b = color & 0x000000ff;
5262 r_e = tests[i].color & 0x00ff0000 >> 16;
5263 g_e = tests[i].color & 0x0000ff00 >> 8;
5264 b_e = tests[i].color & 0x000000ff;
5266 if(tests[i].todo) {
5267 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5268 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5269 tests[i].name, color, tests[i].color);
5270 } else {
5271 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5272 "Test %s returned color 0x%08x, expected 0x%08x\n",
5273 tests[i].name, color, tests[i].color);
5277 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5278 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5279 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5281 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5282 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5284 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5287 hr = IDirect3DDevice9_BeginScene(device);
5288 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5289 if(SUCCEEDED(hr))
5291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5292 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5293 hr = IDirect3DDevice9_EndScene(device);
5294 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5297 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5299 color = getPixelColor(device, 360, 240);
5300 r = color & 0x00ff0000 >> 16;
5301 g = color & 0x0000ff00 >> 8;
5302 b = color & 0x000000ff;
5303 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5304 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5305 b_e = tests[i].color_rhw & 0x000000ff;
5307 if(tests[i].todo_rhw) {
5308 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5309 * pipeline
5311 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5312 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5313 tests[i].name, color, tests[i].color_rhw);
5314 } else {
5315 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5316 "Test %s returned color 0x%08x, expected 0x%08x\n",
5317 tests[i].name, color, tests[i].color_rhw);
5321 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5323 IDirect3DPixelShader9_Release(tests[i].shader);
5326 IDirect3DVertexDeclaration9_Release(decl2);
5327 IDirect3DVertexDeclaration9_Release(decl);
5330 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5331 static const DWORD ps_code[] = {
5332 0xffff0300, /* ps_3_0 */
5333 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5334 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5335 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5336 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5337 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5338 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5339 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5340 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5341 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5343 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5344 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5345 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5346 0x0000001d, /* endloop */
5347 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5348 0x0000ffff /* end */
5350 static const DWORD vs_1_code[] = {
5351 0xfffe0101, /* vs_1_1 */
5352 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5353 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5354 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5355 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5356 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5357 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5358 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5359 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5360 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5361 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5362 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5363 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5364 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5365 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5366 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5367 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5368 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5369 0x0000ffff
5371 DWORD vs_2_code[] = {
5372 0xfffe0200, /* vs_2_0 */
5373 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5374 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5375 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5376 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5377 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5378 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5379 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5380 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5381 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5382 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5383 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5384 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5385 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5386 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5387 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5388 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5389 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5390 0x0000ffff /* end */
5392 /* TODO: Define normal, tangent, blendweight and depth here */
5393 static const DWORD vs_3_code[] = {
5394 0xfffe0300, /* vs_3_0 */
5395 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5396 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5397 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5398 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5399 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5400 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5401 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5402 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5403 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5404 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5405 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5406 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5407 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5408 0x0000ffff /* end */
5410 float quad1[] = {
5411 -1.0, -1.0, 0.1,
5412 0.0, -1.0, 0.1,
5413 -1.0, 0.0, 0.1,
5414 0.0, 0.0, 0.1
5416 float quad2[] = {
5417 0.0, -1.0, 0.1,
5418 1.0, -1.0, 0.1,
5419 0.0, 0.0, 0.1,
5420 1.0, 0.0, 0.1
5422 float quad3[] = {
5423 -1.0, 0.0, 0.1,
5424 0.0, 0.0, 0.1,
5425 -1.0, 1.0, 0.1,
5426 0.0, 1.0, 0.1
5429 HRESULT hr;
5430 DWORD color;
5431 IDirect3DPixelShader9 *pixelshader = NULL;
5432 IDirect3DVertexShader9 *vs_1_shader = NULL;
5433 IDirect3DVertexShader9 *vs_2_shader = NULL;
5434 IDirect3DVertexShader9 *vs_3_shader = NULL;
5436 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5438 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5439 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5440 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5441 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5442 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5443 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5444 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5445 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5446 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5447 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5448 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5450 hr = IDirect3DDevice9_BeginScene(device);
5451 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5452 if(SUCCEEDED(hr))
5454 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5456 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5457 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5459 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5460 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5462 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5464 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5465 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5467 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5469 hr = IDirect3DDevice9_EndScene(device);
5470 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5472 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5473 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5475 color = getPixelColor(device, 160, 120);
5476 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5477 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5478 color = getPixelColor(device, 160, 360);
5479 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5480 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5481 color = getPixelColor(device, 480, 360);
5482 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5483 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5485 /* cleanup */
5486 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5487 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5488 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5489 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5490 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5491 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5492 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5493 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5496 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5497 static const DWORD vs_code[] = {
5498 0xfffe0300, /* vs_3_0 */
5499 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5500 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5501 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5502 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5503 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5504 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5505 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5506 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5507 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5508 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5509 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5510 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5511 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5513 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5514 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5515 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5516 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5517 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5518 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5519 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5520 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5521 0x0000ffff /* end */
5523 static const DWORD ps_1_code[] = {
5524 0xffff0104, /* ps_1_4 */
5525 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5526 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5527 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5528 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5529 0x0000ffff /* end */
5531 static const DWORD ps_2_code[] = {
5532 0xffff0200, /* ps_2_0 */
5533 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5534 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5535 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5537 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5538 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5539 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5540 0x0000ffff /* end */
5542 static const DWORD ps_3_code[] = {
5543 0xffff0300, /* ps_3_0 */
5544 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5545 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5546 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5548 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5549 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5550 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5551 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5552 0x0000ffff /* end */
5555 float quad1[] = {
5556 -1.0, -1.0, 0.1,
5557 0.0, -1.0, 0.1,
5558 -1.0, 0.0, 0.1,
5559 0.0, 0.0, 0.1
5561 float quad2[] = {
5562 0.0, -1.0, 0.1,
5563 1.0, -1.0, 0.1,
5564 0.0, 0.0, 0.1,
5565 1.0, 0.0, 0.1
5567 float quad3[] = {
5568 -1.0, 0.0, 0.1,
5569 0.0, 0.0, 0.1,
5570 -1.0, 1.0, 0.1,
5571 0.0, 1.0, 0.1
5573 float quad4[] = {
5574 0.0, 0.0, 0.1,
5575 1.0, 0.0, 0.1,
5576 0.0, 1.0, 0.1,
5577 1.0, 1.0, 0.1
5580 HRESULT hr;
5581 DWORD color;
5582 IDirect3DVertexShader9 *vertexshader = NULL;
5583 IDirect3DPixelShader9 *ps_1_shader = NULL;
5584 IDirect3DPixelShader9 *ps_2_shader = NULL;
5585 IDirect3DPixelShader9 *ps_3_shader = NULL;
5586 IDirect3DTexture9 *texture = NULL;
5587 D3DLOCKED_RECT lr;
5588 unsigned int x, y;
5590 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5592 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5593 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5594 if(FAILED(hr)) {
5595 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5596 return;
5598 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5599 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5600 for(y = 0; y < 512; y++) {
5601 for(x = 0; x < 512; x++) {
5602 double r_f = (double) x / (double) 512;
5603 double g_f = (double) y / (double) 512;
5604 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5605 unsigned short r = (unsigned short) (r_f * 65535.0);
5606 unsigned short g = (unsigned short) (g_f * 65535.0);
5607 dst[0] = r;
5608 dst[1] = g;
5609 dst[2] = 0;
5610 dst[3] = 65535;
5613 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5614 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5616 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5617 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5618 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5620 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5621 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5622 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5623 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5624 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5625 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5626 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5628 hr = IDirect3DDevice9_BeginScene(device);
5629 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5630 if(SUCCEEDED(hr))
5632 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5635 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5637 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5640 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5642 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5643 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5645 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5647 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5649 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5650 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5651 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5652 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5653 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5654 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5656 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5658 hr = IDirect3DDevice9_EndScene(device);
5659 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5662 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5664 color = getPixelColor(device, 160, 120);
5665 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5666 (color & 0x0000ff00) == 0x0000ff00 &&
5667 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5668 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5669 color = getPixelColor(device, 160, 360);
5670 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5671 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5672 (color & 0x000000ff) == 0x00000000,
5673 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5674 color = getPixelColor(device, 480, 360);
5675 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5676 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5677 (color & 0x000000ff) == 0x00000000,
5678 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5679 color = getPixelColor(device, 480, 160);
5680 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5681 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5682 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5683 (color & 0x000000ff) == 0x00000000),
5684 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5686 /* cleanup */
5687 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5688 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5689 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5690 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5691 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5692 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5693 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5694 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5695 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5696 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5697 if(texture) IDirect3DTexture9_Release(texture);
5700 void test_compare_instructions(IDirect3DDevice9 *device)
5702 DWORD shader_sge_vec_code[] = {
5703 0xfffe0101, /* vs_1_1 */
5704 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5705 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5706 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5707 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5708 0x0000ffff /* end */
5710 DWORD shader_slt_vec_code[] = {
5711 0xfffe0101, /* vs_1_1 */
5712 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5713 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5714 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5715 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5716 0x0000ffff /* end */
5718 DWORD shader_sge_scalar_code[] = {
5719 0xfffe0101, /* vs_1_1 */
5720 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5721 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5722 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5723 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5724 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5725 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5726 0x0000ffff /* end */
5728 DWORD shader_slt_scalar_code[] = {
5729 0xfffe0101, /* vs_1_1 */
5730 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5731 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5732 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5733 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5734 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5735 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5736 0x0000ffff /* end */
5738 IDirect3DVertexShader9 *shader_sge_vec;
5739 IDirect3DVertexShader9 *shader_slt_vec;
5740 IDirect3DVertexShader9 *shader_sge_scalar;
5741 IDirect3DVertexShader9 *shader_slt_scalar;
5742 HRESULT hr, color;
5743 float quad1[] = {
5744 -1.0, -1.0, 0.1,
5745 0.0, -1.0, 0.1,
5746 -1.0, 0.0, 0.1,
5747 0.0, 0.0, 0.1
5749 float quad2[] = {
5750 0.0, -1.0, 0.1,
5751 1.0, -1.0, 0.1,
5752 0.0, 0.0, 0.1,
5753 1.0, 0.0, 0.1
5755 float quad3[] = {
5756 -1.0, 0.0, 0.1,
5757 0.0, 0.0, 0.1,
5758 -1.0, 1.0, 0.1,
5759 0.0, 1.0, 0.1
5761 float quad4[] = {
5762 0.0, 0.0, 0.1,
5763 1.0, 0.0, 0.1,
5764 0.0, 1.0, 0.1,
5765 1.0, 1.0, 0.1
5767 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5768 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5772 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5774 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5776 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5778 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5780 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5781 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5782 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5783 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5785 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5787 hr = IDirect3DDevice9_BeginScene(device);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5789 if(SUCCEEDED(hr))
5791 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5792 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5794 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5796 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5797 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5799 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5801 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5802 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5804 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5806 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5807 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5809 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5810 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5812 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5814 hr = IDirect3DDevice9_EndScene(device);
5815 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5819 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5820 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5821 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5823 color = getPixelColor(device, 160, 360);
5824 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5825 color = getPixelColor(device, 480, 360);
5826 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5827 color = getPixelColor(device, 160, 120);
5828 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5829 color = getPixelColor(device, 480, 160);
5830 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5832 IDirect3DVertexShader9_Release(shader_sge_vec);
5833 IDirect3DVertexShader9_Release(shader_slt_vec);
5834 IDirect3DVertexShader9_Release(shader_sge_scalar);
5835 IDirect3DVertexShader9_Release(shader_slt_scalar);
5838 void test_vshader_input(IDirect3DDevice9 *device)
5840 DWORD swapped_shader_code_3[] = {
5841 0xfffe0300, /* vs_3_0 */
5842 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5843 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5844 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5845 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5846 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5847 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5848 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5849 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5850 0x0000ffff /* end */
5852 DWORD swapped_shader_code_1[] = {
5853 0xfffe0101, /* vs_1_1 */
5854 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5855 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5856 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5857 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5858 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5859 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5860 0x0000ffff /* end */
5862 DWORD swapped_shader_code_2[] = {
5863 0xfffe0200, /* vs_2_0 */
5864 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5865 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5866 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5867 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5868 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5869 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5870 0x0000ffff /* end */
5872 DWORD texcoord_color_shader_code_3[] = {
5873 0xfffe0300, /* vs_3_0 */
5874 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5875 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5876 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5877 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5878 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5879 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5880 0x0000ffff /* end */
5882 DWORD texcoord_color_shader_code_2[] = {
5883 0xfffe0200, /* vs_2_0 */
5884 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5885 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5886 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5887 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5888 0x0000ffff /* end */
5890 DWORD texcoord_color_shader_code_1[] = {
5891 0xfffe0101, /* vs_1_1 */
5892 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5893 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5894 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5895 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5896 0x0000ffff /* end */
5898 DWORD color_color_shader_code_3[] = {
5899 0xfffe0300, /* vs_3_0 */
5900 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5901 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5902 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5903 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5904 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5905 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5906 0x0000ffff /* end */
5908 DWORD color_color_shader_code_2[] = {
5909 0xfffe0200, /* vs_2_0 */
5910 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5911 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5912 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5913 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5914 0x0000ffff /* end */
5916 DWORD color_color_shader_code_1[] = {
5917 0xfffe0101, /* vs_1_1 */
5918 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5919 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5920 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5921 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5922 0x0000ffff /* end */
5924 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5925 HRESULT hr;
5926 DWORD color;
5927 float quad1[] = {
5928 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5929 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5930 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5931 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5933 float quad2[] = {
5934 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5935 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5936 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5937 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5939 float quad3[] = {
5940 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5941 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5942 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5943 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5945 float quad4[] = {
5946 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5947 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5948 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5949 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5951 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5952 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5953 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5954 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5955 D3DDECL_END()
5957 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5958 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5959 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5960 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5961 D3DDECL_END()
5963 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5964 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5965 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5966 D3DDECL_END()
5968 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5969 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5970 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5971 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5972 D3DDECL_END()
5974 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5975 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5976 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5977 D3DDECL_END()
5979 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5980 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5981 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5982 D3DDECL_END()
5984 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5985 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5986 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5987 D3DDECL_END()
5989 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5990 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5991 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5992 D3DDECL_END()
5994 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5995 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5996 unsigned int i;
5997 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5998 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6000 struct vertex quad1_color[] = {
6001 {-1.0, -1.0, 0.1, 0x00ff8040},
6002 { 0.0, -1.0, 0.1, 0x00ff8040},
6003 {-1.0, 0.0, 0.1, 0x00ff8040},
6004 { 0.0, 0.0, 0.1, 0x00ff8040}
6006 struct vertex quad2_color[] = {
6007 { 0.0, -1.0, 0.1, 0x00ff8040},
6008 { 1.0, -1.0, 0.1, 0x00ff8040},
6009 { 0.0, 0.0, 0.1, 0x00ff8040},
6010 { 1.0, 0.0, 0.1, 0x00ff8040}
6012 struct vertex quad3_color[] = {
6013 {-1.0, 0.0, 0.1, 0x00ff8040},
6014 { 0.0, 0.0, 0.1, 0x00ff8040},
6015 {-1.0, 1.0, 0.1, 0x00ff8040},
6016 { 0.0, 1.0, 0.1, 0x00ff8040}
6018 float quad4_color[] = {
6019 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6020 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6021 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6022 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6025 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6026 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6027 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6028 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6029 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6031 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6034 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6036 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6038 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6039 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6040 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6041 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6043 for(i = 1; i <= 3; i++) {
6044 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6045 if(i == 3) {
6046 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6047 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6048 } else if(i == 2){
6049 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6050 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6051 } else if(i == 1) {
6052 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6053 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6056 hr = IDirect3DDevice9_BeginScene(device);
6057 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6058 if(SUCCEEDED(hr))
6060 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6063 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6064 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6066 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6068 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6069 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6071 if(i == 3 || i == 2) {
6072 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6073 } else if(i == 1) {
6074 /* Succeeds or fails, depending on SW or HW vertex processing */
6075 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6078 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6079 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6081 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6083 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6084 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6086 if(i == 3 || i == 2) {
6087 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6088 } else if(i == 1) {
6089 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6092 hr = IDirect3DDevice9_EndScene(device);
6093 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6096 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6097 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6099 if(i == 3 || i == 2) {
6100 color = getPixelColor(device, 160, 360);
6101 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6102 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6104 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6105 color = getPixelColor(device, 480, 360);
6106 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6107 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6108 color = getPixelColor(device, 160, 120);
6109 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6110 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6111 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6113 color = getPixelColor(device, 480, 160);
6114 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6115 } else if(i == 1) {
6116 color = getPixelColor(device, 160, 360);
6117 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6118 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6119 color = getPixelColor(device, 480, 360);
6120 /* Accept the clear color as well in this case, since SW VP returns an error */
6121 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6122 color = getPixelColor(device, 160, 120);
6123 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6124 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6125 color = getPixelColor(device, 480, 160);
6126 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6130 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6132 /* Now find out if the whole streams are re-read, or just the last active value for the
6133 * vertices is used.
6135 hr = IDirect3DDevice9_BeginScene(device);
6136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6137 if(SUCCEEDED(hr))
6139 float quad1_modified[] = {
6140 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6141 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6142 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6143 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6145 float quad2_modified[] = {
6146 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6147 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6148 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6149 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6152 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6153 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6155 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6158 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6160 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6161 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6163 if(i == 3 || i == 2) {
6164 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6165 } else if(i == 1) {
6166 /* Succeeds or fails, depending on SW or HW vertex processing */
6167 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6170 hr = IDirect3DDevice9_EndScene(device);
6171 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6176 color = getPixelColor(device, 480, 350);
6177 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6178 * as well.
6180 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6181 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6182 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6183 * refrast's result.
6185 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6187 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6188 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6189 color = getPixelColor(device, 160, 120);
6191 IDirect3DDevice9_SetVertexShader(device, NULL);
6192 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6194 IDirect3DVertexShader9_Release(swapped_shader);
6197 for(i = 1; i <= 3; i++) {
6198 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6199 if(i == 3) {
6200 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6201 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6202 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6203 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6204 } else if(i == 2){
6205 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6207 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6209 } else if(i == 1) {
6210 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6212 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6213 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6216 hr = IDirect3DDevice9_BeginScene(device);
6217 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6218 if(SUCCEEDED(hr))
6220 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6222 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6223 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6225 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6227 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6228 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6230 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6232 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6233 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6235 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6237 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6238 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6239 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6240 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6241 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6242 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6244 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6245 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6247 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6249 hr = IDirect3DDevice9_EndScene(device);
6250 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6252 IDirect3DDevice9_SetVertexShader(device, NULL);
6253 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6255 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6258 color = getPixelColor(device, 160, 360);
6259 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6260 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6261 color = getPixelColor(device, 480, 360);
6262 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6263 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6264 color = getPixelColor(device, 160, 120);
6265 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6266 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6267 color = getPixelColor(device, 480, 160);
6268 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6269 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6271 IDirect3DVertexShader9_Release(texcoord_color_shader);
6272 IDirect3DVertexShader9_Release(color_color_shader);
6275 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6276 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6277 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6278 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6280 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6281 IDirect3DVertexDeclaration9_Release(decl_color_color);
6282 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6283 IDirect3DVertexDeclaration9_Release(decl_color_float);
6286 static void srgbtexture_test(IDirect3DDevice9 *device)
6288 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6289 * texture stage state to render a quad using that texture. The resulting
6290 * color components should be 0x36 (~ 0.21), per this formula:
6291 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6292 * This is true where srgb_color > 0.04045.
6294 IDirect3D9 *d3d = NULL;
6295 HRESULT hr;
6296 LPDIRECT3DTEXTURE9 texture = NULL;
6297 LPDIRECT3DSURFACE9 surface = NULL;
6298 D3DLOCKED_RECT lr;
6299 DWORD color;
6300 float quad[] = {
6301 -1.0, 1.0, 0.0, 0.0, 0.0,
6302 1.0, 1.0, 0.0, 1.0, 0.0,
6303 -1.0, -1.0, 0.0, 0.0, 1.0,
6304 1.0, -1.0, 0.0, 1.0, 1.0,
6308 memset(&lr, 0, sizeof(lr));
6309 IDirect3DDevice9_GetDirect3D(device, &d3d);
6310 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6311 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6312 D3DFMT_A8R8G8B8) != D3D_OK) {
6313 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6314 goto out;
6317 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6318 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6319 &texture, NULL);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6321 if(!texture) {
6322 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6323 goto out;
6325 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6326 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6328 fill_surface(surface, 0xff7f7f7f);
6329 IDirect3DSurface9_Release(surface);
6331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6332 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6333 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6334 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6336 hr = IDirect3DDevice9_BeginScene(device);
6337 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6338 if(SUCCEEDED(hr))
6340 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6341 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6343 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6348 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6350 hr = IDirect3DDevice9_EndScene(device);
6351 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6354 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6355 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6356 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6360 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6362 color = getPixelColor(device, 320, 240);
6363 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6365 out:
6366 if(texture) IDirect3DTexture9_Release(texture);
6367 IDirect3D9_Release(d3d);
6370 static void shademode_test(IDirect3DDevice9 *device)
6372 /* Render a quad and try all of the different fixed function shading models. */
6373 HRESULT hr;
6374 DWORD color0, color1;
6375 DWORD color0_gouraud = 0, color1_gouraud = 0;
6376 DWORD shademode = D3DSHADE_FLAT;
6377 DWORD primtype = D3DPT_TRIANGLESTRIP;
6378 LPVOID data = NULL;
6379 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6380 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6381 UINT i, j;
6382 struct vertex quad_strip[] =
6384 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6385 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6386 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6387 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6389 struct vertex quad_list[] =
6391 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6392 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6393 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6395 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6396 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6397 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6400 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6401 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6402 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6403 if (FAILED(hr)) goto bail;
6405 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6406 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6407 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6408 if (FAILED(hr)) goto bail;
6410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6413 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6414 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6416 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6417 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6418 memcpy(data, quad_strip, sizeof(quad_strip));
6419 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6420 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6422 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6423 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6424 memcpy(data, quad_list, sizeof(quad_list));
6425 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6426 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6428 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6429 * the color fixups we have to do for FLAT shading will be dependent on that. */
6430 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6431 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6433 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6434 for (j=0; j<2; j++) {
6436 /* Inner loop just changes the D3DRS_SHADEMODE */
6437 for (i=0; i<3; i++) {
6438 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6439 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6444 hr = IDirect3DDevice9_BeginScene(device);
6445 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6446 if(SUCCEEDED(hr))
6448 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6449 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6451 hr = IDirect3DDevice9_EndScene(device);
6452 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6455 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6456 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6458 /* Sample two spots from the output */
6459 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6460 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6461 switch(shademode) {
6462 case D3DSHADE_FLAT:
6463 /* Should take the color of the first vertex of each triangle */
6464 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6465 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6466 shademode = D3DSHADE_GOURAUD;
6467 break;
6468 case D3DSHADE_GOURAUD:
6469 /* Should be an interpolated blend */
6471 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6472 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6473 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6474 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6476 color0_gouraud = color0;
6477 color1_gouraud = color1;
6479 shademode = D3DSHADE_PHONG;
6480 break;
6481 case D3DSHADE_PHONG:
6482 /* Should be the same as GOURAUD, since no hardware implements this */
6483 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6484 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6485 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6486 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6488 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6489 color0_gouraud, color0);
6490 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6491 color1_gouraud, color1);
6492 break;
6495 /* Now, do it all over again with a TRIANGLELIST */
6496 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6497 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6498 primtype = D3DPT_TRIANGLELIST;
6499 shademode = D3DSHADE_FLAT;
6502 bail:
6503 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6504 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6505 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6506 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6508 if (vb_strip)
6509 IDirect3DVertexBuffer9_Release(vb_strip);
6510 if (vb_list)
6511 IDirect3DVertexBuffer9_Release(vb_list);
6515 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6517 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6518 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6519 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6520 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6521 * 0.73
6523 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6524 * so use shaders for this task
6526 IDirect3DPixelShader9 *pshader;
6527 IDirect3DVertexShader9 *vshader;
6528 IDirect3D9 *d3d;
6529 DWORD vshader_code[] = {
6530 0xfffe0101, /* vs_1_1 */
6531 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6532 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6533 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6534 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6535 0x0000ffff /* end */
6537 DWORD pshader_code[] = {
6538 0xffff0101, /* ps_1_1 */
6539 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6540 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6541 0x0000ffff /* end */
6543 const float quad[] = {
6544 -1.0, -1.0, 0.1,
6545 1.0, -1.0, 0.1,
6546 -1.0, 1.0, 0.1,
6547 1.0, 1.0, 0.1
6549 HRESULT hr;
6550 DWORD color;
6552 IDirect3DDevice9_GetDirect3D(device, &d3d);
6553 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6554 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6555 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6556 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6557 * works
6559 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6560 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6561 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6562 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6563 IDirect3D9_Release(d3d);
6564 return;
6566 IDirect3D9_Release(d3d);
6568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6572 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6574 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6578 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6580 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6582 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6584 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6585 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6586 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6588 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6589 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6590 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6591 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6593 hr = IDirect3DDevice9_BeginScene(device);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6595 if(SUCCEEDED(hr)) {
6596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6597 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6599 hr = IDirect3DDevice9_EndScene(device);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6603 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6604 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6605 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6606 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6607 IDirect3DPixelShader9_Release(pshader);
6608 IDirect3DVertexShader9_Release(vshader);
6610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6611 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6613 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6615 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6616 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6617 color = getPixelColor(device, 160, 360);
6618 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6619 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6622 static void alpha_test(IDirect3DDevice9 *device)
6624 HRESULT hr;
6625 IDirect3DTexture9 *offscreenTexture;
6626 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6627 DWORD color;
6629 struct vertex quad1[] =
6631 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6632 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6633 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6634 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6636 struct vertex quad2[] =
6638 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6639 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6640 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6641 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6643 static const float composite_quad[][5] = {
6644 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6645 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6646 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6647 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6650 /* Clear the render target with alpha = 0.5 */
6651 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6652 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6654 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6655 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6657 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6658 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6659 if(!backbuffer) {
6660 goto out;
6663 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6664 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6665 if(!offscreen) {
6666 goto out;
6669 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6670 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6672 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6673 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6674 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6675 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6676 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6677 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6678 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6679 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6683 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6684 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6685 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6687 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6689 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6693 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6696 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6698 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6699 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6700 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6702 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6703 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6704 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6705 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6706 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6707 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6708 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6711 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6713 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6715 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6718 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6720 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6722 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6724 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6725 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6727 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6728 * Disable alpha blending for the final composition
6730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6731 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6732 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6733 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6735 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6738 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6739 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6742 hr = IDirect3DDevice9_EndScene(device);
6743 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6746 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6748 color = getPixelColor(device, 160, 360);
6749 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6750 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6752 color = getPixelColor(device, 160, 120);
6753 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6754 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6756 color = getPixelColor(device, 480, 360);
6757 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6758 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6760 color = getPixelColor(device, 480, 120);
6761 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6762 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6764 out:
6765 /* restore things */
6766 if(backbuffer) {
6767 IDirect3DSurface9_Release(backbuffer);
6769 if(offscreenTexture) {
6770 IDirect3DTexture9_Release(offscreenTexture);
6772 if(offscreen) {
6773 IDirect3DSurface9_Release(offscreen);
6777 struct vertex_shortcolor {
6778 float x, y, z;
6779 unsigned short r, g, b, a;
6781 struct vertex_floatcolor {
6782 float x, y, z;
6783 float r, g, b, a;
6786 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6788 HRESULT hr;
6789 BOOL s_ok, ub_ok, f_ok;
6790 DWORD color, size, i;
6791 void *data;
6792 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6793 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6794 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6795 D3DDECL_END()
6797 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6798 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6799 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6800 D3DDECL_END()
6802 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6803 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6804 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6805 D3DDECL_END()
6807 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6808 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6809 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6810 D3DDECL_END()
6812 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6813 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6814 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6815 D3DDECL_END()
6817 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6818 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6819 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6820 D3DDECL_END()
6822 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6823 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6824 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6825 D3DDECL_END()
6827 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6828 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6829 IDirect3DVertexBuffer9 *vb, *vb2;
6830 struct vertex quad1[] = /* D3DCOLOR */
6832 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6833 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6834 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6835 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6837 struct vertex quad2[] = /* UBYTE4N */
6839 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6840 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6841 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6842 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6844 struct vertex_shortcolor quad3[] = /* short */
6846 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6847 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6848 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6849 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6851 struct vertex_floatcolor quad4[] =
6853 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6854 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6855 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6856 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6858 DWORD colors[] = {
6859 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6860 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6861 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
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,
6876 float quads[] = {
6877 -1.0, -1.0, 0.1,
6878 -1.0, 0.0, 0.1,
6879 0.0, -1.0, 0.1,
6880 0.0, 0.0, 0.1,
6882 0.0, -1.0, 0.1,
6883 0.0, 0.0, 0.1,
6884 1.0, -1.0, 0.1,
6885 1.0, 0.0, 0.1,
6887 0.0, 0.0, 0.1,
6888 0.0, 1.0, 0.1,
6889 1.0, 0.0, 0.1,
6890 1.0, 1.0, 0.1,
6892 -1.0, 0.0, 0.1,
6893 -1.0, 1.0, 0.1,
6894 0.0, 0.0, 0.1,
6895 0.0, 1.0, 0.1
6897 struct tvertex quad_transformed[] = {
6898 { 90, 110, 0.1, 2.0, 0x00ffff00},
6899 { 570, 110, 0.1, 2.0, 0x00ffff00},
6900 { 90, 300, 0.1, 2.0, 0x00ffff00},
6901 { 570, 300, 0.1, 2.0, 0x00ffff00}
6903 D3DCAPS9 caps;
6905 memset(&caps, 0, sizeof(caps));
6906 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6907 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6909 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6910 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6912 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6913 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6914 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6915 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6916 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6917 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6918 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6919 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6920 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6921 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6922 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6923 } else {
6924 trace("D3DDTCAPS_UBYTE4N not supported\n");
6925 dcl_ubyte_2 = NULL;
6926 dcl_ubyte = NULL;
6928 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6929 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6930 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6931 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6933 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6934 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6935 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6936 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6938 hr = IDirect3DDevice9_BeginScene(device);
6939 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6940 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6941 if(SUCCEEDED(hr)) {
6942 if(dcl_color) {
6943 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6944 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6946 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6949 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6950 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6951 * using software vertex processing. Doh!
6953 if(dcl_ubyte) {
6954 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6955 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6957 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6958 ub_ok = SUCCEEDED(hr);
6961 if(dcl_short) {
6962 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6963 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6965 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6966 s_ok = SUCCEEDED(hr);
6969 if(dcl_float) {
6970 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6971 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6973 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6974 f_ok = SUCCEEDED(hr);
6977 hr = IDirect3DDevice9_EndScene(device);
6978 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6981 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6982 if(dcl_short) {
6983 color = getPixelColor(device, 480, 360);
6984 ok(color == 0x000000ff || !s_ok,
6985 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6987 if(dcl_ubyte) {
6988 color = getPixelColor(device, 160, 120);
6989 ok(color == 0x0000ffff || !ub_ok,
6990 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6992 if(dcl_color) {
6993 color = getPixelColor(device, 160, 360);
6994 ok(color == 0x00ffff00,
6995 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6997 if(dcl_float) {
6998 color = getPixelColor(device, 480, 120);
6999 ok(color == 0x00ff0000 || !f_ok,
7000 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7003 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7004 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7005 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7006 * whether the immediate mode code works
7008 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7009 hr = IDirect3DDevice9_BeginScene(device);
7010 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7011 if(SUCCEEDED(hr)) {
7012 if(dcl_color) {
7013 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7014 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7015 memcpy(data, quad1, sizeof(quad1));
7016 hr = IDirect3DVertexBuffer9_Unlock(vb);
7017 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7018 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7019 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7020 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7021 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7022 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7023 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7026 if(dcl_ubyte) {
7027 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7028 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7029 memcpy(data, quad2, sizeof(quad2));
7030 hr = IDirect3DVertexBuffer9_Unlock(vb);
7031 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7032 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7033 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7034 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7035 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7036 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7037 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7038 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7039 ub_ok = SUCCEEDED(hr);
7042 if(dcl_short) {
7043 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7044 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7045 memcpy(data, quad3, sizeof(quad3));
7046 hr = IDirect3DVertexBuffer9_Unlock(vb);
7047 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7048 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7051 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7052 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7053 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7054 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7055 s_ok = SUCCEEDED(hr);
7058 if(dcl_float) {
7059 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7060 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7061 memcpy(data, quad4, sizeof(quad4));
7062 hr = IDirect3DVertexBuffer9_Unlock(vb);
7063 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7064 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7065 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7066 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7067 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7068 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7069 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7070 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7071 f_ok = SUCCEEDED(hr);
7074 hr = IDirect3DDevice9_EndScene(device);
7075 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7078 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7079 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7080 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7081 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7084 if(dcl_short) {
7085 color = getPixelColor(device, 480, 360);
7086 ok(color == 0x000000ff || !s_ok,
7087 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7089 if(dcl_ubyte) {
7090 color = getPixelColor(device, 160, 120);
7091 ok(color == 0x0000ffff || !ub_ok,
7092 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7094 if(dcl_color) {
7095 color = getPixelColor(device, 160, 360);
7096 ok(color == 0x00ffff00,
7097 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7099 if(dcl_float) {
7100 color = getPixelColor(device, 480, 120);
7101 ok(color == 0x00ff0000 || !f_ok,
7102 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7105 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7108 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7109 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7110 memcpy(data, quad_transformed, sizeof(quad_transformed));
7111 hr = IDirect3DVertexBuffer9_Unlock(vb);
7112 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7114 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7115 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7117 hr = IDirect3DDevice9_BeginScene(device);
7118 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7119 if(SUCCEEDED(hr)) {
7120 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7121 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7122 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7123 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7125 hr = IDirect3DDevice9_EndScene(device);
7126 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7129 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7130 color = getPixelColor(device, 88, 108);
7131 ok(color == 0x000000ff,
7132 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7133 color = getPixelColor(device, 92, 108);
7134 ok(color == 0x000000ff,
7135 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7136 color = getPixelColor(device, 88, 112);
7137 ok(color == 0x000000ff,
7138 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7139 color = getPixelColor(device, 92, 112);
7140 ok(color == 0x00ffff00,
7141 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7143 color = getPixelColor(device, 568, 108);
7144 ok(color == 0x000000ff,
7145 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7146 color = getPixelColor(device, 572, 108);
7147 ok(color == 0x000000ff,
7148 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7149 color = getPixelColor(device, 568, 112);
7150 ok(color == 0x00ffff00,
7151 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7152 color = getPixelColor(device, 572, 112);
7153 ok(color == 0x000000ff,
7154 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7156 color = getPixelColor(device, 88, 298);
7157 ok(color == 0x000000ff,
7158 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7159 color = getPixelColor(device, 92, 298);
7160 ok(color == 0x00ffff00,
7161 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7162 color = getPixelColor(device, 88, 302);
7163 ok(color == 0x000000ff,
7164 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7165 color = getPixelColor(device, 92, 302);
7166 ok(color == 0x000000ff,
7167 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7169 color = getPixelColor(device, 568, 298);
7170 ok(color == 0x00ffff00,
7171 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7172 color = getPixelColor(device, 572, 298);
7173 ok(color == 0x000000ff,
7174 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7175 color = getPixelColor(device, 568, 302);
7176 ok(color == 0x000000ff,
7177 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7178 color = getPixelColor(device, 572, 302);
7179 ok(color == 0x000000ff,
7180 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7182 /* This test is pointless without those two declarations: */
7183 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7184 skip("color-ubyte switching test declarations aren't supported\n");
7185 goto out;
7188 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7189 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7190 memcpy(data, quads, sizeof(quads));
7191 hr = IDirect3DVertexBuffer9_Unlock(vb);
7192 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7193 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7194 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7195 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7196 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7197 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7198 memcpy(data, colors, sizeof(colors));
7199 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7200 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7202 for(i = 0; i < 2; i++) {
7203 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7204 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7206 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7207 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7208 if(i == 0) {
7209 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7210 } else {
7211 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7213 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7215 hr = IDirect3DDevice9_BeginScene(device);
7216 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7217 ub_ok = FALSE;
7218 if(SUCCEEDED(hr)) {
7219 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7220 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7221 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7222 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7223 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7224 ub_ok = SUCCEEDED(hr);
7226 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7227 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7228 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7229 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7231 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7232 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7233 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7234 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7235 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7236 ub_ok = (SUCCEEDED(hr) && ub_ok);
7238 hr = IDirect3DDevice9_EndScene(device);
7239 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7242 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7243 if(i == 0) {
7244 color = getPixelColor(device, 480, 360);
7245 ok(color == 0x00ff0000,
7246 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7247 color = getPixelColor(device, 160, 120);
7248 ok(color == 0x00ffffff,
7249 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7250 color = getPixelColor(device, 160, 360);
7251 ok(color == 0x000000ff || !ub_ok,
7252 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7253 color = getPixelColor(device, 480, 120);
7254 ok(color == 0x000000ff || !ub_ok,
7255 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7256 } else {
7257 color = getPixelColor(device, 480, 360);
7258 ok(color == 0x000000ff,
7259 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7260 color = getPixelColor(device, 160, 120);
7261 ok(color == 0x00ffffff,
7262 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7263 color = getPixelColor(device, 160, 360);
7264 ok(color == 0x00ff0000 || !ub_ok,
7265 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7266 color = getPixelColor(device, 480, 120);
7267 ok(color == 0x00ff0000 || !ub_ok,
7268 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7272 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7273 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7274 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7275 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7276 IDirect3DVertexBuffer9_Release(vb2);
7278 out:
7279 IDirect3DVertexBuffer9_Release(vb);
7280 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7281 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7282 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7283 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7284 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7285 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7286 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7289 struct vertex_float16color {
7290 float x, y, z;
7291 DWORD c1, c2;
7294 static void test_vshader_float16(IDirect3DDevice9 *device)
7296 HRESULT hr;
7297 DWORD color;
7298 void *data;
7299 static const D3DVERTEXELEMENT9 decl_elements[] = {
7300 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7301 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7302 D3DDECL_END()
7304 IDirect3DVertexDeclaration9 *vdecl = NULL;
7305 IDirect3DVertexBuffer9 *buffer = NULL;
7306 IDirect3DVertexShader9 *shader;
7307 DWORD shader_code[] = {
7308 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7309 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7310 0x90e40001, 0x0000ffff
7312 struct vertex_float16color quad[] = {
7313 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7314 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7315 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7316 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7318 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7319 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7320 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7321 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7323 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7324 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7325 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7326 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7328 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7329 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7330 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7331 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7334 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7335 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7337 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7338 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7339 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7340 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7341 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7342 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7344 hr = IDirect3DDevice9_BeginScene(device);
7345 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7346 if(SUCCEEDED(hr)) {
7347 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7348 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7349 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7350 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7352 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7354 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7356 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7358 hr = IDirect3DDevice9_EndScene(device);
7359 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7361 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7362 color = getPixelColor(device, 480, 360);
7363 ok(color == 0x00ff0000,
7364 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7365 color = getPixelColor(device, 160, 120);
7366 ok(color == 0x00000000,
7367 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7368 color = getPixelColor(device, 160, 360);
7369 ok(color == 0x0000ff00,
7370 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7371 color = getPixelColor(device, 480, 120);
7372 ok(color == 0x000000ff,
7373 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7376 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7378 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7379 D3DPOOL_MANAGED, &buffer, NULL);
7380 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7381 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7382 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7383 memcpy(data, quad, sizeof(quad));
7384 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7385 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7386 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7387 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7389 hr = IDirect3DDevice9_BeginScene(device);
7390 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7391 if(SUCCEEDED(hr)) {
7392 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7394 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7395 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7396 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7398 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7401 hr = IDirect3DDevice9_EndScene(device);
7402 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7405 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7406 color = getPixelColor(device, 480, 360);
7407 ok(color == 0x00ff0000,
7408 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7409 color = getPixelColor(device, 160, 120);
7410 ok(color == 0x00000000,
7411 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7412 color = getPixelColor(device, 160, 360);
7413 ok(color == 0x0000ff00,
7414 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7415 color = getPixelColor(device, 480, 120);
7416 ok(color == 0x000000ff,
7417 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7419 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7420 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7421 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7422 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7423 IDirect3DDevice9_SetVertexShader(device, NULL);
7424 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7426 IDirect3DVertexDeclaration9_Release(vdecl);
7427 IDirect3DVertexShader9_Release(shader);
7428 IDirect3DVertexBuffer9_Release(buffer);
7431 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7433 D3DCAPS9 caps;
7434 IDirect3DTexture9 *texture;
7435 HRESULT hr;
7436 D3DLOCKED_RECT rect;
7437 unsigned int x, y;
7438 DWORD *dst, color;
7439 const float quad[] = {
7440 -1.0, -1.0, 0.1, -0.2, -0.2,
7441 1.0, -1.0, 0.1, 1.2, -0.2,
7442 -1.0, 1.0, 0.1, -0.2, 1.2,
7443 1.0, 1.0, 0.1, 1.2, 1.2
7445 memset(&caps, 0, sizeof(caps));
7447 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7448 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7449 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7450 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7451 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7452 "Card has conditional NP2 support without power of two restriction set\n");
7453 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7454 return;
7455 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7456 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7457 return;
7460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7461 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7463 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7466 memset(&rect, 0, sizeof(rect));
7467 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7468 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7469 for(y = 0; y < 10; y++) {
7470 for(x = 0; x < 10; x++) {
7471 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7472 if(x == 0 || x == 9 || y == 0 || y == 9) {
7473 *dst = 0x00ff0000;
7474 } else {
7475 *dst = 0x000000ff;
7479 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7480 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7482 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7483 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7484 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7485 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7486 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7487 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7488 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7491 hr = IDirect3DDevice9_BeginScene(device);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7493 if(SUCCEEDED(hr)) {
7494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7497 hr = IDirect3DDevice9_EndScene(device);
7498 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7501 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7503 color = getPixelColor(device, 1, 1);
7504 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7505 color = getPixelColor(device, 639, 479);
7506 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7508 color = getPixelColor(device, 135, 101);
7509 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7510 color = getPixelColor(device, 140, 101);
7511 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7512 color = getPixelColor(device, 135, 105);
7513 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7514 color = getPixelColor(device, 140, 105);
7515 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7517 color = getPixelColor(device, 135, 376);
7518 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7519 color = getPixelColor(device, 140, 376);
7520 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7521 color = getPixelColor(device, 135, 379);
7522 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7523 color = getPixelColor(device, 140, 379);
7524 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7526 color = getPixelColor(device, 500, 101);
7527 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7528 color = getPixelColor(device, 504, 101);
7529 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7530 color = getPixelColor(device, 500, 105);
7531 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7532 color = getPixelColor(device, 504, 105);
7533 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7535 color = getPixelColor(device, 500, 376);
7536 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7537 color = getPixelColor(device, 504, 376);
7538 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7539 color = getPixelColor(device, 500, 380);
7540 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7541 color = getPixelColor(device, 504, 380);
7542 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7544 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7545 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7546 IDirect3DTexture9_Release(texture);
7549 static void vFace_register_test(IDirect3DDevice9 *device)
7551 HRESULT hr;
7552 DWORD color;
7553 const DWORD shader_code[] = {
7554 0xffff0300, /* ps_3_0 */
7555 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7556 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7557 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7558 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7559 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7560 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7561 0x0000ffff /* END */
7563 IDirect3DPixelShader9 *shader;
7564 IDirect3DTexture9 *texture;
7565 IDirect3DSurface9 *surface, *backbuffer;
7566 const float quad[] = {
7567 -1.0, -1.0, 0.1,
7568 1.0, -1.0, 0.1,
7569 -1.0, 0.0, 0.1,
7571 1.0, -1.0, 0.1,
7572 1.0, 0.0, 0.1,
7573 -1.0, 0.0, 0.1,
7575 -1.0, 0.0, 0.1,
7576 -1.0, 1.0, 0.1,
7577 1.0, 0.0, 0.1,
7579 1.0, 0.0, 0.1,
7580 -1.0, 1.0, 0.1,
7581 1.0, 1.0, 0.1,
7583 const float blit[] = {
7584 0.0, -1.0, 0.1, 0.0, 0.0,
7585 1.0, -1.0, 0.1, 1.0, 0.0,
7586 0.0, 1.0, 0.1, 0.0, 1.0,
7587 1.0, 1.0, 0.1, 1.0, 1.0,
7590 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7591 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7592 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7593 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7594 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7595 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7596 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7597 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7598 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7599 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7600 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7601 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7603 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7604 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7606 hr = IDirect3DDevice9_BeginScene(device);
7607 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7608 if(SUCCEEDED(hr)) {
7609 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7610 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7611 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7612 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7613 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7614 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7615 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7616 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7617 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7619 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7621 /* Blit the texture onto the back buffer to make it visible */
7622 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7623 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7624 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7625 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7626 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7627 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7628 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7629 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7630 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7631 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7636 hr = IDirect3DDevice9_EndScene(device);
7637 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7640 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7641 color = getPixelColor(device, 160, 360);
7642 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7643 color = getPixelColor(device, 160, 120);
7644 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7645 color = getPixelColor(device, 480, 360);
7646 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7647 color = getPixelColor(device, 480, 120);
7648 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7650 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7651 IDirect3DDevice9_SetTexture(device, 0, NULL);
7652 IDirect3DPixelShader9_Release(shader);
7653 IDirect3DSurface9_Release(surface);
7654 IDirect3DSurface9_Release(backbuffer);
7655 IDirect3DTexture9_Release(texture);
7658 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7660 HRESULT hr;
7661 DWORD color;
7662 int i;
7663 D3DCAPS9 caps;
7664 BOOL L6V5U5_supported = FALSE;
7665 IDirect3DTexture9 *tex1, *tex2;
7666 D3DLOCKED_RECT locked_rect;
7668 static const float quad[][7] = {
7669 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7670 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7671 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7672 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7675 static const D3DVERTEXELEMENT9 decl_elements[] = {
7676 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7677 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7678 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7679 D3DDECL_END()
7682 /* use asymmetric matrix to test loading */
7683 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7684 float scale, offset;
7686 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7687 IDirect3DTexture9 *texture = NULL;
7689 memset(&caps, 0, sizeof(caps));
7690 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7691 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7692 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7693 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7694 return;
7695 } else {
7696 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7697 * They report that it is not supported, but after that bump mapping works properly. So just test
7698 * if the format is generally supported, and check the BUMPENVMAP flag
7700 IDirect3D9 *d3d9;
7702 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7703 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7704 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7705 L6V5U5_supported = SUCCEEDED(hr);
7706 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7707 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7708 IDirect3D9_Release(d3d9);
7709 if(FAILED(hr)) {
7710 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7711 return;
7715 /* Generate the textures */
7716 generate_bumpmap_textures(device);
7718 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7719 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7720 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7721 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7722 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7723 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7724 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7725 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7727 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7728 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7729 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7730 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7731 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7732 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7734 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7735 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7736 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7737 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7738 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7739 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7741 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7742 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7744 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7745 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7748 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7751 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7752 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7753 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7754 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7756 hr = IDirect3DDevice9_BeginScene(device);
7757 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7760 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7762 hr = IDirect3DDevice9_EndScene(device);
7763 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7765 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7766 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7768 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7769 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7770 * But since testing the color match is not the purpose of the test don't be too picky
7772 color = getPixelColor(device, 320-32, 240);
7773 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7774 color = getPixelColor(device, 320+32, 240);
7775 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7776 color = getPixelColor(device, 320, 240-32);
7777 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7778 color = getPixelColor(device, 320, 240+32);
7779 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7780 color = getPixelColor(device, 320, 240);
7781 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7782 color = getPixelColor(device, 320+32, 240+32);
7783 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7784 color = getPixelColor(device, 320-32, 240+32);
7785 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7786 color = getPixelColor(device, 320+32, 240-32);
7787 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7788 color = getPixelColor(device, 320-32, 240-32);
7789 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7791 for(i = 0; i < 2; i++) {
7792 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7793 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7794 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7795 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7796 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7797 IDirect3DTexture9_Release(texture); /* To destroy it */
7800 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7801 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7802 goto cleanup;
7804 if(L6V5U5_supported == FALSE) {
7805 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7806 goto cleanup;
7809 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7810 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7811 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7812 * would only make this test more complicated
7814 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7815 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7816 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7817 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7819 memset(&locked_rect, 0, sizeof(locked_rect));
7820 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7821 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7822 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7823 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7824 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7826 memset(&locked_rect, 0, sizeof(locked_rect));
7827 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7828 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7829 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7830 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7831 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7833 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7834 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7835 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7836 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7838 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7839 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7840 scale = 2.0;
7841 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7842 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7843 offset = 0.1;
7844 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7845 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7847 hr = IDirect3DDevice9_BeginScene(device);
7848 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7849 if(SUCCEEDED(hr)) {
7850 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7851 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7852 hr = IDirect3DDevice9_EndScene(device);
7853 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7857 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7858 color = getPixelColor(device, 320, 240);
7859 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7860 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7861 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7863 ok(color_match(color, 0x00994c72, 3), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7865 /* Check a result scale factor > 1.0 */
7866 scale = 10;
7867 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7868 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7869 offset = 10;
7870 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7871 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7873 hr = IDirect3DDevice9_BeginScene(device);
7874 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7875 if(SUCCEEDED(hr)) {
7876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7877 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7878 hr = IDirect3DDevice9_EndScene(device);
7879 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7882 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7883 color = getPixelColor(device, 320, 240);
7884 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7886 /* Check clamping in the scale factor calculation */
7887 scale = 1000;
7888 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7889 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7890 offset = -1;
7891 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7892 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7894 hr = IDirect3DDevice9_BeginScene(device);
7895 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7896 if(SUCCEEDED(hr)) {
7897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7898 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7899 hr = IDirect3DDevice9_EndScene(device);
7900 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7902 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7903 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7904 color = getPixelColor(device, 320, 240);
7905 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7907 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7908 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7909 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7910 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7912 IDirect3DTexture9_Release(tex1);
7913 IDirect3DTexture9_Release(tex2);
7915 cleanup:
7916 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7917 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7919 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7922 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7923 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7926 static void stencil_cull_test(IDirect3DDevice9 *device) {
7927 HRESULT hr;
7928 IDirect3DSurface9 *depthstencil = NULL;
7929 D3DSURFACE_DESC desc;
7930 float quad1[] = {
7931 -1.0, -1.0, 0.1,
7932 0.0, -1.0, 0.1,
7933 -1.0, 0.0, 0.1,
7934 0.0, 0.0, 0.1,
7936 float quad2[] = {
7937 0.0, -1.0, 0.1,
7938 1.0, -1.0, 0.1,
7939 0.0, 0.0, 0.1,
7940 1.0, 0.0, 0.1,
7942 float quad3[] = {
7943 0.0, 0.0, 0.1,
7944 1.0, 0.0, 0.1,
7945 0.0, 1.0, 0.1,
7946 1.0, 1.0, 0.1,
7948 float quad4[] = {
7949 -1.0, 0.0, 0.1,
7950 0.0, 0.0, 0.1,
7951 -1.0, 1.0, 0.1,
7952 0.0, 1.0, 0.1,
7954 struct vertex painter[] = {
7955 {-1.0, -1.0, 0.0, 0x00000000},
7956 { 1.0, -1.0, 0.0, 0x00000000},
7957 {-1.0, 1.0, 0.0, 0x00000000},
7958 { 1.0, 1.0, 0.0, 0x00000000},
7960 WORD indices_cw[] = {0, 1, 3};
7961 WORD indices_ccw[] = {0, 2, 3};
7962 unsigned int i;
7963 DWORD color;
7965 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7966 if(depthstencil == NULL) {
7967 skip("No depth stencil buffer\n");
7968 return;
7970 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7971 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
7972 IDirect3DSurface9_Release(depthstencil);
7973 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7974 skip("No 4 or 8 bit stencil surface\n");
7975 return;
7978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7979 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7980 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7983 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7985 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7989 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7992 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7994 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7999 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8000 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8001 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8003 /* First pass: Fill the stencil buffer with some values... */
8004 hr = IDirect3DDevice9_BeginScene(device);
8005 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8006 if(SUCCEEDED(hr))
8008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8009 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8010 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8011 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8012 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8013 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8016 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8018 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8019 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8020 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8021 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8022 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8025 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8026 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8027 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8028 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8029 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8033 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8034 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8035 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8036 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8038 hr = IDirect3DDevice9_EndScene(device);
8039 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8042 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8044 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8046 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8048 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8050 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8052 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8054 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8056 /* 2nd pass: Make the stencil values visible */
8057 hr = IDirect3DDevice9_BeginScene(device);
8058 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8059 if(SUCCEEDED(hr))
8061 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8062 for(i = 0; i < 16; i++) {
8063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8064 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8066 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8067 painter[1].diffuse = (i * 16);
8068 painter[2].diffuse = (i * 16);
8069 painter[3].diffuse = (i * 16);
8070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8071 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8073 hr = IDirect3DDevice9_EndScene(device);
8074 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8077 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8081 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083 color = getPixelColor(device, 160, 420);
8084 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8085 color = getPixelColor(device, 160, 300);
8086 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8088 color = getPixelColor(device, 480, 420);
8089 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8090 color = getPixelColor(device, 480, 300);
8091 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8093 color = getPixelColor(device, 160, 180);
8094 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8095 color = getPixelColor(device, 160, 60);
8096 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8098 color = getPixelColor(device, 480, 180);
8099 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8100 color = getPixelColor(device, 480, 60);
8101 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8104 static void vpos_register_test(IDirect3DDevice9 *device)
8106 HRESULT hr;
8107 DWORD color;
8108 const DWORD shader_code[] = {
8109 0xffff0300, /* ps_3_0 */
8110 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8111 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8112 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8113 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8114 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8115 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8116 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8117 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8118 0x0000ffff /* end */
8120 const DWORD shader_frac_code[] = {
8121 0xffff0300, /* ps_3_0 */
8122 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8123 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8124 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8125 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8126 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8127 0x0000ffff /* end */
8129 IDirect3DPixelShader9 *shader, *shader_frac;
8130 IDirect3DSurface9 *surface = NULL, *backbuffer;
8131 const float quad[] = {
8132 -1.0, -1.0, 0.1, 0.0, 0.0,
8133 1.0, -1.0, 0.1, 1.0, 0.0,
8134 -1.0, 1.0, 0.1, 0.0, 1.0,
8135 1.0, 1.0, 0.1, 1.0, 1.0,
8137 D3DLOCKED_RECT lr;
8138 float constant[4] = {1.0, 0.0, 320, 240};
8139 DWORD *pos;
8141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8142 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8143 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8144 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8145 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8146 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8147 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8148 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8149 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8150 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8151 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8152 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8154 hr = IDirect3DDevice9_BeginScene(device);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8156 if(SUCCEEDED(hr)) {
8157 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8158 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8160 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8161 hr = IDirect3DDevice9_EndScene(device);
8162 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8165 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8166 /* This has to be pixel exact */
8167 color = getPixelColor(device, 319, 239);
8168 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8169 color = getPixelColor(device, 320, 239);
8170 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8171 color = getPixelColor(device, 319, 240);
8172 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8173 color = getPixelColor(device, 320, 240);
8174 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8176 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8177 &surface, NULL);
8178 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8179 hr = IDirect3DDevice9_BeginScene(device);
8180 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8181 if(SUCCEEDED(hr)) {
8182 constant[2] = 16; constant[3] = 16;
8183 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8184 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8185 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8186 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8188 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8189 hr = IDirect3DDevice9_EndScene(device);
8190 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8192 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8193 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8195 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8196 color = *pos & 0x00ffffff;
8197 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8198 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8199 color = *pos & 0x00ffffff;
8200 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8201 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8202 color = *pos & 0x00ffffff;
8203 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8204 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8205 color = *pos & 0x00ffffff;
8206 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8208 hr = IDirect3DSurface9_UnlockRect(surface);
8209 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8211 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8212 * have full control over the multisampling setting inside this test
8214 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8215 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8216 hr = IDirect3DDevice9_BeginScene(device);
8217 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8218 if(SUCCEEDED(hr)) {
8219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8221 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8222 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8223 hr = IDirect3DDevice9_EndScene(device);
8224 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8226 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8229 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8230 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8232 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8233 color = *pos & 0x00ffffff;
8234 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8236 hr = IDirect3DSurface9_UnlockRect(surface);
8237 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8239 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8240 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8241 IDirect3DPixelShader9_Release(shader);
8242 IDirect3DPixelShader9_Release(shader_frac);
8243 if(surface) IDirect3DSurface9_Release(surface);
8244 IDirect3DSurface9_Release(backbuffer);
8247 static void pointsize_test(IDirect3DDevice9 *device)
8249 HRESULT hr;
8250 D3DCAPS9 caps;
8251 D3DMATRIX matrix;
8252 D3DMATRIX identity;
8253 float ptsize, ptsize_orig;
8254 DWORD color;
8256 const float vertices[] = {
8257 64, 64, 0.1,
8258 128, 64, 0.1,
8259 192, 64, 0.1,
8260 256, 64, 0.1,
8261 320, 64, 0.1,
8262 384, 64, 0.1
8265 /* 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 */
8266 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;
8267 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;
8268 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;
8269 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;
8271 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;
8272 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;
8273 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;
8274 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;
8276 memset(&caps, 0, sizeof(caps));
8277 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8278 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8279 if(caps.MaxPointSize < 32.0) {
8280 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8281 return;
8284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8285 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8286 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8287 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8288 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8289 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8290 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8291 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8293 hr = IDirect3DDevice9_BeginScene(device);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8295 if(SUCCEEDED(hr)) {
8296 ptsize = 16.0;
8297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8300 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8302 ptsize = 32.0;
8303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8308 ptsize = 31.5;
8309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8310 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8312 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8314 if(caps.MaxPointSize >= 64.0) {
8315 ptsize = 64.0;
8316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8318 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8319 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8321 ptsize = 63.75;
8322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8325 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8328 ptsize = 1.0;
8329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8332 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8334 hr = IDirect3DDevice9_EndScene(device);
8335 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8337 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8338 color = getPixelColor(device, 64-9, 64-9);
8339 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8340 color = getPixelColor(device, 64-8, 64-8);
8341 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8342 color = getPixelColor(device, 64-7, 64-7);
8343 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8344 color = getPixelColor(device, 64+7, 64+7);
8345 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8346 color = getPixelColor(device, 64+8, 64+8);
8347 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8348 color = getPixelColor(device, 64+9, 64+9);
8349 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8351 color = getPixelColor(device, 128-17, 64-17);
8352 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8353 color = getPixelColor(device, 128-16, 64-16);
8354 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8355 color = getPixelColor(device, 128-15, 64-15);
8356 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8357 color = getPixelColor(device, 128+15, 64+15);
8358 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8359 color = getPixelColor(device, 128+16, 64+16);
8360 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8361 color = getPixelColor(device, 128+17, 64+17);
8362 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8364 color = getPixelColor(device, 192-17, 64-17);
8365 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8366 color = getPixelColor(device, 192-16, 64-16);
8367 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8368 color = getPixelColor(device, 192-15, 64-15);
8369 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8370 color = getPixelColor(device, 192+15, 64+15);
8371 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8372 color = getPixelColor(device, 192+16, 64+16);
8373 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8374 color = getPixelColor(device, 192+17, 64+17);
8375 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8377 if(caps.MaxPointSize >= 64.0) {
8378 color = getPixelColor(device, 256-33, 64-33);
8379 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8380 color = getPixelColor(device, 256-32, 64-32);
8381 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8382 color = getPixelColor(device, 256-31, 64-31);
8383 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8384 color = getPixelColor(device, 256+31, 64+31);
8385 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8386 color = getPixelColor(device, 256+32, 64+32);
8387 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8388 color = getPixelColor(device, 256+33, 64+33);
8389 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8391 color = getPixelColor(device, 384-33, 64-33);
8392 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8393 color = getPixelColor(device, 384-32, 64-32);
8394 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8395 color = getPixelColor(device, 384-31, 64-31);
8396 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8397 color = getPixelColor(device, 384+31, 64+31);
8398 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8399 color = getPixelColor(device, 384+32, 64+32);
8400 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8401 color = getPixelColor(device, 384+33, 64+33);
8402 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8405 color = getPixelColor(device, 320-1, 64-1);
8406 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8407 color = getPixelColor(device, 320-0, 64-0);
8408 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8409 color = getPixelColor(device, 320+1, 64+1);
8410 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8413 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8414 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8418 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8420 HRESULT hr;
8421 IDirect3DPixelShader9 *ps;
8422 IDirect3DTexture9 *tex1, *tex2;
8423 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8424 D3DCAPS9 caps;
8425 DWORD color;
8426 DWORD shader_code[] = {
8427 0xffff0300, /* ps_3_0 */
8428 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8429 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8430 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8431 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8432 0x0000ffff /* END */
8434 float quad[] = {
8435 -1.0, -1.0, 0.1,
8436 1.0, -1.0, 0.1,
8437 -1.0, 1.0, 0.1,
8438 1.0, 1.0, 0.1,
8440 float texquad[] = {
8441 -1.0, -1.0, 0.1, 0.0, 0.0,
8442 0.0, -1.0, 0.1, 1.0, 0.0,
8443 -1.0, 1.0, 0.1, 0.0, 1.0,
8444 0.0, 1.0, 0.1, 1.0, 1.0,
8446 0.0, -1.0, 0.1, 0.0, 0.0,
8447 1.0, -1.0, 0.1, 1.0, 0.0,
8448 0.0, 1.0, 0.1, 0.0, 1.0,
8449 1.0, 1.0, 0.1, 1.0, 1.0,
8452 memset(&caps, 0, sizeof(caps));
8453 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8455 if(caps.NumSimultaneousRTs < 2) {
8456 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8457 return;
8460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8461 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8463 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8465 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8466 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8467 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8468 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8470 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8471 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8472 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8473 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8474 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8475 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8477 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8478 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8479 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8481 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8482 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8483 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8484 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8486 hr = IDirect3DDevice9_BeginScene(device);
8487 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8488 if(SUCCEEDED(hr)) {
8489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8490 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8492 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8493 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8494 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8495 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8496 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8497 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8498 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8499 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8501 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8504 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8506 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8507 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8509 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8511 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8512 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8514 hr = IDirect3DDevice9_EndScene(device);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8518 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8519 color = getPixelColor(device, 160, 240);
8520 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8521 color = getPixelColor(device, 480, 240);
8522 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8524 IDirect3DPixelShader9_Release(ps);
8525 IDirect3DTexture9_Release(tex1);
8526 IDirect3DTexture9_Release(tex2);
8527 IDirect3DSurface9_Release(surf1);
8528 IDirect3DSurface9_Release(surf2);
8529 IDirect3DSurface9_Release(backbuf);
8532 struct formats {
8533 const char *fmtName;
8534 D3DFORMAT textureFormat;
8535 DWORD resultColorBlending;
8536 DWORD resultColorNoBlending;
8539 const struct formats test_formats[] = {
8540 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8541 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8542 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8543 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8544 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8545 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8546 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8547 { NULL, 0 }
8550 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8552 HRESULT hr;
8553 IDirect3DTexture9 *offscreenTexture = NULL;
8554 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8555 IDirect3D9 *d3d = NULL;
8556 DWORD color;
8557 DWORD r0, g0, b0, r1, g1, b1;
8558 int fmt_index;
8560 static const float quad[][5] = {
8561 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8562 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8563 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8564 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8567 /* Quad with R=0x10, G=0x20 */
8568 static const struct vertex quad1[] = {
8569 {-1.0f, -1.0f, 0.1f, 0x80102000},
8570 {-1.0f, 1.0f, 0.1f, 0x80102000},
8571 { 1.0f, -1.0f, 0.1f, 0x80102000},
8572 { 1.0f, 1.0f, 0.1f, 0x80102000},
8575 /* Quad with R=0x20, G=0x10 */
8576 static const struct vertex quad2[] = {
8577 {-1.0f, -1.0f, 0.1f, 0x80201000},
8578 {-1.0f, 1.0f, 0.1f, 0x80201000},
8579 { 1.0f, -1.0f, 0.1f, 0x80201000},
8580 { 1.0f, 1.0f, 0.1f, 0x80201000},
8583 IDirect3DDevice9_GetDirect3D(device, &d3d);
8585 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8586 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8587 if(!backbuffer) {
8588 goto out;
8591 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8593 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8594 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8595 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8596 continue;
8599 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8600 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8602 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8603 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8604 if(!offscreenTexture) {
8605 continue;
8608 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8609 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8610 if(!offscreen) {
8611 continue;
8614 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8615 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8617 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8618 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8619 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8620 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8621 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8622 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8623 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8624 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8628 /* Below we will draw two quads with different colors and try to blend them together.
8629 * The result color is compared with the expected outcome.
8631 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8632 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8633 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8634 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8635 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8638 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8640 /* Draw a quad using color 0x0010200 */
8641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8642 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8644 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8646 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8648 /* Draw a quad using color 0x0020100 */
8649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8652 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8654 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8656 /* We don't want to blend the result on the backbuffer */
8657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8658 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8660 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8661 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8662 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8663 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8664 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8666 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8667 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8669 /* This time with the texture */
8670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8671 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8673 IDirect3DDevice9_EndScene(device);
8675 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8678 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8679 /* Compare the color of the center quad with our expectation */
8680 color = getPixelColor(device, 320, 240);
8681 r0 = (color & 0x00ff0000) >> 16;
8682 g0 = (color & 0x0000ff00) >> 8;
8683 b0 = (color & 0x000000ff) >> 0;
8685 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8686 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8687 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8689 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8690 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8691 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8692 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8693 } else {
8694 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8695 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8696 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8697 color = getPixelColor(device, 320, 240);
8698 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);
8701 IDirect3DDevice9_SetTexture(device, 0, NULL);
8702 if(offscreenTexture) {
8703 IDirect3DTexture9_Release(offscreenTexture);
8705 if(offscreen) {
8706 IDirect3DSurface9_Release(offscreen);
8710 out:
8711 /* restore things */
8712 if(backbuffer) {
8713 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8714 IDirect3DSurface9_Release(backbuffer);
8718 static void tssargtemp_test(IDirect3DDevice9 *device)
8720 HRESULT hr;
8721 DWORD color;
8722 static const struct vertex quad[] = {
8723 {-1.0, -1.0, 0.1, 0x00ff0000},
8724 { 1.0, -1.0, 0.1, 0x00ff0000},
8725 {-1.0, 1.0, 0.1, 0x00ff0000},
8726 { 1.0, 1.0, 0.1, 0x00ff0000}
8728 D3DCAPS9 caps;
8730 memset(&caps, 0, sizeof(caps));
8731 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8732 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8733 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8734 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8735 return;
8738 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8739 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8742 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8743 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8744 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8746 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8747 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8748 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8749 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8750 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8751 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8753 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8754 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8755 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8756 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8757 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8758 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8760 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8761 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8764 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8765 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8766 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8768 hr = IDirect3DDevice9_BeginScene(device);
8769 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8770 if(SUCCEEDED(hr)) {
8772 hr = IDirect3DDevice9_EndScene(device);
8773 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8775 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8777 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8778 color = getPixelColor(device, 320, 240);
8779 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8781 /* Set stage 1 back to default */
8782 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8783 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8784 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8785 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8786 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8787 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8788 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8789 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8790 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8791 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8794 struct testdata
8796 DWORD idxVertex; /* number of instances in the first stream */
8797 DWORD idxColor; /* number of instances in the second stream */
8798 DWORD idxInstance; /* should be 1 ?? */
8799 DWORD color1; /* color 1 instance */
8800 DWORD color2; /* color 2 instance */
8801 DWORD color3; /* color 3 instance */
8802 DWORD color4; /* color 4 instance */
8803 WORD strVertex; /* specify which stream to use 0-2*/
8804 WORD strColor;
8805 WORD strInstance;
8808 static const struct testdata testcases[]=
8810 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8811 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8812 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8813 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8814 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8815 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8816 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8817 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8818 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8819 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8820 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8821 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8822 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8823 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8824 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8826 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8827 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8831 /* Drawing Indexed Geometry with instances*/
8832 static void stream_test(IDirect3DDevice9 *device)
8834 IDirect3DVertexBuffer9 *vb = NULL;
8835 IDirect3DVertexBuffer9 *vb2 = NULL;
8836 IDirect3DVertexBuffer9 *vb3 = NULL;
8837 IDirect3DIndexBuffer9 *ib = NULL;
8838 IDirect3DVertexDeclaration9 *pDecl = NULL;
8839 IDirect3DVertexShader9 *shader = NULL;
8840 HRESULT hr;
8841 BYTE *data;
8842 DWORD color;
8843 DWORD ind;
8844 unsigned i;
8846 const DWORD shader_code[] =
8848 0xfffe0101, /* vs_1_1 */
8849 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8850 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8851 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8852 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8853 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8854 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8855 0x0000ffff
8858 const float quad[][3] =
8860 {-0.5f, -0.5f, 1.1f}, /*0 */
8861 {-0.5f, 0.5f, 1.1f}, /*1 */
8862 { 0.5f, -0.5f, 1.1f}, /*2 */
8863 { 0.5f, 0.5f, 1.1f}, /*3 */
8866 const float vertcolor[][4] =
8868 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8869 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8870 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8871 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8874 /* 4 position for 4 instances */
8875 const float instancepos[][3] =
8877 {-0.6f,-0.6f, 0.0f},
8878 { 0.6f,-0.6f, 0.0f},
8879 { 0.6f, 0.6f, 0.0f},
8880 {-0.6f, 0.6f, 0.0f},
8883 short indices[] = {0, 1, 2, 1, 2, 3};
8885 D3DVERTEXELEMENT9 decl[] =
8887 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8888 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8889 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8890 D3DDECL_END()
8893 /* set the default value because it isn't done in wine? */
8894 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8895 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8897 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8898 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8899 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8901 /* check wrong cases */
8902 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8903 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8904 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8905 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8906 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8907 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8908 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8909 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8910 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8911 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8912 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8913 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8914 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8915 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8916 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8917 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8918 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8919 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8920 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8921 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8923 /* set the default value back */
8924 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8925 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8927 /* create all VertexBuffers*/
8928 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8929 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8930 if(!vb) {
8931 skip("Failed to create a vertex buffer\n");
8932 return;
8934 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8935 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8936 if(!vb2) {
8937 skip("Failed to create a vertex buffer\n");
8938 goto out;
8940 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8941 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8942 if(!vb3) {
8943 skip("Failed to create a vertex buffer\n");
8944 goto out;
8947 /* create IndexBuffer*/
8948 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
8950 if(!ib) {
8951 skip("Failed to create a index buffer\n");
8952 goto out;
8955 /* copy all Buffers (Vertex + Index)*/
8956 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8957 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8958 memcpy(data, quad, sizeof(quad));
8959 hr = IDirect3DVertexBuffer9_Unlock(vb);
8960 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8961 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8962 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8963 memcpy(data, vertcolor, sizeof(vertcolor));
8964 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8965 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8966 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8967 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8968 memcpy(data, instancepos, sizeof(instancepos));
8969 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8970 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8971 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8972 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
8973 memcpy(data, indices, sizeof(indices));
8974 hr = IDirect3DIndexBuffer9_Unlock(ib);
8975 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8977 /* create VertexShader */
8978 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8979 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8980 if(!shader) {
8981 skip("Failed to create a vetex shader\n");
8982 goto out;
8985 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8986 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8988 hr = IDirect3DDevice9_SetIndices(device, ib);
8989 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8991 /* run all tests */
8992 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8994 struct testdata act = testcases[i];
8995 decl[0].Stream = act.strVertex;
8996 decl[1].Stream = act.strColor;
8997 decl[2].Stream = act.strInstance;
8998 /* create VertexDeclarations */
8999 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9000 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9002 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9003 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9005 hr = IDirect3DDevice9_BeginScene(device);
9006 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9007 if(SUCCEEDED(hr))
9009 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9010 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9012 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9013 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9014 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9015 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9017 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9018 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9019 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9020 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9022 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9023 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9024 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9025 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9027 /* don't know if this is right (1*3 and 4*1)*/
9028 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9029 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9030 hr = IDirect3DDevice9_EndScene(device);
9031 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9033 /* set all StreamSource && StreamSourceFreq back to default */
9034 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9035 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9036 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9037 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9038 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9039 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9040 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9041 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9042 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9043 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9044 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9045 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9048 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9049 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9051 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9052 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9054 color = getPixelColor(device, 160, 360);
9055 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9056 color = getPixelColor(device, 480, 360);
9057 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9058 color = getPixelColor(device, 480, 120);
9059 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9060 color = getPixelColor(device, 160, 120);
9061 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9064 hr = IDirect3DDevice9_SetIndices(device, NULL);
9065 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9067 out:
9068 if(vb) IDirect3DVertexBuffer9_Release(vb);
9069 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9070 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9071 if(ib)IDirect3DIndexBuffer9_Release(ib);
9072 if(shader)IDirect3DVertexShader9_Release(shader);
9075 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9076 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9077 IDirect3DTexture9 *dsttex = NULL;
9078 HRESULT hr;
9079 DWORD color;
9080 D3DRECT r1 = {0, 0, 50, 50 };
9081 D3DRECT r2 = {50, 0, 100, 50 };
9082 D3DRECT r3 = {50, 50, 100, 100};
9083 D3DRECT r4 = {0, 50, 50, 100};
9084 const float quad[] = {
9085 -1.0, -1.0, 0.1, 0.0, 0.0,
9086 1.0, -1.0, 0.1, 1.0, 0.0,
9087 -1.0, 1.0, 0.1, 0.0, 1.0,
9088 1.0, 1.0, 0.1, 1.0, 1.0,
9091 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9092 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9094 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9095 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9096 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9097 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9099 if(!src || !dsttex) {
9100 skip("One or more test resources could not be created\n");
9101 goto cleanup;
9104 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9105 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9107 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9108 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9110 /* Clear the StretchRect destination for debugging */
9111 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9113 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9114 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9116 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9117 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9119 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9120 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9121 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9122 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9123 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9124 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9125 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9126 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9128 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9129 * the target -> texture GL blit path
9131 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9132 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9133 IDirect3DSurface9_Release(dst);
9135 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9136 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9138 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9139 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9140 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9141 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9142 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9143 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9145 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9147 hr = IDirect3DDevice9_BeginScene(device);
9148 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9149 if(SUCCEEDED(hr)) {
9150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9151 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9152 hr = IDirect3DDevice9_EndScene(device);
9153 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9156 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9157 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9158 color = getPixelColor(device, 160, 360);
9159 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9160 color = getPixelColor(device, 480, 360);
9161 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9162 color = getPixelColor(device, 480, 120);
9163 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9164 color = getPixelColor(device, 160, 120);
9165 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9167 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9168 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9169 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9170 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9172 cleanup:
9173 if(src) IDirect3DSurface9_Release(src);
9174 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9175 if(dsttex) IDirect3DTexture9_Release(dsttex);
9178 static void texop_test(IDirect3DDevice9 *device)
9180 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9181 IDirect3DTexture9 *texture = NULL;
9182 D3DLOCKED_RECT locked_rect;
9183 D3DCOLOR color;
9184 D3DCAPS9 caps;
9185 HRESULT hr;
9186 unsigned i;
9188 static const struct {
9189 float x, y, z;
9190 float s, t;
9191 D3DCOLOR diffuse;
9192 } quad[] = {
9193 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9194 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9195 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9196 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9199 static const D3DVERTEXELEMENT9 decl_elements[] = {
9200 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9201 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9202 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9203 D3DDECL_END()
9206 static const struct {
9207 D3DTEXTUREOP op;
9208 const char *name;
9209 DWORD caps_flag;
9210 D3DCOLOR result;
9211 } test_data[] = {
9212 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9213 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9214 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9215 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9216 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9217 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9218 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9219 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9220 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9221 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9222 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9223 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9224 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9225 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9226 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9227 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9228 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9229 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9230 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9231 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9232 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9233 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9234 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9237 memset(&caps, 0, sizeof(caps));
9238 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9239 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9241 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9242 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9243 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9244 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9246 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9247 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9248 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9249 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9250 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9251 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9252 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9253 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9254 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9256 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9257 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9258 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9259 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9260 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9261 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9263 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9264 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9267 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9269 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9271 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9273 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9274 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9276 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9278 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9280 skip("tex operation %s not supported\n", test_data[i].name);
9281 continue;
9284 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9285 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9287 hr = IDirect3DDevice9_BeginScene(device);
9288 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9290 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9291 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9293 hr = IDirect3DDevice9_EndScene(device);
9294 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9297 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9299 color = getPixelColor(device, 320, 240);
9300 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9301 test_data[i].name, color, test_data[i].result);
9304 if (texture) IDirect3DTexture9_Release(texture);
9305 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9308 static void yuv_color_test(IDirect3DDevice9 *device) {
9309 HRESULT hr;
9310 IDirect3DSurface9 *surface = NULL, *target = NULL;
9311 unsigned int fmt, i;
9312 D3DFORMAT format;
9313 const char *fmt_string;
9314 D3DLOCKED_RECT lr;
9315 IDirect3D9 *d3d;
9316 HRESULT color;
9317 DWORD ref_color_left, ref_color_right;
9319 struct {
9320 DWORD in; /* The input color */
9321 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9322 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9323 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9324 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9325 } test_data[] = {
9326 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9327 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9328 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9329 * that
9331 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9332 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9333 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9334 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9335 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9336 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9337 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9338 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9339 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9340 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9341 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9342 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9343 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9344 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9346 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9347 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9348 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9349 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9352 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9353 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9354 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9355 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9357 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9358 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9360 for(fmt = 0; fmt < 2; fmt++) {
9361 if(fmt == 0) {
9362 format = D3DFMT_UYVY;
9363 fmt_string = "D3DFMT_UYVY";
9364 } else {
9365 format = D3DFMT_YUY2;
9366 fmt_string = "D3DFMT_YUY2";
9369 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9370 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9372 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9373 D3DRTYPE_SURFACE, format) != D3D_OK) {
9374 skip("%s is not supported\n", fmt_string);
9375 continue;
9378 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9379 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9380 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9382 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9383 if(fmt == 0) {
9384 ref_color_left = test_data[i].uyvy_left;
9385 ref_color_right = test_data[i].uyvy_right;
9386 } else {
9387 ref_color_left = test_data[i].yuy2_left;
9388 ref_color_right = test_data[i].yuy2_right;
9391 memset(&lr, 0, sizeof(lr));
9392 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9393 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9394 *((DWORD *) lr.pBits) = test_data[i].in;
9395 hr = IDirect3DSurface9_UnlockRect(surface);
9396 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9400 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9401 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9403 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9405 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9406 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9407 * want to add tests for the filtered pixels as well.
9409 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9410 * differently, so we need a max diff of 16
9412 color = getPixelColor(device, 40, 240);
9413 ok(color_match(color, ref_color_left, 16),
9414 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9415 test_data[i].in, color, ref_color_left, fmt_string);
9416 color = getPixelColor(device, 600, 240);
9417 ok(color_match(color, ref_color_right, 16),
9418 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9419 test_data[i].in, color, ref_color_left, fmt_string);
9421 IDirect3DSurface9_Release(surface);
9423 IDirect3DSurface9_Release(target);
9424 IDirect3D9_Release(d3d);
9427 static void texop_range_test(IDirect3DDevice9 *device)
9429 static const struct {
9430 float x, y, z;
9431 D3DCOLOR diffuse;
9432 } quad[] = {
9433 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9434 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9435 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9436 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9438 HRESULT hr;
9439 IDirect3DTexture9 *texture;
9440 D3DLOCKED_RECT locked_rect;
9441 D3DCAPS9 caps;
9442 DWORD color;
9444 /* We need ADD and SUBTRACT operations */
9445 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9446 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9447 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9448 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9450 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9451 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9454 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9455 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9456 /* Stage 1: result = diffuse(=1.0) + diffuse
9457 * stage 2: result = result - tfactor(= 0.5)
9459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9460 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9461 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9462 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9463 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9464 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9465 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9466 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9467 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9468 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9469 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9470 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9471 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9472 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9474 hr = IDirect3DDevice9_BeginScene(device);
9475 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9477 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9478 hr = IDirect3DDevice9_EndScene(device);
9479 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9480 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9481 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9483 color = getPixelColor(device, 320, 240);
9484 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9485 color);
9487 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9488 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9489 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9490 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9491 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9492 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9493 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9494 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9495 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9497 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9498 * stage 2: result = result + diffuse(1.0)
9500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9501 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9502 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9503 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9504 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9505 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9506 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9507 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9508 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9509 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9510 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9511 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9512 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9513 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9515 hr = IDirect3DDevice9_BeginScene(device);
9516 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9518 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9519 hr = IDirect3DDevice9_EndScene(device);
9520 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9521 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9522 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9524 color = getPixelColor(device, 320, 240);
9525 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9526 color);
9528 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9529 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9530 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9531 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9532 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)NULL);
9533 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9534 IDirect3DTexture9_Release(texture);
9537 static void alphareplicate_test(IDirect3DDevice9 *device) {
9538 struct vertex quad[] = {
9539 { -1.0, -1.0, 0.1, 0x80ff00ff },
9540 { 1.0, -1.0, 0.1, 0x80ff00ff },
9541 { -1.0, 1.0, 0.1, 0x80ff00ff },
9542 { 1.0, 1.0, 0.1, 0x80ff00ff },
9544 HRESULT hr;
9545 DWORD color;
9547 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9548 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9550 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9551 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9555 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9556 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9558 hr = IDirect3DDevice9_BeginScene(device);
9559 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9560 if(SUCCEEDED(hr)) {
9561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9562 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9563 hr = IDirect3DDevice9_EndScene(device);
9564 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9568 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9570 color = getPixelColor(device, 320, 240);
9571 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9572 color);
9574 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9579 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9580 HRESULT hr;
9581 D3DCAPS9 caps;
9582 DWORD color;
9583 struct vertex quad[] = {
9584 { -1.0, -1.0, 0.1, 0x408080c0 },
9585 { 1.0, -1.0, 0.1, 0x408080c0 },
9586 { -1.0, 1.0, 0.1, 0x408080c0 },
9587 { 1.0, 1.0, 0.1, 0x408080c0 },
9590 memset(&caps, 0, sizeof(caps));
9591 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9592 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9593 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9594 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9595 return;
9598 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9599 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9601 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9602 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9604 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9605 * mov r0.a, diffuse.a
9606 * mov r0, r0.a
9608 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9609 * 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
9610 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9612 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9613 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9614 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9615 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9616 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9617 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9618 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9619 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9620 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9621 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9622 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9623 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9624 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9625 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9626 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9627 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9629 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9631 hr = IDirect3DDevice9_BeginScene(device);
9632 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9633 if(SUCCEEDED(hr)) {
9634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9635 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9636 hr = IDirect3DDevice9_EndScene(device);
9637 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9640 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9641 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9643 color = getPixelColor(device, 320, 240);
9644 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9645 color);
9647 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9648 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9649 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9650 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9651 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9652 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9655 START_TEST(visual)
9657 IDirect3DDevice9 *device_ptr;
9658 D3DCAPS9 caps;
9659 HRESULT hr;
9660 DWORD color;
9662 d3d9_handle = LoadLibraryA("d3d9.dll");
9663 if (!d3d9_handle)
9665 skip("Could not load d3d9.dll\n");
9666 return;
9669 device_ptr = init_d3d9();
9670 if (!device_ptr)
9672 skip("Creating the device failed\n");
9673 return;
9676 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9678 /* Check for the reliability of the returned data */
9679 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9680 if(FAILED(hr))
9682 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9683 goto cleanup;
9685 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9687 color = getPixelColor(device_ptr, 1, 1);
9688 if(color !=0x00ff0000)
9690 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9691 goto cleanup;
9694 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9695 if(FAILED(hr))
9697 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9698 goto cleanup;
9700 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9702 color = getPixelColor(device_ptr, 639, 479);
9703 if(color != 0x0000ddee)
9705 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9706 goto cleanup;
9709 /* Now execute the real tests */
9710 stretchrect_test(device_ptr);
9711 lighting_test(device_ptr);
9712 clear_test(device_ptr);
9713 fog_test(device_ptr);
9714 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9716 test_cube_wrap(device_ptr);
9717 } else {
9718 skip("No cube texture support\n");
9720 z_range_test(device_ptr);
9721 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9723 maxmip_test(device_ptr);
9725 else
9727 skip("No mipmap support\n");
9729 offscreen_test(device_ptr);
9730 alpha_test(device_ptr);
9731 shademode_test(device_ptr);
9732 srgbtexture_test(device_ptr);
9733 release_buffer_test(device_ptr);
9734 float_texture_test(device_ptr);
9735 g16r16_texture_test(device_ptr);
9736 pixelshader_blending_test(device_ptr);
9737 texture_transform_flags_test(device_ptr);
9738 autogen_mipmap_test(device_ptr);
9739 fixed_function_decl_test(device_ptr);
9740 conditional_np2_repeat_test(device_ptr);
9741 fixed_function_bumpmap_test(device_ptr);
9742 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9743 stencil_cull_test(device_ptr);
9744 } else {
9745 skip("No two sided stencil support\n");
9747 pointsize_test(device_ptr);
9748 tssargtemp_test(device_ptr);
9749 np2_stretch_rect_test(device_ptr);
9750 yuv_color_test(device_ptr);
9752 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9754 test_constant_clamp_vs(device_ptr);
9755 test_compare_instructions(device_ptr);
9757 else skip("No vs_1_1 support\n");
9759 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9761 test_mova(device_ptr);
9762 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9763 test_vshader_input(device_ptr);
9764 test_vshader_float16(device_ptr);
9765 stream_test(device_ptr);
9766 } else {
9767 skip("No vs_3_0 support\n");
9770 else skip("No vs_2_0 support\n");
9772 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9774 fog_with_shader_test(device_ptr);
9775 fog_srgbwrite_test(device_ptr);
9777 else skip("No vs_1_1 and ps_1_1 support\n");
9779 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9781 texbem_test(device_ptr);
9782 texdepth_test(device_ptr);
9783 texkill_test(device_ptr);
9784 x8l8v8u8_test(device_ptr);
9785 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9786 constant_clamp_ps_test(device_ptr);
9787 cnd_test(device_ptr);
9788 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9789 dp2add_ps_test(device_ptr);
9790 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9791 nested_loop_test(device_ptr);
9792 fixed_function_varying_test(device_ptr);
9793 vFace_register_test(device_ptr);
9794 vpos_register_test(device_ptr);
9795 multiple_rendertargets_test(device_ptr);
9796 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9797 vshader_version_varying_test(device_ptr);
9798 pshader_version_varying_test(device_ptr);
9799 } else {
9800 skip("No vs_3_0 support\n");
9802 } else {
9803 skip("No ps_3_0 support\n");
9805 } else {
9806 skip("No ps_2_0 support\n");
9810 else skip("No ps_1_1 support\n");
9812 texop_test(device_ptr);
9813 texop_range_test(device_ptr);
9814 alphareplicate_test(device_ptr);
9815 dp3_alpha_test(device_ptr);
9817 cleanup:
9818 if(device_ptr) {
9819 ULONG ref;
9821 D3DPRESENT_PARAMETERS present_parameters;
9822 IDirect3DSwapChain9 *swapchain;
9823 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9824 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9825 IDirect3DSwapChain9_Release(swapchain);
9826 ref = IDirect3DDevice9_Release(device_ptr);
9827 DestroyWindow(present_parameters.hDeviceWindow);
9828 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);