d3d9: Avoid a not needed address-of operator.
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
bloba328123ef874707d8a00482e7065affa99d11251
1 /*
2 * Copyright 2005, 2007 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 <dxerr9.h>
34 #include "wine/test.h"
36 static HMODULE d3d9_handle = 0;
38 static HWND create_window(void)
40 WNDCLASS wc = {0};
41 HWND ret;
42 wc.lpfnWndProc = DefWindowProc;
43 wc.lpszClassName = "d3d9_test_wc";
44 RegisterClass(&wc);
46 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
47 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%s\n", DXGetErrorString9(hr));
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%s\n", DXGetErrorString9(hr));
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%s\n", DXGetErrorString9(hr));
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
114 if(FAILED(hr) || !surf ) /* This is not a test */
116 trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
117 return 0xdeadbeef;
120 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
121 if(FAILED(hr))
123 trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
124 ret = 0xdeadbeed;
125 goto out;
128 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
129 if(FAILED(hr))
131 trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
132 ret = 0xdeadbeec;
133 goto out;
136 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
137 * really important for these tests
139 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
140 hr = IDirect3DSurface9_UnlockRect(surf);
141 if(FAILED(hr))
143 trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
146 out:
147 if(surf) IDirect3DSurface9_Release(surf);
148 return ret;
151 static IDirect3DDevice9 *init_d3d9(void)
153 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
154 IDirect3D9 *d3d9_ptr = 0;
155 IDirect3DDevice9 *device_ptr = 0;
156 D3DPRESENT_PARAMETERS present_parameters;
157 HRESULT hr;
158 D3DADAPTER_IDENTIFIER9 identifier;
160 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
161 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
162 if (!d3d9_create) return NULL;
164 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
165 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
166 if (!d3d9_ptr) return NULL;
168 ZeroMemory(&present_parameters, sizeof(present_parameters));
169 present_parameters.Windowed = FALSE;
170 present_parameters.hDeviceWindow = create_window();
171 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
172 present_parameters.BackBufferWidth = 640;
173 present_parameters.BackBufferHeight = 480;
174 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
175 present_parameters.EnableAutoDepthStencil = TRUE;
176 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
178 memset(&identifier, 0, sizeof(identifier));
179 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
180 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
181 trace("Driver string: \"%s\"\n", identifier.Driver);
182 trace("Description string: \"%s\"\n", identifier.Description);
183 trace("Device name string: \"%s\"\n", identifier.DeviceName);
184 trace("Driver version %d.%d.%d.%d\n",
185 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
186 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
188 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
189 if(FAILED(hr)) {
190 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
191 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
192 if(FAILED(hr)) {
193 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
198 return device_ptr;
201 struct vertex
203 float x, y, z;
204 DWORD diffuse;
207 struct tvertex
209 float x, y, z, rhw;
210 DWORD diffuse;
213 struct nvertex
215 float x, y, z;
216 float nx, ny, nz;
217 DWORD diffuse;
220 static void lighting_test(IDirect3DDevice9 *device)
222 HRESULT hr;
223 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
224 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
225 DWORD color;
227 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
228 0.0f, 1.0f, 0.0f, 0.0f,
229 0.0f, 0.0f, 1.0f, 0.0f,
230 0.0f, 0.0f, 0.0f, 1.0f };
232 struct vertex unlitquad[] =
234 {-1.0f, -1.0f, 0.1f, 0xffff0000},
235 {-1.0f, 0.0f, 0.1f, 0xffff0000},
236 { 0.0f, 0.0f, 0.1f, 0xffff0000},
237 { 0.0f, -1.0f, 0.1f, 0xffff0000},
239 struct vertex litquad[] =
241 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
242 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
243 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
244 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
246 struct nvertex unlitnquad[] =
248 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
249 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
250 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
251 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
253 struct nvertex litnquad[] =
255 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
256 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
257 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
258 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
260 WORD Indices[] = {0, 1, 2, 2, 3, 0};
262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
263 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
265 /* Setup some states that may cause issues */
266 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
267 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
268 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
269 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
270 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
271 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
291 hr = IDirect3DDevice9_SetFVF(device, fvf);
292 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
294 hr = IDirect3DDevice9_BeginScene(device);
295 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
296 if(hr == D3D_OK)
298 /* No lights are defined... That means, lit vertices should be entirely black */
299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
301 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
302 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
303 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
306 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
307 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
308 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
309 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
311 hr = IDirect3DDevice9_SetFVF(device, nfvf);
312 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
318 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
322 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
323 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
324 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
326 IDirect3DDevice9_EndScene(device);
327 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
330 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
332 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
333 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
334 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
335 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
336 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
337 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
338 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
339 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
341 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
342 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
345 static void clear_test(IDirect3DDevice9 *device)
347 /* Tests the correctness of clearing parameters */
348 HRESULT hr;
349 D3DRECT rect[2];
350 D3DRECT rect_negneg;
351 DWORD color;
352 D3DVIEWPORT9 old_vp, vp;
353 RECT scissor;
354 DWORD oldColorWrite;
355 BOOL invalid_clear_failed = FALSE;
357 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
358 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
360 /* Positive x, negative y */
361 rect[0].x1 = 0;
362 rect[0].y1 = 480;
363 rect[0].x2 = 320;
364 rect[0].y2 = 240;
366 /* Positive x, positive y */
367 rect[1].x1 = 0;
368 rect[1].y1 = 0;
369 rect[1].x2 = 320;
370 rect[1].y2 = 240;
371 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
372 * returns D3D_OK, but ignores the rectangle silently
374 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
375 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
376 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
378 /* negative x, negative y */
379 rect_negneg.x1 = 640;
380 rect_negneg.y1 = 240;
381 rect_negneg.x2 = 320;
382 rect_negneg.y2 = 0;
383 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
384 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
385 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
387 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
389 color = getPixelColor(device, 160, 360); /* lower left quad */
390 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
391 color = getPixelColor(device, 160, 120); /* upper left quad */
392 if(invalid_clear_failed) {
393 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
394 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
395 } else {
396 /* If the negative rectangle was dropped silently, the correct ones are cleared */
397 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
399 color = getPixelColor(device, 480, 360); /* lower right quad */
400 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
401 color = getPixelColor(device, 480, 120); /* upper right quad */
402 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
404 /* Test how the viewport affects clears */
405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
406 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
407 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
408 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
410 vp.X = 160;
411 vp.Y = 120;
412 vp.Width = 160;
413 vp.Height = 120;
414 vp.MinZ = 0.0;
415 vp.MaxZ = 1.0;
416 hr = IDirect3DDevice9_SetViewport(device, &vp);
417 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
419 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
421 vp.X = 320;
422 vp.Y = 240;
423 vp.Width = 320;
424 vp.Height = 240;
425 vp.MinZ = 0.0;
426 vp.MaxZ = 1.0;
427 hr = IDirect3DDevice9_SetViewport(device, &vp);
428 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
429 rect[0].x1 = 160;
430 rect[0].y1 = 120;
431 rect[0].x2 = 480;
432 rect[0].y2 = 360;
433 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
434 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
436 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
437 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
439 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
440 color = getPixelColor(device, 158, 118);
441 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
442 color = getPixelColor(device, 162, 118);
443 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
444 color = getPixelColor(device, 158, 122);
445 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
446 color = getPixelColor(device, 162, 122);
447 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
449 color = getPixelColor(device, 318, 238);
450 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
451 color = getPixelColor(device, 322, 238);
452 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
453 color = getPixelColor(device, 318, 242);
454 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
455 color = getPixelColor(device, 322, 242);
456 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
458 color = getPixelColor(device, 478, 358);
459 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
460 color = getPixelColor(device, 482, 358);
461 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
462 color = getPixelColor(device, 478, 362);
463 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
464 color = getPixelColor(device, 482, 362);
465 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
468 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
470 scissor.left = 160;
471 scissor.right = 480;
472 scissor.top = 120;
473 scissor.bottom = 360;
474 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
475 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
476 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
477 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
479 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
480 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
481 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
482 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
485 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
487 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
488 color = getPixelColor(device, 158, 118);
489 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
490 color = getPixelColor(device, 162, 118);
491 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
492 color = getPixelColor(device, 158, 122);
493 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
494 color = getPixelColor(device, 162, 122);
495 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
497 color = getPixelColor(device, 158, 358);
498 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
499 color = getPixelColor(device, 162, 358);
500 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
501 color = getPixelColor(device, 158, 358);
502 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
503 color = getPixelColor(device, 162, 362);
504 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
506 color = getPixelColor(device, 478, 118);
507 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
508 color = getPixelColor(device, 478, 122);
509 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
510 color = getPixelColor(device, 482, 122);
511 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
512 color = getPixelColor(device, 482, 358);
513 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
515 color = getPixelColor(device, 478, 358);
516 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
517 color = getPixelColor(device, 478, 362);
518 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
519 color = getPixelColor(device, 482, 358);
520 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
521 color = getPixelColor(device, 482, 362);
522 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
524 color = getPixelColor(device, 318, 238);
525 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
526 color = getPixelColor(device, 318, 242);
527 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
528 color = getPixelColor(device, 322, 238);
529 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
530 color = getPixelColor(device, 322, 242);
531 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
533 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
534 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
536 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
539 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
542 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
544 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
546 /* Colorwriteenable does not affect the clear */
547 color = getPixelColor(device, 320, 240);
548 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
551 typedef struct {
552 float in[4];
553 DWORD out;
554 } test_data_t;
557 * c7 mova ARGB mov ARGB
558 * -2.4 -2 0x00ffff00 -3 0x00ff0000
559 * -1.6 -2 0x00ffff00 -2 0x00ffff00
560 * -0.4 0 0x0000ffff -1 0x0000ff00
561 * 0.4 0 0x0000ffff 0 0x0000ffff
562 * 1.6 2 0x00ff00ff 1 0x000000ff
563 * 2.4 2 0x00ff00ff 2 0x00ff00ff
565 static void test_mova(IDirect3DDevice9 *device)
567 static const DWORD mova_test[] = {
568 0xfffe0200, /* vs_2_0 */
569 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
570 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
571 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
572 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
573 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
574 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
575 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
576 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
577 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
578 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
579 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
580 0x0000ffff /* END */
582 static const DWORD mov_test[] = {
583 0xfffe0101, /* vs_1_1 */
584 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
585 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
586 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
587 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
588 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
589 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
590 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
591 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
592 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
593 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
594 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
595 0x0000ffff /* END */
598 static const test_data_t test_data[2][6] = {
600 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
601 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
602 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
603 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
604 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
605 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
608 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
609 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
610 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
611 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
612 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
613 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
617 static const float quad[][3] = {
618 {-1.0f, -1.0f, 0.0f},
619 {-1.0f, 1.0f, 0.0f},
620 { 1.0f, -1.0f, 0.0f},
621 { 1.0f, 1.0f, 0.0f},
624 static const D3DVERTEXELEMENT9 decl_elements[] = {
625 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
626 D3DDECL_END()
629 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
630 IDirect3DVertexShader9 *mova_shader = NULL;
631 IDirect3DVertexShader9 *mov_shader = NULL;
632 HRESULT hr;
633 UINT i, j;
635 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
636 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
637 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
638 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
639 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
640 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
641 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
642 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
644 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
645 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
646 for(j = 0; j < 2; ++j)
648 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
650 DWORD color;
652 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
653 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
655 hr = IDirect3DDevice9_BeginScene(device);
656 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
659 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
661 hr = IDirect3DDevice9_EndScene(device);
662 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
664 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
665 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
667 color = getPixelColor(device, 320, 240);
668 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
669 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
672 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
674 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
675 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
678 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
679 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
681 IDirect3DVertexDeclaration9_Release(vertex_declaration);
682 IDirect3DVertexShader9_Release(mova_shader);
683 IDirect3DVertexShader9_Release(mov_shader);
686 struct sVertex {
687 float x, y, z;
688 DWORD diffuse;
689 DWORD specular;
692 struct sVertexT {
693 float x, y, z, rhw;
694 DWORD diffuse;
695 DWORD specular;
698 static void fog_test(IDirect3DDevice9 *device)
700 HRESULT hr;
701 DWORD color;
702 BYTE r, g, b;
703 float start = 0.0f, end = 1.0f;
704 D3DCAPS9 caps;
705 int i;
707 /* Gets full z based fog with linear fog, no fog with specular color */
708 struct sVertex unstransformed_1[] = {
709 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
710 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
711 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
712 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
714 /* Ok, I am too lazy to deal with transform matrices */
715 struct sVertex unstransformed_2[] = {
716 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
717 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
718 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
719 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
721 /* Untransformed ones. Give them a different diffuse color to make the test look
722 * nicer. It also makes making sure that they are drawn correctly easier.
724 struct sVertexT transformed_1[] = {
725 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
726 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
727 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
728 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
730 struct sVertexT transformed_2[] = {
731 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
732 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
733 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
734 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
736 struct vertex rev_fog_quads[] = {
737 {-1.0, -1.0, 0.1, 0x000000ff},
738 {-1.0, 0.0, 0.1, 0x000000ff},
739 { 0.0, 0.0, 0.1, 0x000000ff},
740 { 0.0, -1.0, 0.1, 0x000000ff},
742 { 0.0, -1.0, 0.9, 0x000000ff},
743 { 0.0, 0.0, 0.9, 0x000000ff},
744 { 1.0, 0.0, 0.9, 0x000000ff},
745 { 1.0, -1.0, 0.9, 0x000000ff},
747 { 0.0, 0.0, 0.4, 0x000000ff},
748 { 0.0, 1.0, 0.4, 0x000000ff},
749 { 1.0, 1.0, 0.4, 0x000000ff},
750 { 1.0, 0.0, 0.4, 0x000000ff},
752 {-1.0, 0.0, 0.7, 0x000000ff},
753 {-1.0, 1.0, 0.7, 0x000000ff},
754 { 0.0, 1.0, 0.7, 0x000000ff},
755 { 0.0, 0.0, 0.7, 0x000000ff},
757 WORD Indices[] = {0, 1, 2, 2, 3, 0};
759 memset(&caps, 0, sizeof(caps));
760 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
761 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
762 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
763 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
765 /* Setup initial states: No lighting, fog on, fog color */
766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
767 ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
769 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
771 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
773 /* First test: Both table fog and vertex fog off */
774 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
775 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
777 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
779 /* Start = 0, end = 1. Should be default, but set them */
780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
781 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
783 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
785 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
787 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
788 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
789 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
790 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
791 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
792 sizeof(unstransformed_1[0]));
793 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
795 /* That makes it use the Z value */
796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
797 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
798 /* Untransformed, vertex fog != none (or table fog != none):
799 * Use the Z value as input into the equation
801 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
802 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
803 sizeof(unstransformed_1[0]));
804 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
806 /* transformed verts */
807 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
808 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
809 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
810 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
811 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
812 sizeof(transformed_1[0]));
813 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
816 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
817 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
818 * equation
820 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
821 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
822 sizeof(transformed_2[0]));
824 hr = IDirect3DDevice9_EndScene(device);
825 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
827 else
829 ok(FALSE, "BeginScene failed\n");
832 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
833 color = getPixelColor(device, 160, 360);
834 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
835 color = getPixelColor(device, 160, 120);
836 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
837 color = getPixelColor(device, 480, 120);
838 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
839 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
841 color = getPixelColor(device, 480, 360);
842 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
844 else
846 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
847 * The settings above result in no fogging with vertex fog
849 color = getPixelColor(device, 480, 120);
850 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
851 trace("Info: Table fog not supported by this device\n");
854 /* Now test the special case fogstart == fogend */
855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
856 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
858 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
860 start = 512;
861 end = 512;
862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
863 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
865 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
867 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
868 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
870 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
872 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
874 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
875 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
876 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
877 * The third transformed quad remains unfogged because the fogcoords are read from the specular
878 * color and has fixed fogstart and fogend.
880 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
881 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
882 sizeof(unstransformed_1[0]));
883 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
884 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
885 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
886 sizeof(unstransformed_1[0]));
887 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
889 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
890 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
891 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
892 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
893 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
894 sizeof(transformed_1[0]));
895 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
897 hr = IDirect3DDevice9_EndScene(device);
898 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
900 else
902 ok(FALSE, "BeginScene failed\n");
904 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
905 color = getPixelColor(device, 160, 360);
906 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
907 color = getPixelColor(device, 160, 120);
908 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
909 color = getPixelColor(device, 480, 120);
910 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
912 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
913 * but without shaders it seems to work everywhere
915 end = 0.2;
916 start = 0.8;
917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
918 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
920 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
921 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
922 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
924 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
925 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
926 * so skip this for now
928 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
929 const char *mode = (i ? "table" : "vertex");
930 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
931 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
933 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
935 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
936 hr = IDirect3DDevice9_BeginScene(device);
937 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
938 if(SUCCEEDED(hr)) {
939 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
940 4, 5, 6, 6, 7, 4,
941 8, 9, 10, 10, 11, 8,
942 12, 13, 14, 14, 15, 12};
944 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
945 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
946 sizeof(rev_fog_quads[0]));
948 hr = IDirect3DDevice9_EndScene(device);
949 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
951 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
952 color = getPixelColor(device, 160, 360);
953 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
955 color = getPixelColor(device, 160, 120);
956 r = (color & 0x00ff0000) >> 16;
957 g = (color & 0x0000ff00) >> 8;
958 b = (color & 0x000000ff);
959 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
960 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
962 color = getPixelColor(device, 480, 120);
963 r = (color & 0x00ff0000) >> 16;
964 g = (color & 0x0000ff00) >> 8;
965 b = (color & 0x000000ff);
966 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
967 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
969 color = getPixelColor(device, 480, 360);
970 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
972 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
973 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
974 break;
977 /* Turn off the fog master switch to avoid confusing other tests */
978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
979 ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
980 start = 0.0;
981 end = 1.0;
982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
983 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
985 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
987 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
989 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
992 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
993 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
994 * regardless of the actual addressing mode set. */
995 static void test_cube_wrap(IDirect3DDevice9 *device)
997 static const float quad[][6] = {
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},
1001 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1004 static const D3DVERTEXELEMENT9 decl_elements[] = {
1005 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1006 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1007 D3DDECL_END()
1010 static const struct {
1011 D3DTEXTUREADDRESS mode;
1012 const char *name;
1013 } address_modes[] = {
1014 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1015 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1016 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1017 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1018 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1021 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1022 IDirect3DCubeTexture9 *texture = NULL;
1023 IDirect3DSurface9 *surface = NULL;
1024 D3DLOCKED_RECT locked_rect;
1025 HRESULT hr;
1026 UINT x;
1027 INT y, face;
1029 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1030 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1031 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1032 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1034 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1035 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1036 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1038 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1039 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1041 for (y = 0; y < 128; ++y)
1043 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1044 for (x = 0; x < 64; ++x)
1046 *ptr++ = 0xffff0000;
1048 for (x = 64; x < 128; ++x)
1050 *ptr++ = 0xff0000ff;
1054 hr = IDirect3DSurface9_UnlockRect(surface);
1055 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1057 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1058 D3DPOOL_DEFAULT, &texture, NULL);
1059 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1061 /* Create cube faces */
1062 for (face = 0; face < 6; ++face)
1064 IDirect3DSurface9 *face_surface = NULL;
1066 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1067 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1069 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1070 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1072 IDirect3DSurface9_Release(face_surface);
1075 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1076 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1078 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1079 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1080 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1081 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1082 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1083 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1086 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1088 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1090 DWORD color;
1092 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1093 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1094 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1095 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1097 hr = IDirect3DDevice9_BeginScene(device);
1098 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1101 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1103 hr = IDirect3DDevice9_EndScene(device);
1104 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1106 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1107 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1109 /* Due to the nature of this test, we sample essentially at the edge
1110 * between two faces. Because of this it's undefined from which face
1111 * the driver will sample. Fortunately that's not important for this
1112 * test, since all we care about is that it doesn't sample from the
1113 * other side of the surface or from the border. */
1114 color = getPixelColor(device, 320, 240);
1115 ok(color == 0x00ff0000 || color == 0x000000ff,
1116 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1117 color, address_modes[x].name);
1119 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1120 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1123 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1124 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1126 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1127 IDirect3DCubeTexture9_Release(texture);
1128 IDirect3DSurface9_Release(surface);
1131 static void offscreen_test(IDirect3DDevice9 *device)
1133 HRESULT hr;
1134 IDirect3DTexture9 *offscreenTexture = NULL;
1135 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1136 DWORD color;
1138 static const float quad[][5] = {
1139 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1140 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1141 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1142 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1145 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1146 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1148 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1149 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1150 if(!offscreenTexture) {
1151 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1152 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1153 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1154 if(!offscreenTexture) {
1155 skip("Cannot create an offscreen render target\n");
1156 goto out;
1160 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1161 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1162 if(!backbuffer) {
1163 goto out;
1166 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1167 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1168 if(!offscreen) {
1169 goto out;
1172 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1173 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1175 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1176 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1178 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1179 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1180 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1181 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1182 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1183 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1184 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1186 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1187 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1188 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1190 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1192 /* Draw without textures - Should result in a white quad */
1193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1194 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1196 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1197 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1198 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1199 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1201 /* This time with the texture */
1202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1203 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1205 IDirect3DDevice9_EndScene(device);
1208 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1210 /* Center quad - should be white */
1211 color = getPixelColor(device, 320, 240);
1212 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1213 /* Some quad in the cleared part of the texture */
1214 color = getPixelColor(device, 170, 240);
1215 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1216 /* Part of the originally cleared back buffer */
1217 color = getPixelColor(device, 10, 10);
1218 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1219 if(0) {
1220 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1221 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1222 * the offscreen rendering mode this test would succeed or fail
1224 color = getPixelColor(device, 10, 470);
1225 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1228 out:
1229 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1231 /* restore things */
1232 if(backbuffer) {
1233 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1234 IDirect3DSurface9_Release(backbuffer);
1236 if(offscreenTexture) {
1237 IDirect3DTexture9_Release(offscreenTexture);
1239 if(offscreen) {
1240 IDirect3DSurface9_Release(offscreen);
1244 /* This test tests fog in combination with shaders.
1245 * What's tested: linear fog (vertex and table) with pixel shader
1246 * linear table fog with non foggy vertex shader
1247 * vertex fog with foggy vertex shader
1248 * What's not tested: non linear fog with shader
1249 * table fog with foggy vertex shader
1251 static void fog_with_shader_test(IDirect3DDevice9 *device)
1253 HRESULT hr;
1254 DWORD color;
1255 union {
1256 float f;
1257 DWORD i;
1258 } start, end;
1259 unsigned int i, j;
1261 /* basic vertex shader without fog computation ("non foggy") */
1262 static const DWORD vertex_shader_code1[] = {
1263 0xfffe0101, /* vs_1_1 */
1264 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1265 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1266 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1267 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1268 0x0000ffff
1270 /* basic vertex shader with reversed fog computation ("foggy") */
1271 static const DWORD vertex_shader_code2[] = {
1272 0xfffe0101, /* vs_1_1 */
1273 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1274 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1275 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1276 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1277 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1278 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1279 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1280 0x0000ffff
1282 /* basic pixel shader */
1283 static const DWORD pixel_shader_code[] = {
1284 0xffff0101, /* ps_1_1 */
1285 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1286 0x0000ffff
1289 static struct vertex quad[] = {
1290 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1291 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1292 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1293 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1296 static const D3DVERTEXELEMENT9 decl_elements[] = {
1297 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1298 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1299 D3DDECL_END()
1302 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1303 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1304 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1306 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1307 static const struct test_data_t {
1308 int vshader;
1309 int pshader;
1310 D3DFOGMODE vfog;
1311 D3DFOGMODE tfog;
1312 unsigned int color[11];
1313 } test_data[] = {
1314 /* only pixel shader: */
1315 {0, 1, 0, 3,
1316 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1317 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1318 {0, 1, 1, 3,
1319 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1320 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1321 {0, 1, 2, 3,
1322 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1323 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1324 {0, 1, 3, 0,
1325 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1326 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1327 {0, 1, 3, 3,
1328 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1329 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1331 /* vertex shader */
1332 {1, 0, 0, 0,
1333 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1334 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1335 {1, 0, 0, 3,
1336 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1337 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1338 {1, 0, 1, 3,
1339 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1340 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1342 {1, 0, 2, 3,
1343 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1344 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1345 {1, 0, 3, 3,
1346 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1347 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1349 /* vertex shader and pixel shader */
1350 {1, 1, 0, 3,
1351 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1352 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1353 {1, 1, 1, 3,
1354 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1355 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1356 {1, 1, 2, 3,
1357 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1358 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1360 {1, 1, 3, 3,
1361 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1362 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1365 #if 0 /* FIXME: these fail on GeForce 8500 */
1366 /* foggy vertex shader */
1367 {2, 0, 0, 0,
1368 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1369 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1370 {2, 0, 1, 0,
1371 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1372 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1373 {2, 0, 2, 0,
1374 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1375 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1376 {2, 0, 3, 0,
1377 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1378 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1379 #endif
1381 /* foggy vertex shader and pixel shader */
1382 {2, 1, 0, 0,
1383 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1384 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1385 {2, 1, 1, 0,
1386 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1387 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1388 {2, 1, 2, 0,
1389 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1390 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1391 {2, 1, 3, 0,
1392 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1393 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1397 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1398 start.f=0.1f;
1399 end.f=0.9f;
1401 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1402 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1403 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1404 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1405 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1406 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1407 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1408 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1410 /* Setup initial states: No lighting, fog on, fog color */
1411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1412 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1414 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1416 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1417 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1418 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1421 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1423 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1425 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1427 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1428 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1429 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1431 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1433 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1434 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1435 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1436 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1438 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1440 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1442 for(j=0; j < 11; j++)
1444 /* Don't use the whole zrange to prevent rounding errors */
1445 quad[0].z = 0.001f + (float)j / 10.02f;
1446 quad[1].z = 0.001f + (float)j / 10.02f;
1447 quad[2].z = 0.001f + (float)j / 10.02f;
1448 quad[3].z = 0.001f + (float)j / 10.02f;
1450 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1451 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1453 hr = IDirect3DDevice9_BeginScene(device);
1454 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1456 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1457 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1459 hr = IDirect3DDevice9_EndScene(device);
1460 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1462 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1464 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1465 color = getPixelColor(device, 128, 240);
1466 ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1467 && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1468 && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1469 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1470 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1474 /* reset states */
1475 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1476 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1477 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1478 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1479 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1480 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1481 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1482 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1484 IDirect3DVertexShader9_Release(vertex_shader[1]);
1485 IDirect3DVertexShader9_Release(vertex_shader[2]);
1486 IDirect3DPixelShader9_Release(pixel_shader[1]);
1487 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1490 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1491 unsigned int i, x, y;
1492 HRESULT hr;
1493 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1494 D3DLOCKED_RECT locked_rect;
1496 /* Generate the textures */
1497 for(i=0; i<2; i++)
1499 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1500 D3DPOOL_MANAGED, &texture[i], NULL);
1501 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1503 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1504 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1505 for (y = 0; y < 128; ++y)
1507 if(i)
1508 { /* Set up black texture with 2x2 texel white spot in the middle */
1509 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1510 for (x = 0; x < 128; ++x)
1512 if(y>62 && y<66 && x>62 && x<66)
1513 *ptr++ = 0xffffffff;
1514 else
1515 *ptr++ = 0xff000000;
1518 else
1519 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1520 * (if multiplied with bumpenvmat)
1522 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1523 for (x = 0; x < 128; ++x)
1525 if(abs(x-64)>abs(y-64))
1527 if(x < 64)
1528 *ptr++ = 0xc000;
1529 else
1530 *ptr++ = 0x4000;
1532 else
1534 if(y < 64)
1535 *ptr++ = 0x0040;
1536 else
1537 *ptr++ = 0x00c0;
1542 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1543 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1545 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1546 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1548 /* Disable texture filtering */
1549 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1550 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1551 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1552 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1554 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1555 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1556 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1557 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1561 /* test the behavior of the texbem instruction
1562 * with normal 2D and projective 2D textures
1564 static void texbem_test(IDirect3DDevice9 *device)
1566 HRESULT hr;
1567 DWORD color;
1568 int i;
1570 static const DWORD pixel_shader_code[] = {
1571 0xffff0101, /* ps_1_1*/
1572 0x00000042, 0xb00f0000, /* tex t0*/
1573 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1574 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1575 0x0000ffff
1577 static const DWORD double_texbem_code[] = {
1578 0xffff0103, /* ps_1_3 */
1579 0x00000042, 0xb00f0000, /* tex t0 */
1580 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1581 0x00000042, 0xb00f0002, /* tex t2 */
1582 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1583 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1584 0x0000ffff /* end */
1588 static const float quad[][7] = {
1589 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1590 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1591 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1592 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1594 static const float quad_proj[][9] = {
1595 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1596 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1597 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1598 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1601 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1602 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1603 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1604 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1605 D3DDECL_END()
1607 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1608 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1609 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1610 D3DDECL_END()
1611 } };
1613 /* use asymmetric matrix to test loading */
1614 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1616 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1617 IDirect3DPixelShader9 *pixel_shader = NULL;
1618 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1619 D3DLOCKED_RECT locked_rect;
1621 generate_bumpmap_textures(device);
1623 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1624 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1625 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1626 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1627 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1629 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1630 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1632 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1633 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1635 for(i=0; i<2; i++)
1637 if(i)
1639 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1640 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1643 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1644 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1645 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1646 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1648 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1649 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1650 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1651 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1653 hr = IDirect3DDevice9_BeginScene(device);
1654 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1656 if(!i)
1657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1658 else
1659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1660 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1662 hr = IDirect3DDevice9_EndScene(device);
1663 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1665 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1666 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1668 color = getPixelColor(device, 320-32, 240);
1669 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1670 color = getPixelColor(device, 320+32, 240);
1671 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1672 color = getPixelColor(device, 320, 240-32);
1673 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1674 color = getPixelColor(device, 320, 240+32);
1675 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1677 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1678 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1679 IDirect3DPixelShader9_Release(pixel_shader);
1681 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1682 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1683 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1686 /* clean up */
1687 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1688 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1690 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1691 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1693 for(i=0; i<2; i++)
1695 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1696 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1697 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1698 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1699 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1700 IDirect3DTexture9_Release(texture);
1703 /* Test double texbem */
1704 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1705 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1706 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1707 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1708 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1709 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1710 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1711 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1713 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1714 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1715 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1716 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1718 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1719 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1721 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1722 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1723 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1724 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1725 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1726 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1729 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1730 #define tex 0x00ff0000
1731 #define tex1 0x0000ff00
1732 #define origin 0x000000ff
1733 static const DWORD pixel_data[] = {
1734 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1735 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1736 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1737 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1738 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1739 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1740 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1741 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1743 #undef tex1
1744 #undef tex2
1745 #undef origin
1747 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1748 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1749 for(i = 0; i < 8; i++) {
1750 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1752 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1753 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1756 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1757 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1758 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1759 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1760 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1761 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1762 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1763 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1764 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1765 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1766 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1767 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1769 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1770 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1771 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1772 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1773 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1774 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1776 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1777 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1778 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1779 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1780 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1781 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1783 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1784 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1785 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1786 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1787 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1788 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1789 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1790 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1792 hr = IDirect3DDevice9_BeginScene(device);
1793 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1794 if(SUCCEEDED(hr)) {
1795 static const float double_quad[] = {
1796 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1797 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1798 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1799 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1803 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1804 hr = IDirect3DDevice9_EndScene(device);
1805 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1807 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1808 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1809 color = getPixelColor(device, 320, 240);
1810 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1812 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1813 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1814 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1815 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1816 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1817 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1818 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1819 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1820 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1821 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1823 IDirect3DPixelShader9_Release(pixel_shader);
1824 IDirect3DTexture9_Release(texture);
1825 IDirect3DTexture9_Release(texture1);
1826 IDirect3DTexture9_Release(texture2);
1829 static void z_range_test(IDirect3DDevice9 *device)
1831 const struct vertex quad[] =
1833 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1834 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1835 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1836 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1838 const struct vertex quad2[] =
1840 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1841 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1842 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1843 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1846 const struct tvertex quad3[] =
1848 { 0, 240, 1.1f, 1.0, 0xffffff00},
1849 { 0, 480, 1.1f, 1.0, 0xffffff00},
1850 { 640, 240, -1.1f, 1.0, 0xffffff00},
1851 { 640, 480, -1.1f, 1.0, 0xffffff00},
1853 const struct tvertex quad4[] =
1855 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1856 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1857 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1858 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1860 HRESULT hr;
1861 DWORD color;
1862 IDirect3DVertexShader9 *shader;
1863 IDirect3DVertexDeclaration9 *decl;
1864 D3DCAPS9 caps;
1865 const DWORD shader_code[] = {
1866 0xfffe0101, /* vs_1_1 */
1867 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1868 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1869 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1870 0x0000ffff /* end */
1872 static const D3DVERTEXELEMENT9 decl_elements[] = {
1873 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1874 D3DDECL_END()
1876 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1877 * then call Present. Then clear the color buffer to make sure it has some defined content
1878 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1879 * by the depth value.
1881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1882 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1894 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1895 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1897 hr = IDirect3DDevice9_BeginScene(device);
1898 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1899 if(hr == D3D_OK)
1901 /* Test the untransformed vertex path */
1902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1903 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1905 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1907 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1909 /* Test the transformed vertex path */
1910 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1911 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1913 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1914 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1918 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1920 hr = IDirect3DDevice9_EndScene(device);
1921 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1924 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1925 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1927 /* Do not test the exact corner pixels, but go pretty close to them */
1929 /* Clipped because z > 1.0 */
1930 color = getPixelColor(device, 28, 238);
1931 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1932 color = getPixelColor(device, 28, 241);
1933 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1935 /* Not clipped, > z buffer clear value(0.75) */
1936 color = getPixelColor(device, 31, 238);
1937 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1938 color = getPixelColor(device, 31, 241);
1939 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1940 color = getPixelColor(device, 100, 238);
1941 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1942 color = getPixelColor(device, 100, 241);
1943 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1945 /* Not clipped, < z buffer clear value */
1946 color = getPixelColor(device, 104, 238);
1947 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1948 color = getPixelColor(device, 104, 241);
1949 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1950 color = getPixelColor(device, 318, 238);
1951 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1952 color = getPixelColor(device, 318, 241);
1953 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1955 /* Clipped because z < 0.0 */
1956 color = getPixelColor(device, 321, 238);
1957 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1958 color = getPixelColor(device, 321, 241);
1959 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1961 /* Test the shader path */
1962 IDirect3DDevice9_GetDeviceCaps(device, &caps);
1963 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1964 skip("Vertex shaders not supported\n");
1965 goto out;
1967 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1968 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1969 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1970 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1974 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1975 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1976 IDirect3DDevice9_SetVertexShader(device, shader);
1977 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1979 hr = IDirect3DDevice9_BeginScene(device);
1980 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1981 if(hr == D3D_OK)
1983 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1984 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1985 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1987 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1989 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1990 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1992 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1994 hr = IDirect3DDevice9_EndScene(device);
1995 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1998 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1999 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2000 IDirect3DDevice9_SetVertexShader(device, NULL);
2001 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
2003 IDirect3DVertexDeclaration9_Release(decl);
2004 IDirect3DVertexShader9_Release(shader);
2006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2007 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2008 /* Z < 1.0 */
2009 color = getPixelColor(device, 28, 238);
2010 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2012 /* 1.0 < z < 0.75 */
2013 color = getPixelColor(device, 31, 238);
2014 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2015 color = getPixelColor(device, 100, 238);
2016 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2018 /* 0.75 < z < 0.0 */
2019 color = getPixelColor(device, 104, 238);
2020 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2021 color = getPixelColor(device, 318, 238);
2022 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2024 /* 0.0 < z */
2025 color = getPixelColor(device, 321, 238);
2026 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2028 out:
2029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2030 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2033 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2034 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2037 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2039 D3DSURFACE_DESC desc;
2040 D3DLOCKED_RECT l;
2041 HRESULT hr;
2042 unsigned int x, y;
2043 DWORD *mem;
2045 memset(&desc, 0, sizeof(desc));
2046 memset(&l, 0, sizeof(l));
2047 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2048 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2049 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2050 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2051 if(FAILED(hr)) return;
2053 for(y = 0; y < desc.Height; y++)
2055 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2056 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2058 mem[x] = color;
2061 hr = IDirect3DSurface9_UnlockRect(surface);
2062 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2065 /* This tests a variety of possible StretchRect() situations */
2066 static void stretchrect_test(IDirect3DDevice9 *device)
2068 HRESULT hr;
2069 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2070 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2071 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2072 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2073 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2074 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2075 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2076 IDirect3DSurface9 *orig_rt = NULL;
2077 DWORD color;
2079 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2080 ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2081 if(!orig_rt) {
2082 goto out;
2085 /* Create our temporary surfaces in system memory */
2086 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2087 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2088 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2089 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2091 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2092 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2093 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2094 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2095 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2096 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2097 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2099 /* Create render target surfaces */
2100 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2101 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2102 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2103 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2104 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2105 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2107 /* Create render target textures */
2108 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2109 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2110 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2111 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2112 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2113 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2114 if (tex_rt32) {
2115 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2116 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2118 if (tex_rt64) {
2119 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2120 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2122 if (tex_rt_dest64) {
2123 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2124 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2127 /* Create regular textures in D3DPOOL_DEFAULT */
2128 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2129 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2130 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2131 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2132 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2133 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2134 if (tex32) {
2135 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2136 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2138 if (tex64) {
2139 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2140 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2142 if (tex_dest64) {
2143 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2144 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2147 /*********************************************************************
2148 * Tests for when the source parameter is an offscreen plain surface *
2149 *********************************************************************/
2151 /* Fill the offscreen 64x64 surface with green */
2152 if (surf_offscreen64)
2153 fill_surface(surf_offscreen64, 0xff00ff00);
2155 /* offscreenplain ==> offscreenplain, same size */
2156 if(surf_offscreen64 && surf_offscreen_dest64) {
2157 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2158 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2160 if (hr == D3D_OK) {
2161 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2162 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2166 /* offscreenplain ==> rendertarget texture, same size */
2167 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2168 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2169 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2171 /* We can't lock rendertarget textures, so copy to our temp surface first */
2172 if (hr == D3D_OK) {
2173 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2174 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2177 if (hr == D3D_OK) {
2178 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2179 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2183 /* offscreenplain ==> rendertarget surface, same size */
2184 if(surf_offscreen64 && surf_rt_dest64) {
2185 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2186 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2188 if (hr == D3D_OK) {
2189 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2190 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2194 /* offscreenplain ==> texture, same size (should fail) */
2195 if(surf_offscreen64 && surf_tex_dest64) {
2196 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2197 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2200 /* Fill the smaller offscreen surface with red */
2201 fill_surface(surf_offscreen32, 0xffff0000);
2203 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2204 if(surf_offscreen32 && surf_offscreen64) {
2205 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2206 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2209 /* offscreenplain ==> rendertarget texture, scaling */
2210 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2211 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2212 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2214 /* We can't lock rendertarget textures, so copy to our temp surface first */
2215 if (hr == D3D_OK) {
2216 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2217 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2220 if (hr == D3D_OK) {
2221 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2222 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2226 /* offscreenplain ==> rendertarget surface, scaling */
2227 if(surf_offscreen32 && surf_rt_dest64) {
2228 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2229 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2231 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2232 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2235 /* offscreenplain ==> texture, scaling (should fail) */
2236 if(surf_offscreen32 && surf_tex_dest64) {
2237 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2238 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2241 /************************************************************
2242 * Tests for when the source parameter is a regular texture *
2243 ************************************************************/
2245 /* Fill the surface of the regular texture with blue */
2246 if (surf_tex64 && surf_temp64) {
2247 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2248 fill_surface(surf_temp64, 0xff0000ff);
2249 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2250 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2253 /* texture ==> offscreenplain, same size */
2254 if(surf_tex64 && surf_offscreen64) {
2255 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2256 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2259 /* texture ==> rendertarget texture, same size */
2260 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2261 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2262 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2264 /* We can't lock rendertarget textures, so copy to our temp surface first */
2265 if (hr == D3D_OK) {
2266 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2267 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2270 if (hr == D3D_OK) {
2271 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2272 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2276 /* texture ==> rendertarget surface, same size */
2277 if(surf_tex64 && surf_rt_dest64) {
2278 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2279 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2281 if (hr == D3D_OK) {
2282 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2283 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2287 /* texture ==> texture, same size (should fail) */
2288 if(surf_tex64 && surf_tex_dest64) {
2289 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2290 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2293 /* Fill the surface of the smaller regular texture with red */
2294 if (surf_tex32 && surf_temp32) {
2295 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2296 fill_surface(surf_temp32, 0xffff0000);
2297 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2298 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2301 /* texture ==> offscreenplain, scaling (should fail) */
2302 if(surf_tex32 && surf_offscreen64) {
2303 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2304 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2307 /* texture ==> rendertarget texture, scaling */
2308 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2309 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2310 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2312 /* We can't lock rendertarget textures, so copy to our temp surface first */
2313 if (hr == D3D_OK) {
2314 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2315 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2318 if (hr == D3D_OK) {
2319 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2320 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2324 /* texture ==> rendertarget surface, scaling */
2325 if(surf_tex32 && surf_rt_dest64) {
2326 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2327 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2329 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2330 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2333 /* texture ==> texture, scaling (should fail) */
2334 if(surf_tex32 && surf_tex_dest64) {
2335 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2336 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2339 /*****************************************************************
2340 * Tests for when the source parameter is a rendertarget texture *
2341 *****************************************************************/
2343 /* Fill the surface of the rendertarget texture with white */
2344 if (surf_tex_rt64 && surf_temp64) {
2345 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2346 fill_surface(surf_temp64, 0xffffffff);
2347 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2348 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2351 /* rendertarget texture ==> offscreenplain, same size */
2352 if(surf_tex_rt64 && surf_offscreen64) {
2353 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2354 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2357 /* rendertarget texture ==> rendertarget texture, same size */
2358 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2359 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2360 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2362 /* We can't lock rendertarget textures, so copy to our temp surface first */
2363 if (hr == D3D_OK) {
2364 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2365 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2368 if (hr == D3D_OK) {
2369 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2370 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2374 /* rendertarget texture ==> rendertarget surface, same size */
2375 if(surf_tex_rt64 && surf_rt_dest64) {
2376 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2377 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2379 if (hr == D3D_OK) {
2380 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2381 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2385 /* rendertarget texture ==> texture, same size (should fail) */
2386 if(surf_tex_rt64 && surf_tex_dest64) {
2387 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2388 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2391 /* Fill the surface of the smaller rendertarget texture with red */
2392 if (surf_tex_rt32 && surf_temp32) {
2393 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2394 fill_surface(surf_temp32, 0xffff0000);
2395 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2396 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2399 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2400 if(surf_tex_rt32 && surf_offscreen64) {
2401 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2402 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2405 /* rendertarget texture ==> rendertarget texture, scaling */
2406 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2407 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2408 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2410 /* We can't lock rendertarget textures, so copy to our temp surface first */
2411 if (hr == D3D_OK) {
2412 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2413 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2416 if (hr == D3D_OK) {
2417 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2418 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2422 /* rendertarget texture ==> rendertarget surface, scaling */
2423 if(surf_tex_rt32 && surf_rt_dest64) {
2424 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2425 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2427 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2428 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2431 /* rendertarget texture ==> texture, scaling (should fail) */
2432 if(surf_tex_rt32 && surf_tex_dest64) {
2433 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2434 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2437 /*****************************************************************
2438 * Tests for when the source parameter is a rendertarget surface *
2439 *****************************************************************/
2441 /* Fill the surface of the rendertarget surface with black */
2442 if (surf_rt64)
2443 fill_surface(surf_rt64, 0xff000000);
2445 /* rendertarget texture ==> offscreenplain, same size */
2446 if(surf_rt64 && surf_offscreen64) {
2447 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2448 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2451 /* rendertarget surface ==> rendertarget texture, same size */
2452 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2453 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2454 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2456 /* We can't lock rendertarget textures, so copy to our temp surface first */
2457 if (hr == D3D_OK) {
2458 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2459 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2462 if (hr == D3D_OK) {
2463 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2464 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2468 /* rendertarget surface ==> rendertarget surface, same size */
2469 if(surf_rt64 && surf_rt_dest64) {
2470 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2471 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2473 if (hr == D3D_OK) {
2474 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2475 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2479 /* rendertarget surface ==> texture, same size (should fail) */
2480 if(surf_rt64 && surf_tex_dest64) {
2481 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2482 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2485 /* Fill the surface of the smaller rendertarget texture with red */
2486 if (surf_rt32)
2487 fill_surface(surf_rt32, 0xffff0000);
2489 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2490 if(surf_rt32 && surf_offscreen64) {
2491 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2492 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2495 /* rendertarget surface ==> rendertarget texture, scaling */
2496 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2497 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2498 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2500 /* We can't lock rendertarget textures, so copy to our temp surface first */
2501 if (hr == D3D_OK) {
2502 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2503 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2506 if (hr == D3D_OK) {
2507 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2508 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512 /* rendertarget surface ==> rendertarget surface, scaling */
2513 if(surf_rt32 && surf_rt_dest64) {
2514 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2515 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2517 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2518 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2521 /* rendertarget surface ==> texture, scaling (should fail) */
2522 if(surf_rt32 && surf_tex_dest64) {
2523 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2524 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2527 /* TODO: Test when source and destination RECT parameters are given... */
2528 /* TODO: Test format conversions */
2531 out:
2532 /* Clean up */
2533 if (surf_rt32)
2534 IDirect3DSurface9_Release(surf_rt32);
2535 if (surf_rt64)
2536 IDirect3DSurface9_Release(surf_rt64);
2537 if (surf_rt_dest64)
2538 IDirect3DSurface9_Release(surf_rt_dest64);
2539 if (surf_temp32)
2540 IDirect3DSurface9_Release(surf_temp32);
2541 if (surf_temp64)
2542 IDirect3DSurface9_Release(surf_temp64);
2543 if (surf_offscreen32)
2544 IDirect3DSurface9_Release(surf_offscreen32);
2545 if (surf_offscreen64)
2546 IDirect3DSurface9_Release(surf_offscreen64);
2547 if (surf_offscreen_dest64)
2548 IDirect3DSurface9_Release(surf_offscreen_dest64);
2550 if (tex_rt32) {
2551 if (surf_tex_rt32)
2552 IDirect3DSurface9_Release(surf_tex_rt32);
2553 IDirect3DTexture9_Release(tex_rt32);
2555 if (tex_rt64) {
2556 if (surf_tex_rt64)
2557 IDirect3DSurface9_Release(surf_tex_rt64);
2558 IDirect3DTexture9_Release(tex_rt64);
2560 if (tex_rt_dest64) {
2561 if (surf_tex_rt_dest64)
2562 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2563 IDirect3DTexture9_Release(tex_rt_dest64);
2565 if (tex32) {
2566 if (surf_tex32)
2567 IDirect3DSurface9_Release(surf_tex32);
2568 IDirect3DTexture9_Release(tex32);
2570 if (tex64) {
2571 if (surf_tex64)
2572 IDirect3DSurface9_Release(surf_tex64);
2573 IDirect3DTexture9_Release(tex64);
2575 if (tex_dest64) {
2576 if (surf_tex_dest64)
2577 IDirect3DSurface9_Release(surf_tex_dest64);
2578 IDirect3DTexture9_Release(tex_dest64);
2581 if (orig_rt) {
2582 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2583 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2584 IDirect3DSurface9_Release(orig_rt);
2588 static void maxmip_test(IDirect3DDevice9 *device)
2590 IDirect3DTexture9 *texture = NULL;
2591 IDirect3DSurface9 *surface = NULL;
2592 HRESULT hr;
2593 DWORD color;
2594 const float quads[] = {
2595 -1.0, -1.0, 0.0, 0.0, 0.0,
2596 -1.0, 0.0, 0.0, 0.0, 1.0,
2597 0.0, -1.0, 0.0, 1.0, 0.0,
2598 0.0, 0.0, 0.0, 1.0, 1.0,
2600 0.0, -1.0, 0.0, 0.0, 0.0,
2601 0.0, 0.0, 0.0, 0.0, 1.0,
2602 1.0, -1.0, 0.0, 1.0, 0.0,
2603 1.0, 0.0, 0.0, 1.0, 1.0,
2605 0.0, 0.0, 0.0, 0.0, 0.0,
2606 0.0, 1.0, 0.0, 0.0, 1.0,
2607 1.0, 0.0, 0.0, 1.0, 0.0,
2608 1.0, 1.0, 0.0, 1.0, 1.0,
2610 -1.0, 0.0, 0.0, 0.0, 0.0,
2611 -1.0, 1.0, 0.0, 0.0, 1.0,
2612 0.0, 0.0, 0.0, 1.0, 0.0,
2613 0.0, 1.0, 0.0, 1.0, 1.0,
2616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2619 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2620 &texture, NULL);
2621 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2622 if(!texture)
2624 skip("Failed to create test texture\n");
2625 return;
2628 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2629 fill_surface(surface, 0xffff0000);
2630 IDirect3DSurface9_Release(surface);
2631 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2632 fill_surface(surface, 0xff00ff00);
2633 IDirect3DSurface9_Release(surface);
2634 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2635 fill_surface(surface, 0xff0000ff);
2636 IDirect3DSurface9_Release(surface);
2638 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2639 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2640 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2641 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2643 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2644 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2646 hr = IDirect3DDevice9_BeginScene(device);
2647 if(SUCCEEDED(hr))
2649 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2650 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2652 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2654 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2655 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2657 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2659 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2660 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2661 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2662 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2664 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2665 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2666 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2667 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2668 hr = IDirect3DDevice9_EndScene(device);
2671 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2672 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2673 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2674 color = getPixelColor(device, 160, 360);
2675 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2676 color = getPixelColor(device, 160, 120);
2677 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2678 color = getPixelColor(device, 480, 120);
2679 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2680 color = getPixelColor(device, 480, 360);
2681 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2684 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2686 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2687 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2689 hr = IDirect3DDevice9_BeginScene(device);
2690 if(SUCCEEDED(hr))
2692 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2693 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2695 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2697 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2698 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2699 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2700 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2702 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2703 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2705 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2707 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2708 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2710 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2711 hr = IDirect3DDevice9_EndScene(device);
2714 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2715 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2716 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2717 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2719 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2720 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2721 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2722 * samples from the highest level in the texture(level 2)
2724 color = getPixelColor(device, 160, 360);
2725 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2726 color = getPixelColor(device, 160, 120);
2727 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2728 color = getPixelColor(device, 480, 120);
2729 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2730 color = getPixelColor(device, 480, 360);
2731 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2733 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2734 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2735 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2736 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2737 IDirect3DTexture9_Release(texture);
2740 static void release_buffer_test(IDirect3DDevice9 *device)
2742 IDirect3DVertexBuffer9 *vb = NULL;
2743 IDirect3DIndexBuffer9 *ib = NULL;
2744 HRESULT hr;
2745 BYTE *data;
2746 long ref;
2748 static const struct vertex quad[] = {
2749 {-1.0, -1.0, 0.1, 0xffff0000},
2750 {-1.0, 1.0, 0.1, 0xffff0000},
2751 { 1.0, 1.0, 0.1, 0xffff0000},
2753 {-1.0, -1.0, 0.1, 0xff00ff00},
2754 {-1.0, 1.0, 0.1, 0xff00ff00},
2755 { 1.0, 1.0, 0.1, 0xff00ff00}
2757 short indices[] = {3, 4, 5};
2759 /* Index and vertex buffers should always be creatable */
2760 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2761 D3DPOOL_MANAGED, &vb, NULL);
2762 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2763 if(!vb) {
2764 skip("Failed to create a vertex buffer\n");
2765 return;
2767 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2768 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2769 if(!ib) {
2770 skip("Failed to create an index buffer\n");
2771 return;
2774 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2775 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2776 memcpy(data, quad, sizeof(quad));
2777 hr = IDirect3DVertexBuffer9_Unlock(vb);
2778 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2780 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2781 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2782 memcpy(data, indices, sizeof(indices));
2783 hr = IDirect3DIndexBuffer9_Unlock(ib);
2784 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2786 hr = IDirect3DDevice9_SetIndices(device, ib);
2787 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2788 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2789 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2790 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2791 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2793 /* Now destroy the bound index buffer and draw again */
2794 ref = IDirect3DIndexBuffer9_Release(ib);
2795 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2797 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2798 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2800 hr = IDirect3DDevice9_BeginScene(device);
2801 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2802 if(SUCCEEDED(hr))
2804 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2805 * making assumptions about the indices or vertices
2807 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2808 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2809 hr = IDirect3DDevice9_EndScene(device);
2810 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2813 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2814 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2816 hr = IDirect3DDevice9_SetIndices(device, NULL);
2817 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2818 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2819 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2821 /* Index buffer was already destroyed as part of the test */
2822 IDirect3DVertexBuffer9_Release(vb);
2825 static void float_texture_test(IDirect3DDevice9 *device)
2827 IDirect3D9 *d3d = NULL;
2828 HRESULT hr;
2829 IDirect3DTexture9 *texture = NULL;
2830 D3DLOCKED_RECT lr;
2831 float *data;
2832 DWORD color;
2833 float quad[] = {
2834 -1.0, -1.0, 0.1, 0.0, 0.0,
2835 -1.0, 1.0, 0.1, 0.0, 1.0,
2836 1.0, -1.0, 0.1, 1.0, 0.0,
2837 1.0, 1.0, 0.1, 1.0, 1.0,
2840 memset(&lr, 0, sizeof(lr));
2841 IDirect3DDevice9_GetDirect3D(device, &d3d);
2842 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2843 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2844 skip("D3DFMT_R32F textures not supported\n");
2845 goto out;
2848 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2849 D3DPOOL_MANAGED, &texture, NULL);
2850 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2851 if(!texture) {
2852 skip("Failed to create R32F texture\n");
2853 goto out;
2856 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2857 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2858 data = lr.pBits;
2859 *data = 0.0;
2860 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2861 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2863 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2864 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2866 hr = IDirect3DDevice9_BeginScene(device);
2867 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2868 if(SUCCEEDED(hr))
2870 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2871 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2874 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2876 hr = IDirect3DDevice9_EndScene(device);
2877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2879 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2880 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2883 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2885 color = getPixelColor(device, 240, 320);
2886 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2888 out:
2889 if(texture) IDirect3DTexture9_Release(texture);
2890 IDirect3D9_Release(d3d);
2893 static void g16r16_texture_test(IDirect3DDevice9 *device)
2895 IDirect3D9 *d3d = NULL;
2896 HRESULT hr;
2897 IDirect3DTexture9 *texture = NULL;
2898 D3DLOCKED_RECT lr;
2899 DWORD *data;
2900 DWORD color, red, green, blue;
2901 float quad[] = {
2902 -1.0, -1.0, 0.1, 0.0, 0.0,
2903 -1.0, 1.0, 0.1, 0.0, 1.0,
2904 1.0, -1.0, 0.1, 1.0, 0.0,
2905 1.0, 1.0, 0.1, 1.0, 1.0,
2908 memset(&lr, 0, sizeof(lr));
2909 IDirect3DDevice9_GetDirect3D(device, &d3d);
2910 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2911 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2912 skip("D3DFMT_G16R16 textures not supported\n");
2913 goto out;
2916 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2917 D3DPOOL_MANAGED, &texture, NULL);
2918 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2919 if(!texture) {
2920 skip("Failed to create D3DFMT_G16R16 texture\n");
2921 goto out;
2924 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2925 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2926 data = lr.pBits;
2927 *data = 0x0f00f000;
2928 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2929 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2931 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2932 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2934 hr = IDirect3DDevice9_BeginScene(device);
2935 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2936 if(SUCCEEDED(hr))
2938 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2939 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2942 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2944 hr = IDirect3DDevice9_EndScene(device);
2945 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2947 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2948 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2950 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2951 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2953 color = getPixelColor(device, 240, 320);
2954 red = (color & 0x00ff0000) >> 16;
2955 green = (color & 0x0000ff00) >> 8;
2956 blue = (color & 0x000000ff) >> 0;
2957 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2958 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2960 out:
2961 if(texture) IDirect3DTexture9_Release(texture);
2962 IDirect3D9_Release(d3d);
2965 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2967 HRESULT hr;
2968 IDirect3D9 *d3d;
2969 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2970 D3DCAPS9 caps;
2971 IDirect3DTexture9 *texture = NULL;
2972 IDirect3DVolumeTexture9 *volume = NULL;
2973 unsigned int x, y, z;
2974 D3DLOCKED_RECT lr;
2975 D3DLOCKED_BOX lb;
2976 DWORD color;
2977 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2978 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2979 0.0, 1.0, 0.0, 0.0,
2980 0.0, 0.0, 1.0, 0.0,
2981 0.0, 0.0, 0.0, 1.0};
2982 static const D3DVERTEXELEMENT9 decl_elements[] = {
2983 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2984 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2985 D3DDECL_END()
2987 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2988 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2989 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2990 D3DDECL_END()
2992 static const D3DVERTEXELEMENT9 decl_elements3[] = {
2993 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2994 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2995 D3DDECL_END()
2997 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2998 0x00, 0xff, 0x00, 0x00,
2999 0x00, 0x00, 0x00, 0x00,
3000 0x00, 0x00, 0x00, 0x00};
3002 memset(&lr, 0, sizeof(lr));
3003 memset(&lb, 0, sizeof(lb));
3004 IDirect3DDevice9_GetDirect3D(device, &d3d);
3005 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3006 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3007 fmt = D3DFMT_A16B16G16R16;
3009 IDirect3D9_Release(d3d);
3011 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3012 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3013 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3015 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3016 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3017 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3018 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
3019 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3020 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
3021 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3022 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3023 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3024 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3025 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3026 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3027 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3028 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3029 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3030 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3034 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3036 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3037 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3038 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3039 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3040 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3041 if(!texture) {
3042 skip("Failed to create the test texture\n");
3043 return;
3046 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3047 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3048 * 1.0 in red and green for the x and y coords
3050 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3051 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3052 for(y = 0; y < caps.MaxTextureHeight; y++) {
3053 for(x = 0; x < caps.MaxTextureWidth; x++) {
3054 double r_f = (double) y / (double) caps.MaxTextureHeight;
3055 double g_f = (double) x / (double) caps.MaxTextureWidth;
3056 if(fmt == D3DFMT_A16B16G16R16) {
3057 unsigned short r, g;
3058 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3059 r = (unsigned short) (r_f * 65536.0);
3060 g = (unsigned short) (g_f * 65536.0);
3061 dst[0] = r;
3062 dst[1] = g;
3063 dst[2] = 0;
3064 dst[3] = 65535;
3065 } else {
3066 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3067 unsigned char r = (unsigned char) (r_f * 255.0);
3068 unsigned char g = (unsigned char) (g_f * 255.0);
3069 dst[0] = 0;
3070 dst[1] = g;
3071 dst[2] = r;
3072 dst[3] = 255;
3076 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3077 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3078 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3079 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3082 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3083 hr = IDirect3DDevice9_BeginScene(device);
3084 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3085 if(SUCCEEDED(hr))
3087 float quad1[] = {
3088 -1.0, -1.0, 0.1, 1.0, 1.0,
3089 -1.0, 0.0, 0.1, 1.0, 1.0,
3090 0.0, -1.0, 0.1, 1.0, 1.0,
3091 0.0, 0.0, 0.1, 1.0, 1.0,
3093 float quad2[] = {
3094 -1.0, 0.0, 0.1, 1.0, 1.0,
3095 -1.0, 1.0, 0.1, 1.0, 1.0,
3096 0.0, 0.0, 0.1, 1.0, 1.0,
3097 0.0, 1.0, 0.1, 1.0, 1.0,
3099 float quad3[] = {
3100 0.0, 0.0, 0.1, 0.5, 0.5,
3101 0.0, 1.0, 0.1, 0.5, 0.5,
3102 1.0, 0.0, 0.1, 0.5, 0.5,
3103 1.0, 1.0, 0.1, 0.5, 0.5,
3105 float quad4[] = {
3106 320, 480, 0.1, 1.0, 0.0, 1.0,
3107 320, 240, 0.1, 1.0, 0.0, 1.0,
3108 640, 480, 0.1, 1.0, 0.0, 1.0,
3109 640, 240, 0.1, 1.0, 0.0, 1.0,
3111 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3112 0.0, 0.0, 0.0, 0.0,
3113 0.0, 0.0, 0.0, 0.0,
3114 0.0, 0.0, 0.0, 0.0};
3116 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3117 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3118 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3119 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3120 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3122 /* What happens with transforms enabled? */
3123 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3124 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3126 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3128 /* What happens if 4 coords are used, but only 2 given ?*/
3129 mat[8] = 1.0;
3130 mat[13] = 1.0;
3131 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3133 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3134 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3136 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3138 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3139 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3140 * due to the coords in the vertices. (turns out red, indeed)
3142 memset(mat, 0, sizeof(mat));
3143 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3145 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3146 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3148 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3150 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3152 hr = IDirect3DDevice9_EndScene(device);
3153 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3156 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3157 color = getPixelColor(device, 160, 360);
3158 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3159 color = getPixelColor(device, 160, 120);
3160 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3161 color = getPixelColor(device, 480, 120);
3162 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3163 color = getPixelColor(device, 480, 360);
3164 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3166 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3167 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3169 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3170 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3171 hr = IDirect3DDevice9_BeginScene(device);
3172 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3173 if(SUCCEEDED(hr))
3175 float quad1[] = {
3176 -1.0, -1.0, 0.1, 0.8, 0.2,
3177 -1.0, 0.0, 0.1, 0.8, 0.2,
3178 0.0, -1.0, 0.1, 0.8, 0.2,
3179 0.0, 0.0, 0.1, 0.8, 0.2,
3181 float quad2[] = {
3182 -1.0, 0.0, 0.1, 0.5, 1.0,
3183 -1.0, 1.0, 0.1, 0.5, 1.0,
3184 0.0, 0.0, 0.1, 0.5, 1.0,
3185 0.0, 1.0, 0.1, 0.5, 1.0,
3187 float quad3[] = {
3188 0.0, 0.0, 0.1, 0.5, 1.0,
3189 0.0, 1.0, 0.1, 0.5, 1.0,
3190 1.0, 0.0, 0.1, 0.5, 1.0,
3191 1.0, 1.0, 0.1, 0.5, 1.0,
3193 float quad4[] = {
3194 0.0, -1.0, 0.1, 0.8, 0.2,
3195 0.0, 0.0, 0.1, 0.8, 0.2,
3196 1.0, -1.0, 0.1, 0.8, 0.2,
3197 1.0, 0.0, 0.1, 0.8, 0.2,
3199 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3200 0.0, 0.0, 0.0, 0.0,
3201 0.0, 1.0, 0.0, 0.0,
3202 0.0, 0.0, 0.0, 0.0};
3204 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3206 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3207 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3208 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3209 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3212 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3214 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3215 * it behaves like COUNT2 because normal textures require 2 coords
3217 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3218 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3220 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3222 /* Just to be sure, the same as quad2 above */
3223 memset(mat, 0, sizeof(mat));
3224 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3225 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3226 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3227 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3229 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3231 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3232 * used? And what happens to the first?
3234 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3237 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3239 hr = IDirect3DDevice9_EndScene(device);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3243 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3244 color = getPixelColor(device, 160, 360);
3245 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3246 color = getPixelColor(device, 160, 120);
3247 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3248 color = getPixelColor(device, 480, 120);
3249 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3250 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3251 color = getPixelColor(device, 480, 360);
3252 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3253 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3255 IDirect3DTexture9_Release(texture);
3257 /* Test projected textures, without any fancy matrices */
3258 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3259 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3260 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3262 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3264 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3265 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3267 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3268 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3269 for(x = 0; x < 4; x++) {
3270 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3272 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3273 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3277 hr = IDirect3DDevice9_BeginScene(device);
3278 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3279 if(SUCCEEDED(hr))
3281 const float proj_quads[] = {
3282 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3283 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3284 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3285 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3286 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3287 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3288 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3289 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3292 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3293 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3295 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3297 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3298 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3302 hr = IDirect3DDevice9_EndScene(device);
3303 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3306 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3307 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3308 IDirect3DTexture9_Release(texture);
3310 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3311 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3312 color = getPixelColor(device, 158, 118);
3313 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3314 color = getPixelColor(device, 162, 118);
3315 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3316 color = getPixelColor(device, 158, 122);
3317 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3318 color = getPixelColor(device, 162, 122);
3319 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3321 color = getPixelColor(device, 158, 178);
3322 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3323 color = getPixelColor(device, 162, 178);
3324 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3325 color = getPixelColor(device, 158, 182);
3326 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3327 color = getPixelColor(device, 162, 182);
3328 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3330 color = getPixelColor(device, 318, 118);
3331 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3332 color = getPixelColor(device, 322, 118);
3333 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3334 color = getPixelColor(device, 318, 122);
3335 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3336 color = getPixelColor(device, 322, 122);
3337 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3339 color = getPixelColor(device, 318, 178);
3340 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3341 color = getPixelColor(device, 322, 178);
3342 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3343 color = getPixelColor(device, 318, 182);
3344 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3345 color = getPixelColor(device, 322, 182);
3346 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3348 color = getPixelColor(device, 238, 298);
3349 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3350 color = getPixelColor(device, 242, 298);
3351 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3352 color = getPixelColor(device, 238, 302);
3353 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3354 color = getPixelColor(device, 242, 302);
3355 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3357 color = getPixelColor(device, 238, 388);
3358 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3359 color = getPixelColor(device, 242, 388);
3360 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3361 color = getPixelColor(device, 238, 392);
3362 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3363 color = getPixelColor(device, 242, 392);
3364 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3366 color = getPixelColor(device, 478, 298);
3367 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3368 color = getPixelColor(device, 482, 298);
3369 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3370 color = getPixelColor(device, 478, 302);
3371 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3372 color = getPixelColor(device, 482, 302);
3373 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3375 color = getPixelColor(device, 478, 388);
3376 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3377 color = getPixelColor(device, 482, 388);
3378 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3379 color = getPixelColor(device, 478, 392);
3380 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3381 color = getPixelColor(device, 482, 392);
3382 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3384 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3385 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3386 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3387 * Thus watch out if sampling from texels between 0 and 1.
3389 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3390 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3391 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3392 if(!volume) {
3393 skip("Failed to create a volume texture\n");
3394 goto out;
3397 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3398 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3399 for(z = 0; z < 32; z++) {
3400 for(y = 0; y < 32; y++) {
3401 for(x = 0; x < 32; x++) {
3402 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3403 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3404 float r_f = (float) x / 31.0;
3405 float g_f = (float) y / 31.0;
3406 float b_f = (float) z / 31.0;
3408 if(fmt == D3DFMT_A16B16G16R16) {
3409 unsigned short *mem_s = mem;
3410 mem_s[0] = r_f * 65535.0;
3411 mem_s[1] = g_f * 65535.0;
3412 mem_s[2] = b_f * 65535.0;
3413 mem_s[3] = 65535;
3414 } else {
3415 unsigned char *mem_c = mem;
3416 mem_c[0] = b_f * 255.0;
3417 mem_c[1] = g_f * 255.0;
3418 mem_c[2] = r_f * 255.0;
3419 mem_c[3] = 255;
3424 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3425 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3427 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3428 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3430 hr = IDirect3DDevice9_BeginScene(device);
3431 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3432 if(SUCCEEDED(hr))
3434 float quad1[] = {
3435 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3436 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3437 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3438 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3440 float quad2[] = {
3441 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3442 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3443 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3444 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3446 float quad3[] = {
3447 0.0, 0.0, 0.1, 0.0, 0.0,
3448 0.0, 1.0, 0.1, 0.0, 0.0,
3449 1.0, 0.0, 0.1, 0.0, 0.0,
3450 1.0, 1.0, 0.1, 0.0, 0.0
3452 float quad4[] = {
3453 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3454 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3455 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3456 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3458 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3459 0.0, 0.0, 1.0, 0.0,
3460 0.0, 1.0, 0.0, 0.0,
3461 0.0, 0.0, 0.0, 1.0};
3462 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3465 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3466 * values
3468 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3470 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3471 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3473 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3475 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3476 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3477 * otherwise the w will be missing(blue).
3478 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3479 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3481 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3482 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3484 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3486 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3487 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3489 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3490 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3491 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3492 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3494 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3496 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3497 * disable. ATI extends it up to the amount of values needed for the volume texture
3499 memset(mat, 0, sizeof(mat));
3500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3502 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3503 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3504 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3507 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3509 hr = IDirect3DDevice9_EndScene(device);
3510 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3512 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3513 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3515 color = getPixelColor(device, 160, 360);
3516 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3517 color = getPixelColor(device, 160, 120);
3518 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3519 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3520 color = getPixelColor(device, 480, 120);
3521 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3522 color = getPixelColor(device, 480, 360);
3523 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3525 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3526 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3527 hr = IDirect3DDevice9_BeginScene(device);
3528 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3529 if(SUCCEEDED(hr))
3531 float quad1[] = {
3532 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3533 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3534 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3535 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3537 float quad2[] = {
3538 -1.0, 0.0, 0.1,
3539 -1.0, 1.0, 0.1,
3540 0.0, 0.0, 0.1,
3541 0.0, 1.0, 0.1,
3543 float quad3[] = {
3544 0.0, 0.0, 0.1, 1.0,
3545 0.0, 1.0, 0.1, 1.0,
3546 1.0, 0.0, 0.1, 1.0,
3547 1.0, 1.0, 0.1, 1.0
3549 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3550 0.0, 0.0, 0.0, 0.0,
3551 0.0, 0.0, 0.0, 0.0,
3552 0.0, 1.0, 0.0, 0.0};
3553 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3554 1.0, 0.0, 0.0, 0.0,
3555 0.0, 1.0, 0.0, 0.0,
3556 0.0, 0.0, 1.0, 0.0};
3557 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3558 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3560 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3562 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3563 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3564 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3565 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3567 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3569 /* None passed */
3570 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3575 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3577 /* 4 used, 1 passed */
3578 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3580 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3581 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3583 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3585 hr = IDirect3DDevice9_EndScene(device);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3588 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3589 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3590 color = getPixelColor(device, 160, 360);
3591 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3592 color = getPixelColor(device, 160, 120);
3593 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3594 color = getPixelColor(device, 480, 120);
3595 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3596 /* Quad4: unused */
3598 IDirect3DVolumeTexture9_Release(volume);
3600 out:
3601 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3602 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3603 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3604 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3605 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3606 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3607 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3608 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3609 IDirect3DVertexDeclaration9_Release(decl);
3610 IDirect3DVertexDeclaration9_Release(decl2);
3611 IDirect3DVertexDeclaration9_Release(decl3);
3614 static void texdepth_test(IDirect3DDevice9 *device)
3616 IDirect3DPixelShader9 *shader;
3617 HRESULT hr;
3618 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3619 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3620 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3621 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3622 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3623 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3624 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3625 DWORD shader_code[] = {
3626 0xffff0104, /* ps_1_4 */
3627 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3628 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3629 0x0000fffd, /* phase */
3630 0x00000057, 0x800f0005, /* texdepth r5 */
3631 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3632 0x0000ffff /* end */
3634 DWORD color;
3635 float vertex[] = {
3636 -1.0, -1.0, 0.0,
3637 1.0, -1.0, 1.0,
3638 -1.0, 1.0, 0.0,
3639 1.0, 1.0, 1.0
3642 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3643 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3646 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3652 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3653 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3655 /* Fill the depth buffer with a gradient */
3656 hr = IDirect3DDevice9_BeginScene(device);
3657 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3658 if(SUCCEEDED(hr))
3660 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3661 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3662 hr = IDirect3DDevice9_EndScene(device);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3666 /* Now perform the actual tests. Same geometry, but with the shader */
3667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3670 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3671 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3674 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3676 hr = IDirect3DDevice9_BeginScene(device);
3677 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3678 if(SUCCEEDED(hr))
3680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3681 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3683 hr = IDirect3DDevice9_EndScene(device);
3684 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3687 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3688 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3689 color = getPixelColor(device, 158, 240);
3690 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3691 color = getPixelColor(device, 162, 240);
3692 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3696 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3697 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3698 hr = IDirect3DDevice9_BeginScene(device);
3699 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3700 if(SUCCEEDED(hr))
3702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3703 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3705 hr = IDirect3DDevice9_EndScene(device);
3706 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3709 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3710 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3711 color = getPixelColor(device, 318, 240);
3712 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3713 color = getPixelColor(device, 322, 240);
3714 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3718 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3720 hr = IDirect3DDevice9_BeginScene(device);
3721 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3722 if(SUCCEEDED(hr))
3724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3725 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3727 hr = IDirect3DDevice9_EndScene(device);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3730 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3733 color = getPixelColor(device, 1, 240);
3734 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3736 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3738 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3739 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3740 hr = IDirect3DDevice9_BeginScene(device);
3741 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3742 if(SUCCEEDED(hr))
3744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3745 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3747 hr = IDirect3DDevice9_EndScene(device);
3748 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3750 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3752 color = getPixelColor(device, 318, 240);
3753 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3754 color = getPixelColor(device, 322, 240);
3755 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3757 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3759 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3761 hr = IDirect3DDevice9_BeginScene(device);
3762 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3763 if(SUCCEEDED(hr))
3765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3766 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3768 hr = IDirect3DDevice9_EndScene(device);
3769 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3771 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3772 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3774 color = getPixelColor(device, 1, 240);
3775 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3779 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3781 hr = IDirect3DDevice9_BeginScene(device);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3783 if(SUCCEEDED(hr))
3785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3786 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3788 hr = IDirect3DDevice9_EndScene(device);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3791 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3792 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3794 color = getPixelColor(device, 638, 240);
3795 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3797 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3799 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3801 hr = IDirect3DDevice9_BeginScene(device);
3802 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3803 if(SUCCEEDED(hr))
3805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3806 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3808 hr = IDirect3DDevice9_EndScene(device);
3809 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3812 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3814 color = getPixelColor(device, 638, 240);
3815 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3817 /* Cleanup */
3818 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3819 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3820 IDirect3DPixelShader9_Release(shader);
3822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3823 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3825 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3828 static void texkill_test(IDirect3DDevice9 *device)
3830 IDirect3DPixelShader9 *shader;
3831 HRESULT hr;
3832 DWORD color;
3834 const float vertex[] = {
3835 /* bottom top right left */
3836 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3837 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3838 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3839 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3842 DWORD shader_code_11[] = {
3843 0xffff0101, /* ps_1_1 */
3844 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3845 0x00000041, 0xb00f0000, /* texkill t0 */
3846 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3847 0x0000ffff /* end */
3849 DWORD shader_code_20[] = {
3850 0xffff0200, /* ps_2_0 */
3851 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3852 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3853 0x01000041, 0xb00f0000, /* texkill t0 */
3854 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3855 0x0000ffff /* end */
3858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3859 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3860 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3863 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3865 hr = IDirect3DDevice9_BeginScene(device);
3866 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3867 if(SUCCEEDED(hr))
3869 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3870 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3872 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3873 hr = IDirect3DDevice9_EndScene(device);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3876 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3878 color = getPixelColor(device, 63, 46);
3879 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3880 color = getPixelColor(device, 66, 46);
3881 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3882 color = getPixelColor(device, 63, 49);
3883 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3884 color = getPixelColor(device, 66, 49);
3885 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3887 color = getPixelColor(device, 578, 46);
3888 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3889 color = getPixelColor(device, 575, 46);
3890 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3891 color = getPixelColor(device, 578, 49);
3892 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3893 color = getPixelColor(device, 575, 49);
3894 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3896 color = getPixelColor(device, 63, 430);
3897 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3898 color = getPixelColor(device, 63, 433);
3899 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3900 color = getPixelColor(device, 66, 433);
3901 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3902 color = getPixelColor(device, 66, 430);
3903 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3905 color = getPixelColor(device, 578, 430);
3906 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3907 color = getPixelColor(device, 578, 433);
3908 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3909 color = getPixelColor(device, 575, 433);
3910 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3911 color = getPixelColor(device, 575, 430);
3912 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3914 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3915 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3916 IDirect3DPixelShader9_Release(shader);
3918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3919 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3920 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3921 if(FAILED(hr)) {
3922 skip("Failed to create 2.0 test shader, most likely not supported\n");
3923 return;
3926 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3927 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3928 hr = IDirect3DDevice9_BeginScene(device);
3929 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3930 if(SUCCEEDED(hr))
3932 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3933 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3934 hr = IDirect3DDevice9_EndScene(device);
3935 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3937 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3939 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3940 color = getPixelColor(device, 63, 46);
3941 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3942 color = getPixelColor(device, 66, 46);
3943 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3944 color = getPixelColor(device, 63, 49);
3945 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3946 color = getPixelColor(device, 66, 49);
3947 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3949 color = getPixelColor(device, 578, 46);
3950 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3951 color = getPixelColor(device, 575, 46);
3952 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3953 color = getPixelColor(device, 578, 49);
3954 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3955 color = getPixelColor(device, 575, 49);
3956 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3958 color = getPixelColor(device, 63, 430);
3959 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3960 color = getPixelColor(device, 63, 433);
3961 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3962 color = getPixelColor(device, 66, 433);
3963 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3964 color = getPixelColor(device, 66, 430);
3965 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3967 color = getPixelColor(device, 578, 430);
3968 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3969 color = getPixelColor(device, 578, 433);
3970 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3971 color = getPixelColor(device, 575, 433);
3972 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3973 color = getPixelColor(device, 575, 430);
3974 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3976 /* Cleanup */
3977 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3978 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3979 IDirect3DPixelShader9_Release(shader);
3982 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3984 IDirect3D9 *d3d9;
3985 HRESULT hr;
3986 IDirect3DTexture9 *texture;
3987 IDirect3DPixelShader9 *shader;
3988 IDirect3DPixelShader9 *shader2;
3989 D3DLOCKED_RECT lr;
3990 DWORD color;
3991 DWORD shader_code[] = {
3992 0xffff0101, /* ps_1_1 */
3993 0x00000042, 0xb00f0000, /* tex t0 */
3994 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3995 0x0000ffff /* end */
3997 DWORD shader_code2[] = {
3998 0xffff0101, /* ps_1_1 */
3999 0x00000042, 0xb00f0000, /* tex t0 */
4000 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4001 0x0000ffff /* end */
4004 float quad[] = {
4005 -1.0, -1.0, 0.1, 0.5, 0.5,
4006 1.0, -1.0, 0.1, 0.5, 0.5,
4007 -1.0, 1.0, 0.1, 0.5, 0.5,
4008 1.0, 1.0, 0.1, 0.5, 0.5,
4011 memset(&lr, 0, sizeof(lr));
4012 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4013 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4014 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4015 IDirect3D9_Release(d3d9);
4016 if(FAILED(hr)) {
4017 skip("No D3DFMT_X8L8V8U8 support\n");
4020 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4023 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4025 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4026 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4027 *((DWORD *) lr.pBits) = 0x11ca3141;
4028 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4029 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4031 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4033 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4034 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4036 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4038 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4040 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4041 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4043 hr = IDirect3DDevice9_BeginScene(device);
4044 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4045 if(SUCCEEDED(hr))
4047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4048 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4050 hr = IDirect3DDevice9_EndScene(device);
4051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4053 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4054 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4055 color = getPixelColor(device, 578, 430);
4056 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4057 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4059 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4061 hr = IDirect3DDevice9_BeginScene(device);
4062 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4063 if(SUCCEEDED(hr))
4065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4066 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4068 hr = IDirect3DDevice9_EndScene(device);
4069 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4072 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4073 color = getPixelColor(device, 578, 430);
4074 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4076 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4077 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4078 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4079 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4080 IDirect3DPixelShader9_Release(shader);
4081 IDirect3DPixelShader9_Release(shader2);
4082 IDirect3DTexture9_Release(texture);
4085 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4087 HRESULT hr;
4088 IDirect3D9 *d3d;
4089 IDirect3DTexture9 *texture = NULL;
4090 IDirect3DSurface9 *surface;
4091 DWORD color;
4092 const RECT r1 = {256, 256, 512, 512};
4093 const RECT r2 = {512, 256, 768, 512};
4094 const RECT r3 = {256, 512, 512, 768};
4095 const RECT r4 = {512, 512, 768, 768};
4096 unsigned int x, y;
4097 D3DLOCKED_RECT lr;
4098 memset(&lr, 0, sizeof(lr));
4100 IDirect3DDevice9_GetDirect3D(device, &d3d);
4101 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4102 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4103 skip("No autogenmipmap support\n");
4104 IDirect3D9_Release(d3d);
4105 return;
4107 IDirect3D9_Release(d3d);
4109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4112 /* Make the mipmap big, so that a smaller mipmap is used
4114 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4115 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4118 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4119 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4120 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4121 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4122 for(y = 0; y < 1024; y++) {
4123 for(x = 0; x < 1024; x++) {
4124 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4125 POINT pt;
4127 pt.x = x;
4128 pt.y = y;
4129 if(PtInRect(&r1, pt)) {
4130 *dst = 0xffff0000;
4131 } else if(PtInRect(&r2, pt)) {
4132 *dst = 0xff00ff00;
4133 } else if(PtInRect(&r3, pt)) {
4134 *dst = 0xff0000ff;
4135 } else if(PtInRect(&r4, pt)) {
4136 *dst = 0xff000000;
4137 } else {
4138 *dst = 0xffffffff;
4142 hr = IDirect3DSurface9_UnlockRect(surface);
4143 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4144 IDirect3DSurface9_Release(surface);
4146 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4148 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4149 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4151 hr = IDirect3DDevice9_BeginScene(device);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4153 if(SUCCEEDED(hr)) {
4154 const float quad[] = {
4155 -0.5, -0.5, 0.1, 0.0, 0.0,
4156 -0.5, 0.5, 0.1, 0.0, 1.0,
4157 0.5, -0.5, 0.1, 1.0, 0.0,
4158 0.5, 0.5, 0.1, 1.0, 1.0
4161 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4164 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4165 hr = IDirect3DDevice9_EndScene(device);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4168 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4169 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4172 IDirect3DTexture9_Release(texture);
4174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4175 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4176 color = getPixelColor(device, 200, 200);
4177 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4178 color = getPixelColor(device, 280, 200);
4179 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4180 color = getPixelColor(device, 360, 200);
4181 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4182 color = getPixelColor(device, 440, 200);
4183 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4184 color = getPixelColor(device, 200, 270);
4185 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4186 color = getPixelColor(device, 280, 270);
4187 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4188 color = getPixelColor(device, 360, 270);
4189 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4190 color = getPixelColor(device, 440, 270);
4191 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4194 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4196 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4197 IDirect3DVertexDeclaration9 *decl;
4198 HRESULT hr;
4199 DWORD color;
4200 DWORD shader_code_11[] = {
4201 0xfffe0101, /* vs_1_1 */
4202 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4203 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4204 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4205 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4206 0x0000ffff /* end */
4208 DWORD shader_code_11_2[] = {
4209 0xfffe0101, /* vs_1_1 */
4210 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4211 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4212 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4213 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4214 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4215 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4216 0x0000ffff /* end */
4218 DWORD shader_code_20[] = {
4219 0xfffe0200, /* vs_2_0 */
4220 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4221 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4222 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4223 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4224 0x0000ffff /* end */
4226 DWORD shader_code_20_2[] = {
4227 0xfffe0200, /* vs_2_0 */
4228 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4229 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4230 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4231 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4232 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4233 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4234 0x0000ffff /* end */
4236 static const D3DVERTEXELEMENT9 decl_elements[] = {
4237 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4238 D3DDECL_END()
4240 float quad1[] = {
4241 -1.0, -1.0, 0.1,
4242 0.0, -1.0, 0.1,
4243 -1.0, 0.0, 0.1,
4244 0.0, 0.0, 0.1
4246 float quad2[] = {
4247 0.0, -1.0, 0.1,
4248 1.0, -1.0, 0.1,
4249 0.0, 0.0, 0.1,
4250 1.0, 0.0, 0.1
4252 float quad3[] = {
4253 0.0, 0.0, 0.1,
4254 1.0, 0.0, 0.1,
4255 0.0, 1.0, 0.1,
4256 1.0, 1.0, 0.1
4258 float quad4[] = {
4259 -1.0, 0.0, 0.1,
4260 0.0, 0.0, 0.1,
4261 -1.0, 1.0, 0.1,
4262 0.0, 1.0, 0.1
4264 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4265 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4267 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4270 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4272 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4273 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4274 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4275 if(FAILED(hr)) shader_20 = NULL;
4276 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4277 if(FAILED(hr)) shader_20_2 = NULL;
4278 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4279 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4281 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4283 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4284 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4285 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4286 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4288 hr = IDirect3DDevice9_BeginScene(device);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4290 if(SUCCEEDED(hr))
4292 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4293 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4295 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4297 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4298 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4300 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4302 if(shader_20) {
4303 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4306 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4309 if(shader_20_2) {
4310 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4312 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4313 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4316 hr = IDirect3DDevice9_EndScene(device);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4319 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4320 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4322 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4323 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4324 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4327 color = getPixelColor(device, 160, 360);
4328 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4330 color = getPixelColor(device, 480, 360);
4331 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4332 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4333 if(shader_20) {
4334 color = getPixelColor(device, 160, 120);
4335 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4336 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4338 if(shader_20_2) {
4339 color = getPixelColor(device, 480, 120);
4340 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4341 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4344 IDirect3DVertexDeclaration9_Release(decl);
4345 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4346 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4347 IDirect3DVertexShader9_Release(shader_11_2);
4348 IDirect3DVertexShader9_Release(shader_11);
4351 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4353 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4354 HRESULT hr;
4355 DWORD color;
4356 DWORD shader_code_11[] = {
4357 0xffff0101, /* ps_1_1 */
4358 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4359 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4360 0x0000ffff /* end */
4362 DWORD shader_code_12[] = {
4363 0xffff0102, /* ps_1_2 */
4364 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4365 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4366 0x0000ffff /* end */
4368 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4369 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4370 * During development of this test, 1.3 shaders were verified too
4372 DWORD shader_code_14[] = {
4373 0xffff0104, /* ps_1_4 */
4374 /* Try to make one constant local. It gets clamped too, although the binary contains
4375 * the bigger numbers
4377 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4378 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4379 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4380 0x0000ffff /* end */
4382 DWORD shader_code_20[] = {
4383 0xffff0200, /* ps_2_0 */
4384 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4385 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4386 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4387 0x0000ffff /* end */
4389 float quad1[] = {
4390 -1.0, -1.0, 0.1,
4391 0.0, -1.0, 0.1,
4392 -1.0, 0.0, 0.1,
4393 0.0, 0.0, 0.1
4395 float quad2[] = {
4396 0.0, -1.0, 0.1,
4397 1.0, -1.0, 0.1,
4398 0.0, 0.0, 0.1,
4399 1.0, 0.0, 0.1
4401 float quad3[] = {
4402 0.0, 0.0, 0.1,
4403 1.0, 0.0, 0.1,
4404 0.0, 1.0, 0.1,
4405 1.0, 1.0, 0.1
4407 float quad4[] = {
4408 -1.0, 0.0, 0.1,
4409 0.0, 0.0, 0.1,
4410 -1.0, 1.0, 0.1,
4411 0.0, 1.0, 0.1
4413 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4414 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4419 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4420 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4421 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4422 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4423 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4424 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4425 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4426 if(FAILED(hr)) shader_20 = NULL;
4428 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4429 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4430 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4431 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4435 hr = IDirect3DDevice9_BeginScene(device);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4437 if(SUCCEEDED(hr))
4439 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4440 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4442 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4444 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4445 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4447 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4449 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4450 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4452 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4454 if(shader_20) {
4455 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4456 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4458 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4461 hr = IDirect3DDevice9_EndScene(device);
4462 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4465 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4467 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4468 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4470 color = getPixelColor(device, 160, 360);
4471 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4472 "quad 1 has color %08x, expected 0x00808000\n", color);
4473 color = getPixelColor(device, 480, 360);
4474 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4475 "quad 2 has color %08x, expected 0x00808000\n", color);
4476 color = getPixelColor(device, 480, 120);
4477 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4478 "quad 3 has color %08x, expected 0x00808000\n", color);
4479 if(shader_20) {
4480 color = getPixelColor(device, 160, 120);
4481 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4482 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4485 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4486 IDirect3DPixelShader9_Release(shader_14);
4487 IDirect3DPixelShader9_Release(shader_12);
4488 IDirect3DPixelShader9_Release(shader_11);
4491 static void dp2add_ps_test(IDirect3DDevice9 *device)
4493 IDirect3DPixelShader9 *shader_dp2add = NULL;
4494 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4495 HRESULT hr;
4496 DWORD color;
4498 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4499 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4500 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4501 * r0 first.
4502 * The result here for the r,g,b components should be roughly 0.5:
4503 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4504 static const DWORD shader_code_dp2add[] = {
4505 0xffff0200, /* ps_2_0 */
4506 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4508 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4509 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4511 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4512 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4513 0x0000ffff /* end */
4516 /* Test the _sat modifier, too. Result here should be:
4517 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4518 * _SAT: ==> 1.0
4519 * ADD: (1.0 + -0.5) = 0.5
4521 static const DWORD shader_code_dp2add_sat[] = {
4522 0xffff0200, /* ps_2_0 */
4523 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4525 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4526 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4527 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4529 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4530 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4531 0x0000ffff /* end */
4534 const float quad[] = {
4535 -1.0, -1.0, 0.1,
4536 1.0, -1.0, 0.1,
4537 -1.0, 1.0, 0.1,
4538 1.0, 1.0, 0.1
4542 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4543 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4545 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4546 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4548 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4549 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4551 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4554 if (shader_dp2add) {
4556 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4559 hr = IDirect3DDevice9_BeginScene(device);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4561 if(SUCCEEDED(hr))
4563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4564 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4566 hr = IDirect3DDevice9_EndScene(device);
4567 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4569 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4572 color = getPixelColor(device, 360, 240);
4573 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4575 IDirect3DPixelShader9_Release(shader_dp2add);
4576 } else {
4577 skip("dp2add shader creation failed\n");
4580 if (shader_dp2add_sat) {
4582 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4583 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4585 hr = IDirect3DDevice9_BeginScene(device);
4586 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4587 if(SUCCEEDED(hr))
4589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4590 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4592 hr = IDirect3DDevice9_EndScene(device);
4593 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4596 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4598 color = getPixelColor(device, 360, 240);
4599 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4601 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4602 } else {
4603 skip("dp2add shader creation failed\n");
4606 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4607 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4610 static void cnd_test(IDirect3DDevice9 *device)
4612 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4613 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4614 HRESULT hr;
4615 DWORD color;
4616 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4617 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4618 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4620 DWORD shader_code_11[] = {
4621 0xffff0101, /* ps_1_1 */
4622 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4623 0x00000040, 0xb00f0000, /* texcoord t0 */
4624 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4625 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4626 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4627 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4628 0x0000ffff /* end */
4630 DWORD shader_code_12[] = {
4631 0xffff0102, /* ps_1_2 */
4632 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4633 0x00000040, 0xb00f0000, /* texcoord t0 */
4634 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4635 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4636 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4637 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4638 0x0000ffff /* end */
4640 DWORD shader_code_13[] = {
4641 0xffff0103, /* ps_1_3 */
4642 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4643 0x00000040, 0xb00f0000, /* texcoord t0 */
4644 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4645 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4646 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4647 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4648 0x0000ffff /* end */
4650 DWORD shader_code_14[] = {
4651 0xffff0104, /* ps_1_3 */
4652 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4653 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4654 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4655 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4656 0x0000ffff /* end */
4659 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4660 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4661 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4662 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4663 * native CreatePixelShader returns an error.
4665 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4666 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4667 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4668 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4670 DWORD shader_code_11_coissue[] = {
4671 0xffff0101, /* ps_1_1 */
4672 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4673 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4674 0x00000040, 0xb00f0000, /* texcoord t0 */
4675 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4676 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4677 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4678 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4679 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4680 /* 0x40000000 = D3DSI_COISSUE */
4681 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4682 0x0000ffff /* end */
4684 DWORD shader_code_12_coissue[] = {
4685 0xffff0102, /* ps_1_2 */
4686 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4687 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4688 0x00000040, 0xb00f0000, /* texcoord t0 */
4689 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4690 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4691 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4692 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4693 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4694 /* 0x40000000 = D3DSI_COISSUE */
4695 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4696 0x0000ffff /* end */
4698 DWORD shader_code_13_coissue[] = {
4699 0xffff0103, /* ps_1_3 */
4700 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4701 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4702 0x00000040, 0xb00f0000, /* texcoord t0 */
4703 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4704 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4705 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4706 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4707 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4708 /* 0x40000000 = D3DSI_COISSUE */
4709 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4710 0x0000ffff /* end */
4712 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4713 * compare against 0.5
4715 DWORD shader_code_14_coissue[] = {
4716 0xffff0104, /* ps_1_4 */
4717 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4718 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4719 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4720 /* 0x40000000 = D3DSI_COISSUE */
4721 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4722 0x0000ffff /* end */
4724 float quad1[] = {
4725 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4726 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4727 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4728 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4730 float quad2[] = {
4731 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4732 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4733 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4734 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4736 float quad3[] = {
4737 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4738 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4739 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4740 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4742 float quad4[] = {
4743 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4744 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4745 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4746 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4748 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4749 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4750 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4751 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4754 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4756 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4757 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4760 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4762 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4763 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4764 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4765 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4766 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4767 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4768 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4770 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4771 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4773 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4774 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4775 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4776 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4777 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4780 hr = IDirect3DDevice9_BeginScene(device);
4781 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4782 if(SUCCEEDED(hr))
4784 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4785 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4787 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4789 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4790 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4792 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4794 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4795 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4797 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4799 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4804 hr = IDirect3DDevice9_EndScene(device);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4807 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4810 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4811 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4813 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4814 color = getPixelColor(device, 158, 118);
4815 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4816 color = getPixelColor(device, 162, 118);
4817 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4818 color = getPixelColor(device, 158, 122);
4819 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4820 color = getPixelColor(device, 162, 122);
4821 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4823 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4824 color = getPixelColor(device, 158, 358);
4825 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4826 color = getPixelColor(device, 162, 358);
4827 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4828 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4829 color = getPixelColor(device, 158, 362);
4830 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4831 color = getPixelColor(device, 162, 362);
4832 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4833 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4835 /* 1.2 shader */
4836 color = getPixelColor(device, 478, 358);
4837 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4838 color = getPixelColor(device, 482, 358);
4839 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4840 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4841 color = getPixelColor(device, 478, 362);
4842 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4843 color = getPixelColor(device, 482, 362);
4844 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4845 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4847 /* 1.3 shader */
4848 color = getPixelColor(device, 478, 118);
4849 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4850 color = getPixelColor(device, 482, 118);
4851 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4852 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4853 color = getPixelColor(device, 478, 122);
4854 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4855 color = getPixelColor(device, 482, 122);
4856 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4857 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4860 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4861 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4863 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4866 hr = IDirect3DDevice9_BeginScene(device);
4867 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4868 if(SUCCEEDED(hr))
4870 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4871 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4873 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4875 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4876 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4878 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4880 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4883 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4885 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4886 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4887 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4888 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4890 hr = IDirect3DDevice9_EndScene(device);
4891 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
4987 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4989 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4990 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4994 hr = IDirect3DDevice9_BeginScene(device);
4995 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5003 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5217 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5218 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5219 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5220 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(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 = %s\n",
5226 tests[i].name, DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5234 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5235 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5237 hr = IDirect3DDevice9_BeginScene(device);
5238 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5248 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5249 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5284 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5287 hr = IDirect3DDevice9_BeginScene(device);
5288 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5297 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(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,
5339 0x0200001f, 0x80000006, 0x900f0007,
5340 0x0200001f, 0x80000001, 0x900f0008,
5341 0x0200001f, 0x8000000c, 0x900f0009,
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.5, 0.0, 0.0, 0.0 */
5375 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
5376 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 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 %s\n", DXGetErrorString9(hr));
5440 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5441 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5442 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5443 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5444 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5445 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5446 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5447 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5448 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5450 hr = IDirect3DDevice9_BeginScene(device);
5451 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5452 if(SUCCEEDED(hr))
5454 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
5472 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5473 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5475 color = getPixelColor(device, 160, 120);
5476 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5477 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5478 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5479 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5480 color = getPixelColor(device, 160, 360);
5481 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5482 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5483 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5484 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5485 color = getPixelColor(device, 480, 360);
5486 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5487 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5488 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5489 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5491 /* cleanup */
5492 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5493 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5494 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5495 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5496 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5497 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5498 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5499 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5502 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5503 static const DWORD vs_code[] = {
5504 0xfffe0300, /* vs_3_0 */
5505 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5506 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5507 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5508 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5509 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5510 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5511 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5512 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5513 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5514 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5515 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5516 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5517 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5519 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5520 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5521 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5522 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5523 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5524 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5525 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5526 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5527 0x0000ffff /* end */
5529 static const DWORD ps_1_code[] = {
5530 0xffff0104, /* ps_1_4 */
5531 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5532 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5533 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5534 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5535 0x0000ffff /* end */
5537 static const DWORD ps_2_code[] = {
5538 0xffff0200, /* ps_2_0 */
5539 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5540 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5541 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5543 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5544 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5545 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5546 0x0000ffff /* end */
5548 static const DWORD ps_3_code[] = {
5549 0xffff0300, /* ps_3_0 */
5550 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5551 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5552 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5554 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5555 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5556 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5557 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5558 0x0000ffff /* end */
5561 float quad1[] = {
5562 -1.0, -1.0, 0.1,
5563 0.0, -1.0, 0.1,
5564 -1.0, 0.0, 0.1,
5565 0.0, 0.0, 0.1
5567 float quad2[] = {
5568 0.0, -1.0, 0.1,
5569 1.0, -1.0, 0.1,
5570 0.0, 0.0, 0.1,
5571 1.0, 0.0, 0.1
5573 float quad3[] = {
5574 -1.0, 0.0, 0.1,
5575 0.0, 0.0, 0.1,
5576 -1.0, 1.0, 0.1,
5577 0.0, 1.0, 0.1
5579 float quad4[] = {
5580 0.0, 0.0, 0.1,
5581 1.0, 0.0, 0.1,
5582 0.0, 1.0, 0.1,
5583 1.0, 1.0, 0.1
5586 HRESULT hr;
5587 DWORD color;
5588 IDirect3DVertexShader9 *vertexshader = NULL;
5589 IDirect3DPixelShader9 *ps_1_shader = NULL;
5590 IDirect3DPixelShader9 *ps_2_shader = NULL;
5591 IDirect3DPixelShader9 *ps_3_shader = NULL;
5592 IDirect3DTexture9 *texture = NULL;
5593 D3DLOCKED_RECT lr;
5594 unsigned int x, y;
5596 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5598 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5599 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5600 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5601 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5602 for(y = 0; y < 512; y++) {
5603 for(x = 0; x < 512; x++) {
5604 double r_f = (double) x / (double) 512;
5605 double g_f = (double) y / (double) 512;
5606 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5607 unsigned short r = (unsigned short) (r_f * 65535.0);
5608 unsigned short g = (unsigned short) (g_f * 65535.0);
5609 dst[0] = r;
5610 dst[1] = g;
5611 dst[2] = 0;
5612 dst[3] = 65535;
5615 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5616 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5618 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5620 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5621 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5622 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5623 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5624 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5625 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5626 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5627 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5628 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5630 hr = IDirect3DDevice9_BeginScene(device);
5631 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5632 if(SUCCEEDED(hr))
5634 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5635 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5637 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5639 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5640 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5642 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5644 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5645 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5647 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5649 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5650 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5651 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5652 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5653 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5654 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5655 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5656 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5658 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5660 hr = IDirect3DDevice9_EndScene(device);
5661 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5663 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5664 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5666 color = getPixelColor(device, 160, 120);
5667 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5668 (color & 0x0000ff00) == 0x0000ff00 &&
5669 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5670 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5671 color = getPixelColor(device, 160, 360);
5672 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5673 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5674 (color & 0x000000ff) == 0x00000000,
5675 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5676 color = getPixelColor(device, 480, 360);
5677 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5678 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5679 (color & 0x000000ff) == 0x00000000,
5680 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5681 color = getPixelColor(device, 480, 160);
5682 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5683 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5684 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5685 (color & 0x000000ff) == 0x00000000),
5686 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5688 /* cleanup */
5689 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5690 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5691 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5692 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5693 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5694 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5695 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5696 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5697 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5698 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5699 if(texture) IDirect3DTexture9_Release(texture);
5702 void test_compare_instructions(IDirect3DDevice9 *device)
5704 DWORD shader_sge_vec_code[] = {
5705 0xfffe0101, /* vs_1_1 */
5706 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5707 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5708 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5709 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5710 0x0000ffff /* end */
5712 DWORD shader_slt_vec_code[] = {
5713 0xfffe0101, /* vs_1_1 */
5714 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5715 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5716 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5717 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5718 0x0000ffff /* end */
5720 DWORD shader_sge_scalar_code[] = {
5721 0xfffe0101, /* vs_1_1 */
5722 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5723 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5724 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5725 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5726 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5727 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5728 0x0000ffff /* end */
5730 DWORD shader_slt_scalar_code[] = {
5731 0xfffe0101, /* vs_1_1 */
5732 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5733 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5734 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5735 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5736 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5737 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5738 0x0000ffff /* end */
5740 IDirect3DVertexShader9 *shader_sge_vec;
5741 IDirect3DVertexShader9 *shader_slt_vec;
5742 IDirect3DVertexShader9 *shader_sge_scalar;
5743 IDirect3DVertexShader9 *shader_slt_scalar;
5744 HRESULT hr, color;
5745 float quad1[] = {
5746 -1.0, -1.0, 0.1,
5747 0.0, -1.0, 0.1,
5748 -1.0, 0.0, 0.1,
5749 0.0, 0.0, 0.1
5751 float quad2[] = {
5752 0.0, -1.0, 0.1,
5753 1.0, -1.0, 0.1,
5754 0.0, 0.0, 0.1,
5755 1.0, 0.0, 0.1
5757 float quad3[] = {
5758 -1.0, 0.0, 0.1,
5759 0.0, 0.0, 0.1,
5760 -1.0, 1.0, 0.1,
5761 0.0, 1.0, 0.1
5763 float quad4[] = {
5764 0.0, 0.0, 0.1,
5765 1.0, 0.0, 0.1,
5766 0.0, 1.0, 0.1,
5767 1.0, 1.0, 0.1
5769 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5770 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5772 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5776 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5778 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5780 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5782 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5783 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5784 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5785 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5786 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5787 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5789 hr = IDirect3DDevice9_BeginScene(device);
5790 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5791 if(SUCCEEDED(hr))
5793 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5796 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5798 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5801 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5803 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5804 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5806 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5808 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5809 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5811 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5814 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5816 hr = IDirect3DDevice9_EndScene(device);
5817 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5821 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(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, r, g, b;
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 %s\n", DXGetErrorString9(hr));
6027 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6028 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6029 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6031 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6034 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6036 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6038 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6039 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6040 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6041 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6056 hr = IDirect3DDevice9_BeginScene(device);
6057 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6058 if(SUCCEEDED(hr))
6060 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6063 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6064 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6096 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6097 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6099 if(i == 3 || i == 2) {
6100 color = getPixelColor(device, 160, 360);
6101 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
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 == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
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 == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
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 == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6155 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6202 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6203 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6207 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6212 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6213 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6216 hr = IDirect3DDevice9_BeginScene(device);
6217 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6218 if(SUCCEEDED(hr))
6220 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6222 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6223 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6230 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6232 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6233 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6239 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6240 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
6258 color = getPixelColor(device, 160, 360);
6259 r = (color & 0x00ff0000) >> 16;
6260 g = (color & 0x0000ff00) >> 8;
6261 b = (color & 0x000000ff) >> 0;
6262 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6263 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6264 color = getPixelColor(device, 480, 360);
6265 r = (color & 0x00ff0000) >> 16;
6266 g = (color & 0x0000ff00) >> 8;
6267 b = (color & 0x000000ff) >> 0;
6268 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6269 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6270 color = getPixelColor(device, 160, 120);
6271 r = (color & 0x00ff0000) >> 16;
6272 g = (color & 0x0000ff00) >> 8;
6273 b = (color & 0x000000ff) >> 0;
6274 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6275 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6276 color = getPixelColor(device, 480, 160);
6277 r = (color & 0x00ff0000) >> 16;
6278 g = (color & 0x0000ff00) >> 8;
6279 b = (color & 0x000000ff) >> 0;
6280 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6281 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6283 IDirect3DVertexShader9_Release(texcoord_color_shader);
6284 IDirect3DVertexShader9_Release(color_color_shader);
6287 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6288 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6289 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6290 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6292 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6293 IDirect3DVertexDeclaration9_Release(decl_color_color);
6294 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6295 IDirect3DVertexDeclaration9_Release(decl_color_float);
6298 static void srgbtexture_test(IDirect3DDevice9 *device)
6300 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6301 * texture stage state to render a quad using that texture. The resulting
6302 * color components should be 0x36 (~ 0.21), per this formula:
6303 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6304 * This is true where srgb_color > 0.04045.
6306 IDirect3D9 *d3d = NULL;
6307 HRESULT hr;
6308 LPDIRECT3DTEXTURE9 texture = NULL;
6309 LPDIRECT3DSURFACE9 surface = NULL;
6310 D3DLOCKED_RECT lr;
6311 DWORD color;
6312 float quad[] = {
6313 -1.0, 1.0, 0.0, 0.0, 0.0,
6314 1.0, 1.0, 0.0, 1.0, 0.0,
6315 -1.0, -1.0, 0.0, 0.0, 1.0,
6316 1.0, -1.0, 0.0, 1.0, 1.0,
6320 memset(&lr, 0, sizeof(lr));
6321 IDirect3DDevice9_GetDirect3D(device, &d3d);
6322 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6323 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6324 D3DFMT_A8R8G8B8) != D3D_OK) {
6325 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6326 goto out;
6329 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6330 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6331 &texture, NULL);
6332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6333 if(!texture) {
6334 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6335 goto out;
6337 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6338 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6340 fill_surface(surface, 0xff7f7f7f);
6341 IDirect3DSurface9_Release(surface);
6343 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6345 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6346 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6348 hr = IDirect3DDevice9_BeginScene(device);
6349 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6350 if(SUCCEEDED(hr))
6352 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6353 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6355 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6356 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6360 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6362 hr = IDirect3DDevice9_EndScene(device);
6363 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6366 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6367 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6368 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6369 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6371 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6372 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6374 color = getPixelColor(device, 320, 240);
6375 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6377 out:
6378 if(texture) IDirect3DTexture9_Release(texture);
6379 IDirect3D9_Release(d3d);
6382 /* Return true if color is near the expected value */
6383 static int color_near(DWORD color, DWORD expected)
6385 const BYTE slop = 2;
6387 BYTE r, g, b;
6388 BYTE rx, gx, bx;
6389 r = (color & 0x00ff0000) >> 16;
6390 g = (color & 0x0000ff00) >> 8;
6391 b = (color & 0x000000ff);
6392 rx = (expected & 0x00ff0000) >> 16;
6393 gx = (expected & 0x0000ff00) >> 8;
6394 bx = (expected & 0x000000ff);
6396 return
6397 ((r >= (rx - slop)) && (r <= (rx + slop))) &&
6398 ((g >= (gx - slop)) && (g <= (gx + slop))) &&
6399 ((b >= (bx - slop)) && (b <= (bx + slop)));
6402 static void shademode_test(IDirect3DDevice9 *device)
6404 /* Render a quad and try all of the different fixed function shading models. */
6405 HRESULT hr;
6406 DWORD color0, color1;
6407 DWORD color0_gouraud = 0, color1_gouraud = 0;
6408 DWORD shademode = D3DSHADE_FLAT;
6409 DWORD primtype = D3DPT_TRIANGLESTRIP;
6410 LPVOID data = NULL;
6411 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6412 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6413 UINT i, j;
6414 struct vertex quad_strip[] =
6416 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6417 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6418 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6419 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6421 struct vertex quad_list[] =
6423 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6424 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6425 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6427 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6428 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6429 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6432 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6433 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6434 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6435 if (FAILED(hr)) goto bail;
6437 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6438 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6439 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6440 if (FAILED(hr)) goto bail;
6442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6445 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6446 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6448 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6449 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6450 memcpy(data, quad_strip, sizeof(quad_strip));
6451 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6452 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6454 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6455 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6456 memcpy(data, quad_list, sizeof(quad_list));
6457 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6458 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6460 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6461 * the color fixups we have to do for FLAT shading will be dependent on that. */
6462 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6463 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6465 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6466 for (j=0; j<2; j++) {
6468 /* Inner loop just changes the D3DRS_SHADEMODE */
6469 for (i=0; i<3; i++) {
6470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6471 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6474 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6476 hr = IDirect3DDevice9_BeginScene(device);
6477 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6478 if(SUCCEEDED(hr))
6480 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6481 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6483 hr = IDirect3DDevice9_EndScene(device);
6484 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6488 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6490 /* Sample two spots from the output */
6491 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6492 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6493 switch(shademode) {
6494 case D3DSHADE_FLAT:
6495 /* Should take the color of the first vertex of each triangle */
6496 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6497 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6498 shademode = D3DSHADE_GOURAUD;
6499 break;
6500 case D3DSHADE_GOURAUD:
6501 /* Should be an interpolated blend */
6503 ok(color_near(color0, 0x000dca28),
6504 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6505 ok(color_near(color1, 0x000d45c7),
6506 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6508 color0_gouraud = color0;
6509 color1_gouraud = color1;
6511 shademode = D3DSHADE_PHONG;
6512 break;
6513 case D3DSHADE_PHONG:
6514 /* Should be the same as GOURAUD, since no hardware implements this */
6515 ok(color_near(color0, 0x000dca28),
6516 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6517 ok(color_near(color1, 0x000d45c7),
6518 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6520 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6521 color0_gouraud, color0);
6522 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6523 color1_gouraud, color1);
6524 break;
6527 /* Now, do it all over again with a TRIANGLELIST */
6528 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6529 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6530 primtype = D3DPT_TRIANGLELIST;
6531 shademode = D3DSHADE_FLAT;
6534 bail:
6535 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6536 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6538 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6540 if (vb_strip)
6541 IDirect3DVertexBuffer9_Release(vb_strip);
6542 if (vb_list)
6543 IDirect3DVertexBuffer9_Release(vb_list);
6547 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6549 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6550 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6551 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6552 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6553 * 0.73
6555 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6556 * so use shaders for this task
6558 IDirect3DPixelShader9 *pshader;
6559 IDirect3DVertexShader9 *vshader;
6560 IDirect3D9 *d3d;
6561 DWORD vshader_code[] = {
6562 0xfffe0101, /* vs_1_1 */
6563 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6564 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6565 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6566 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6567 0x0000ffff /* end */
6569 DWORD pshader_code[] = {
6570 0xffff0101, /* ps_1_1 */
6571 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6572 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6573 0x0000ffff /* end */
6575 const float quad[] = {
6576 -1.0, -1.0, 0.1,
6577 1.0, -1.0, 0.1,
6578 -1.0, 1.0, 0.1,
6579 1.0, 1.0, 0.1
6581 HRESULT hr;
6582 DWORD color;
6584 IDirect3DDevice9_GetDirect3D(device, &d3d);
6585 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6586 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6587 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6588 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6589 * works
6591 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6592 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6593 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6594 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6595 IDirect3D9_Release(d3d);
6596 return;
6598 IDirect3D9_Release(d3d);
6600 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6601 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6604 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6606 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6608 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6609 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6610 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6612 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6614 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6615 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6616 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6617 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6618 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6619 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6620 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6621 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6622 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6623 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6625 hr = IDirect3DDevice9_BeginScene(device);
6626 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6627 if(SUCCEEDED(hr)) {
6628 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6629 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6631 hr = IDirect3DDevice9_EndScene(device);
6632 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6635 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6636 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6637 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6639 IDirect3DPixelShader9_Release(pshader);
6640 IDirect3DVertexShader9_Release(vshader);
6642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6643 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6648 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6649 color = getPixelColor(device, 160, 360);
6650 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6651 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6654 static void alpha_test(IDirect3DDevice9 *device)
6656 HRESULT hr;
6657 IDirect3DTexture9 *offscreenTexture;
6658 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6659 DWORD color, red, green, blue;
6661 struct vertex quad1[] =
6663 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6664 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6665 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6666 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6668 struct vertex quad2[] =
6670 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6671 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6672 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6673 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6675 static const float composite_quad[][5] = {
6676 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6677 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6678 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6679 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6682 /* Clear the render target with alpha = 0.5 */
6683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6684 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6686 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6687 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6689 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6690 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6691 if(!backbuffer) {
6692 goto out;
6695 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6696 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6697 if(!offscreen) {
6698 goto out;
6701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6704 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6705 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6706 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6707 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6708 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6709 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6710 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6711 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6713 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6716 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6717 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6719 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6725 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6728 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6732 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6734 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6735 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6736 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6737 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6738 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6740 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6745 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6747 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6749 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6752 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6754 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6756 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6757 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6759 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6760 * Disable alpha blending for the final composition
6762 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6763 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6765 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6767 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6768 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6770 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6771 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6774 hr = IDirect3DDevice9_EndScene(device);
6775 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6778 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6780 color = getPixelColor(device, 160, 360);
6781 red = (color & 0x00ff0000) >> 16;
6782 green = (color & 0x0000ff00) >> 8;
6783 blue = (color & 0x000000ff);
6784 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6785 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6787 color = getPixelColor(device, 160, 120);
6788 red = (color & 0x00ff0000) >> 16;
6789 green = (color & 0x0000ff00) >> 8;
6790 blue = (color & 0x000000ff);
6791 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6792 "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6794 color = getPixelColor(device, 480, 360);
6795 red = (color & 0x00ff0000) >> 16;
6796 green = (color & 0x0000ff00) >> 8;
6797 blue = (color & 0x000000ff);
6798 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6799 "SRCALPHA on texture returned color %08x, expected bar\n", color);
6801 color = getPixelColor(device, 480, 120);
6802 red = (color & 0x00ff0000) >> 16;
6803 green = (color & 0x0000ff00) >> 8;
6804 blue = (color & 0x000000ff);
6805 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6806 "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6808 out:
6809 /* restore things */
6810 if(backbuffer) {
6811 IDirect3DSurface9_Release(backbuffer);
6813 if(offscreenTexture) {
6814 IDirect3DTexture9_Release(offscreenTexture);
6816 if(offscreen) {
6817 IDirect3DSurface9_Release(offscreen);
6821 struct vertex_shortcolor {
6822 float x, y, z;
6823 unsigned short r, g, b, a;
6825 struct vertex_floatcolor {
6826 float x, y, z;
6827 float r, g, b, a;
6830 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6832 HRESULT hr;
6833 BOOL s_ok, ub_ok, f_ok;
6834 DWORD color, size, i;
6835 void *data;
6836 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6837 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6838 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6839 D3DDECL_END()
6841 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6842 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6843 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6844 D3DDECL_END()
6846 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6847 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6848 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6849 D3DDECL_END()
6851 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6852 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6853 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6854 D3DDECL_END()
6856 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6857 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6858 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6859 D3DDECL_END()
6861 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6862 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6863 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6864 D3DDECL_END()
6866 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6867 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6868 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6869 D3DDECL_END()
6871 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6872 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6873 IDirect3DVertexBuffer9 *vb, *vb2;
6874 struct vertex quad1[] = /* D3DCOLOR */
6876 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6877 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6878 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6879 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6881 struct vertex quad2[] = /* UBYTE4N */
6883 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6884 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6885 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6886 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6888 struct vertex_shortcolor quad3[] = /* short */
6890 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6891 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6892 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6893 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6895 struct vertex_floatcolor quad4[] =
6897 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6898 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6899 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6900 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6902 DWORD colors[] = {
6903 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6904 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6905 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6906 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6907 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6908 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6909 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6910 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6911 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6912 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6913 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6914 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6915 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6916 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6917 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6918 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6920 float quads[] = {
6921 -1.0, -1.0, 0.1,
6922 -1.0, 0.0, 0.1,
6923 0.0, -1.0, 0.1,
6924 0.0, 0.0, 0.1,
6926 0.0, -1.0, 0.1,
6927 0.0, 0.0, 0.1,
6928 1.0, -1.0, 0.1,
6929 1.0, 0.0, 0.1,
6931 0.0, 0.0, 0.1,
6932 0.0, 1.0, 0.1,
6933 1.0, 0.0, 0.1,
6934 1.0, 1.0, 0.1,
6936 -1.0, 0.0, 0.1,
6937 -1.0, 1.0, 0.1,
6938 0.0, 0.0, 0.1,
6939 0.0, 1.0, 0.1
6941 struct tvertex quad_transformed[] = {
6942 { 90, 110, 0.1, 2.0, 0x00ffff00},
6943 { 570, 110, 0.1, 2.0, 0x00ffff00},
6944 { 90, 300, 0.1, 2.0, 0x00ffff00},
6945 { 570, 300, 0.1, 2.0, 0x00ffff00}
6947 D3DCAPS9 caps;
6949 memset(&caps, 0, sizeof(caps));
6950 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6951 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6953 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6954 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6956 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6957 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6958 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6959 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6960 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6961 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6962 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6963 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6964 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6965 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6966 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6967 } else {
6968 trace("D3DDTCAPS_UBYTE4N not supported\n");
6969 dcl_ubyte_2 = NULL;
6970 dcl_ubyte = NULL;
6972 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6973 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6974 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6975 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6977 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6978 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6979 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6980 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6982 hr = IDirect3DDevice9_BeginScene(device);
6983 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6984 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6985 if(SUCCEEDED(hr)) {
6986 if(dcl_color) {
6987 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6990 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6993 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6994 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6995 * using software vertex processing. Doh!
6997 if(dcl_ubyte) {
6998 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6999 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7001 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7002 ub_ok = SUCCEEDED(hr);
7005 if(dcl_short) {
7006 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7007 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7008 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7009 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7010 s_ok = SUCCEEDED(hr);
7013 if(dcl_float) {
7014 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7015 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7016 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7017 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7018 f_ok = SUCCEEDED(hr);
7021 hr = IDirect3DDevice9_EndScene(device);
7022 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7025 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7026 if(dcl_short) {
7027 color = getPixelColor(device, 480, 360);
7028 ok(color == 0x000000ff || !s_ok,
7029 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7031 if(dcl_ubyte) {
7032 color = getPixelColor(device, 160, 120);
7033 ok(color == 0x0000ffff || !ub_ok,
7034 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7036 if(dcl_color) {
7037 color = getPixelColor(device, 160, 360);
7038 ok(color == 0x00ffff00,
7039 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7041 if(dcl_float) {
7042 color = getPixelColor(device, 480, 120);
7043 ok(color == 0x00ff0000 || !f_ok,
7044 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7047 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7048 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7049 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7050 * whether the immediate mode code works
7052 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7053 hr = IDirect3DDevice9_BeginScene(device);
7054 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7055 if(SUCCEEDED(hr)) {
7056 if(dcl_color) {
7057 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7058 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7059 memcpy(data, quad1, sizeof(quad1));
7060 hr = IDirect3DVertexBuffer9_Unlock(vb);
7061 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7062 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7063 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7064 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7065 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7066 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7067 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7070 if(dcl_ubyte) {
7071 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7072 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7073 memcpy(data, quad2, sizeof(quad2));
7074 hr = IDirect3DVertexBuffer9_Unlock(vb);
7075 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7076 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7077 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7078 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7079 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7080 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7081 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7082 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7083 ub_ok = SUCCEEDED(hr);
7086 if(dcl_short) {
7087 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7088 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7089 memcpy(data, quad3, sizeof(quad3));
7090 hr = IDirect3DVertexBuffer9_Unlock(vb);
7091 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7092 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7093 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7094 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7095 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7096 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7097 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7098 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7099 s_ok = SUCCEEDED(hr);
7102 if(dcl_float) {
7103 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7104 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7105 memcpy(data, quad4, sizeof(quad4));
7106 hr = IDirect3DVertexBuffer9_Unlock(vb);
7107 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7108 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7109 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7110 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7111 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7112 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7113 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7114 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7115 f_ok = SUCCEEDED(hr);
7118 hr = IDirect3DDevice9_EndScene(device);
7119 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7122 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7123 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7124 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7125 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7127 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7128 if(dcl_short) {
7129 color = getPixelColor(device, 480, 360);
7130 ok(color == 0x000000ff || !s_ok,
7131 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7133 if(dcl_ubyte) {
7134 color = getPixelColor(device, 160, 120);
7135 ok(color == 0x0000ffff || !ub_ok,
7136 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7138 if(dcl_color) {
7139 color = getPixelColor(device, 160, 360);
7140 ok(color == 0x00ffff00,
7141 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7143 if(dcl_float) {
7144 color = getPixelColor(device, 480, 120);
7145 ok(color == 0x00ff0000 || !f_ok,
7146 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7149 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7150 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7152 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7153 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7154 memcpy(data, quad_transformed, sizeof(quad_transformed));
7155 hr = IDirect3DVertexBuffer9_Unlock(vb);
7156 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7158 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7161 hr = IDirect3DDevice9_BeginScene(device);
7162 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7163 if(SUCCEEDED(hr)) {
7164 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7165 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7166 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7167 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7169 hr = IDirect3DDevice9_EndScene(device);
7170 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7173 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7174 color = getPixelColor(device, 88, 108);
7175 ok(color == 0x000000ff,
7176 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7177 color = getPixelColor(device, 92, 108);
7178 ok(color == 0x000000ff,
7179 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7180 color = getPixelColor(device, 88, 112);
7181 ok(color == 0x000000ff,
7182 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7183 color = getPixelColor(device, 92, 112);
7184 ok(color == 0x00ffff00,
7185 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7187 color = getPixelColor(device, 568, 108);
7188 ok(color == 0x000000ff,
7189 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7190 color = getPixelColor(device, 572, 108);
7191 ok(color == 0x000000ff,
7192 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7193 color = getPixelColor(device, 568, 112);
7194 ok(color == 0x00ffff00,
7195 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7196 color = getPixelColor(device, 572, 112);
7197 ok(color == 0x000000ff,
7198 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7200 color = getPixelColor(device, 88, 298);
7201 ok(color == 0x000000ff,
7202 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7203 color = getPixelColor(device, 92, 298);
7204 ok(color == 0x00ffff00,
7205 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7206 color = getPixelColor(device, 88, 302);
7207 ok(color == 0x000000ff,
7208 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7209 color = getPixelColor(device, 92, 302);
7210 ok(color == 0x000000ff,
7211 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7213 color = getPixelColor(device, 568, 298);
7214 ok(color == 0x00ffff00,
7215 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7216 color = getPixelColor(device, 572, 298);
7217 ok(color == 0x000000ff,
7218 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7219 color = getPixelColor(device, 568, 302);
7220 ok(color == 0x000000ff,
7221 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7222 color = getPixelColor(device, 572, 302);
7223 ok(color == 0x000000ff,
7224 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7226 /* This test is pointless without those two declarations: */
7227 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7228 skip("color-ubyte switching test declarations aren't supported\n");
7229 goto out;
7232 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7233 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7234 memcpy(data, quads, sizeof(quads));
7235 hr = IDirect3DVertexBuffer9_Unlock(vb);
7236 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7237 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7238 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7239 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7240 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7241 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7242 memcpy(data, colors, sizeof(colors));
7243 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7244 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7246 for(i = 0; i < 2; i++) {
7247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7248 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7250 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7251 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7252 if(i == 0) {
7253 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7254 } else {
7255 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7259 hr = IDirect3DDevice9_BeginScene(device);
7260 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7261 ub_ok = FALSE;
7262 if(SUCCEEDED(hr)) {
7263 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7264 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7265 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7266 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7267 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7268 ub_ok = SUCCEEDED(hr);
7270 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7271 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7272 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7273 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7275 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7276 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7277 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7278 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7279 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7280 ub_ok = (SUCCEEDED(hr) && ub_ok);
7282 hr = IDirect3DDevice9_EndScene(device);
7283 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7286 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7287 if(i == 0) {
7288 color = getPixelColor(device, 480, 360);
7289 ok(color == 0x00ff0000,
7290 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7291 color = getPixelColor(device, 160, 120);
7292 ok(color == 0x00ffffff,
7293 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7294 color = getPixelColor(device, 160, 360);
7295 ok(color == 0x000000ff || !ub_ok,
7296 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7297 color = getPixelColor(device, 480, 120);
7298 ok(color == 0x000000ff || !ub_ok,
7299 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7300 } else {
7301 color = getPixelColor(device, 480, 360);
7302 ok(color == 0x000000ff,
7303 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7304 color = getPixelColor(device, 160, 120);
7305 ok(color == 0x00ffffff,
7306 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7307 color = getPixelColor(device, 160, 360);
7308 ok(color == 0x00ff0000 || !ub_ok,
7309 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7310 color = getPixelColor(device, 480, 120);
7311 ok(color == 0x00ff0000 || !ub_ok,
7312 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7316 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7317 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7318 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7319 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7320 IDirect3DVertexBuffer9_Release(vb2);
7322 out:
7323 IDirect3DVertexBuffer9_Release(vb);
7324 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7325 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7326 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7327 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7328 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7329 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7330 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7333 struct vertex_float16color {
7334 float x, y, z;
7335 DWORD c1, c2;
7338 static void test_vshader_float16(IDirect3DDevice9 *device)
7340 HRESULT hr;
7341 DWORD color;
7342 void *data;
7343 static const D3DVERTEXELEMENT9 decl_elements[] = {
7344 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7345 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7346 D3DDECL_END()
7348 IDirect3DVertexDeclaration9 *vdecl = NULL;
7349 IDirect3DVertexBuffer9 *buffer = NULL;
7350 IDirect3DVertexShader9 *shader;
7351 DWORD shader_code[] = {
7352 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7353 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7354 0x90e40001, 0x0000ffff
7356 struct vertex_float16color quad[] = {
7357 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7358 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7359 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7360 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7362 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7363 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7364 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7365 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7367 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7368 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7369 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7370 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7372 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7373 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7374 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7375 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7378 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7379 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7381 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7382 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7383 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7384 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7385 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7386 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7388 hr = IDirect3DDevice9_BeginScene(device);
7389 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7390 if(SUCCEEDED(hr)) {
7391 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7392 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7394 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7396 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7398 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7400 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7402 hr = IDirect3DDevice9_EndScene(device);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(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_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7420 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7422 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7423 D3DPOOL_MANAGED, &buffer, NULL);
7424 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7425 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7426 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7427 memcpy(data, quad, sizeof(quad));
7428 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7429 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7430 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7431 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7433 hr = IDirect3DDevice9_BeginScene(device);
7434 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7435 if(SUCCEEDED(hr)) {
7436 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7437 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7438 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7439 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7440 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7441 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7442 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7443 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7445 hr = IDirect3DDevice9_EndScene(device);
7446 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7449 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7450 color = getPixelColor(device, 480, 360);
7451 ok(color == 0x00ff0000,
7452 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7453 color = getPixelColor(device, 160, 120);
7454 ok(color == 0x00000000,
7455 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7456 color = getPixelColor(device, 160, 360);
7457 ok(color == 0x0000ff00,
7458 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7459 color = getPixelColor(device, 480, 120);
7460 ok(color == 0x000000ff,
7461 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7463 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7465 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7466 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7467 IDirect3DDevice9_SetVertexShader(device, NULL);
7468 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7470 IDirect3DVertexDeclaration9_Release(vdecl);
7471 IDirect3DVertexShader9_Release(shader);
7472 IDirect3DVertexBuffer9_Release(buffer);
7475 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7477 D3DCAPS9 caps;
7478 IDirect3DTexture9 *texture;
7479 HRESULT hr;
7480 D3DLOCKED_RECT rect;
7481 unsigned int x, y;
7482 DWORD *dst, color;
7483 const float quad[] = {
7484 -1.0, -1.0, 0.1, -0.2, -0.2,
7485 1.0, -1.0, 0.1, 1.2, -0.2,
7486 -1.0, 1.0, 0.1, -0.2, 1.2,
7487 1.0, 1.0, 0.1, 1.2, 1.2
7489 memset(&caps, 0, sizeof(caps));
7491 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7493 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7494 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7495 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7496 "Card has conditional NP2 support without power of two restriction set\n");
7497 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7498 return;
7499 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7500 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7501 return;
7504 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7505 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7507 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7508 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7510 memset(&rect, 0, sizeof(rect));
7511 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7512 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7513 for(y = 0; y < 10; y++) {
7514 for(x = 0; x < 10; x++) {
7515 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7516 if(x == 0 || x == 9 || y == 0 || y == 9) {
7517 *dst = 0x00ff0000;
7518 } else {
7519 *dst = 0x000000ff;
7523 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7524 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7526 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7527 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7528 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7529 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7530 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7531 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7533 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7535 hr = IDirect3DDevice9_BeginScene(device);
7536 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7537 if(SUCCEEDED(hr)) {
7538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7539 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7541 hr = IDirect3DDevice9_EndScene(device);
7542 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7545 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7547 color = getPixelColor(device, 1, 1);
7548 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7549 color = getPixelColor(device, 639, 479);
7550 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7552 color = getPixelColor(device, 135, 101);
7553 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7554 color = getPixelColor(device, 140, 101);
7555 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7556 color = getPixelColor(device, 135, 105);
7557 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7558 color = getPixelColor(device, 140, 105);
7559 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7561 color = getPixelColor(device, 135, 376);
7562 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7563 color = getPixelColor(device, 140, 376);
7564 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7565 color = getPixelColor(device, 135, 379);
7566 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7567 color = getPixelColor(device, 140, 379);
7568 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7570 color = getPixelColor(device, 500, 101);
7571 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7572 color = getPixelColor(device, 504, 101);
7573 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7574 color = getPixelColor(device, 500, 105);
7575 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7576 color = getPixelColor(device, 504, 105);
7577 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7579 color = getPixelColor(device, 500, 376);
7580 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7581 color = getPixelColor(device, 504, 376);
7582 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7583 color = getPixelColor(device, 500, 380);
7584 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7585 color = getPixelColor(device, 504, 380);
7586 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7588 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7589 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7590 IDirect3DTexture9_Release(texture);
7593 static void vFace_register_test(IDirect3DDevice9 *device)
7595 HRESULT hr;
7596 DWORD color;
7597 const DWORD shader_code[] = {
7598 0xffff0300, /* ps_3_0 */
7599 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7600 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7601 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7602 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7603 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7604 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7605 0x0000ffff /* END */
7607 IDirect3DPixelShader9 *shader;
7608 IDirect3DTexture9 *texture;
7609 IDirect3DSurface9 *surface, *backbuffer;
7610 const float quad[] = {
7611 -1.0, -1.0, 0.1,
7612 1.0, -1.0, 0.1,
7613 -1.0, 0.0, 0.1,
7615 1.0, -1.0, 0.1,
7616 1.0, 0.0, 0.1,
7617 -1.0, 0.0, 0.1,
7619 -1.0, 0.0, 0.1,
7620 -1.0, 1.0, 0.1,
7621 1.0, 0.0, 0.1,
7623 1.0, 0.0, 0.1,
7624 -1.0, 1.0, 0.1,
7625 1.0, 1.0, 0.1,
7627 const float blit[] = {
7628 0.0, -1.0, 0.1, 0.0, 0.0,
7629 1.0, -1.0, 0.1, 1.0, 0.0,
7630 0.0, 1.0, 0.1, 0.0, 1.0,
7631 1.0, 1.0, 0.1, 1.0, 1.0,
7634 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7635 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7636 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7637 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7638 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7639 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7640 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7641 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7642 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7643 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7644 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7645 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7648 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7650 hr = IDirect3DDevice9_BeginScene(device);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7652 if(SUCCEEDED(hr)) {
7653 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7654 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7655 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7656 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7657 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7659 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7660 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7661 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7663 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7665 /* Blit the texture onto the back buffer to make it visible */
7666 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7667 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7668 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7669 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7672 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7674 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7675 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7680 hr = IDirect3DDevice9_EndScene(device);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7684 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7685 color = getPixelColor(device, 160, 360);
7686 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7687 color = getPixelColor(device, 160, 120);
7688 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7689 color = getPixelColor(device, 480, 360);
7690 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7691 color = getPixelColor(device, 480, 120);
7692 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7694 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7695 IDirect3DDevice9_SetTexture(device, 0, NULL);
7696 IDirect3DPixelShader9_Release(shader);
7697 IDirect3DSurface9_Release(surface);
7698 IDirect3DSurface9_Release(backbuffer);
7699 IDirect3DTexture9_Release(texture);
7702 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7704 HRESULT hr;
7705 DWORD color;
7706 int i;
7707 D3DCAPS9 caps;
7709 static const float quad[][7] = {
7710 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7711 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7712 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7713 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7716 static const D3DVERTEXELEMENT9 decl_elements[] = {
7717 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7718 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7719 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7720 D3DDECL_END()
7723 /* use asymmetric matrix to test loading */
7724 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7726 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7727 IDirect3DTexture9 *texture = NULL;
7729 memset(&caps, 0, sizeof(caps));
7730 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7731 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7732 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7733 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7734 return;
7735 } else {
7736 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7737 * They report that it is not supported, but after that bump mapping works properly. So just test
7738 * if the format is generally supported, and check the BUMPENVMAP flag
7740 IDirect3D9 *d3d9;
7742 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7743 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7744 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7745 IDirect3D9_Release(d3d9);
7746 if(FAILED(hr)) {
7747 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7748 return;
7752 /* Generate the textures */
7753 generate_bumpmap_textures(device);
7755 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7756 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7757 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7758 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7759 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7760 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7761 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7762 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7764 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7765 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7766 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7767 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7769 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7771 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7772 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7773 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7774 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7775 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7776 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7778 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7779 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7781 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7782 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7785 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7788 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7789 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7790 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7791 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7793 hr = IDirect3DDevice9_BeginScene(device);
7794 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7797 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7799 hr = IDirect3DDevice9_EndScene(device);
7800 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7802 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7803 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7805 color = getPixelColor(device, 320-32, 240);
7806 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7807 color = getPixelColor(device, 320+32, 240);
7808 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7809 color = getPixelColor(device, 320, 240-32);
7810 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7811 color = getPixelColor(device, 320, 240+32);
7812 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7813 color = getPixelColor(device, 320, 240);
7814 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7815 color = getPixelColor(device, 320+32, 240+32);
7816 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7817 color = getPixelColor(device, 320-32, 240+32);
7818 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7819 color = getPixelColor(device, 320+32, 240-32);
7820 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7821 color = getPixelColor(device, 320-32, 240-32);
7822 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7824 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7825 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7826 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7828 for(i = 0; i < 2; i++) {
7829 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7830 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7831 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7832 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7833 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7834 IDirect3DTexture9_Release(texture); /* To destroy it */
7837 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7838 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7839 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7840 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7844 static void stencil_cull_test(IDirect3DDevice9 *device) {
7845 HRESULT hr;
7846 IDirect3DSurface9 *depthstencil = NULL;
7847 D3DSURFACE_DESC desc;
7848 float quad1[] = {
7849 -1.0, -1.0, 0.1,
7850 0.0, -1.0, 0.1,
7851 -1.0, 0.0, 0.1,
7852 0.0, 0.0, 0.1,
7854 float quad2[] = {
7855 0.0, -1.0, 0.1,
7856 1.0, -1.0, 0.1,
7857 0.0, 0.0, 0.1,
7858 1.0, 0.0, 0.1,
7860 float quad3[] = {
7861 0.0, 0.0, 0.1,
7862 1.0, 0.0, 0.1,
7863 0.0, 1.0, 0.1,
7864 1.0, 1.0, 0.1,
7866 float quad4[] = {
7867 -1.0, 0.0, 0.1,
7868 0.0, 0.0, 0.1,
7869 -1.0, 1.0, 0.1,
7870 0.0, 1.0, 0.1,
7872 struct vertex painter[] = {
7873 {-1.0, -1.0, 0.0, 0x00000000},
7874 { 1.0, -1.0, 0.0, 0x00000000},
7875 {-1.0, 1.0, 0.0, 0x00000000},
7876 { 1.0, 1.0, 0.0, 0x00000000},
7878 WORD indices_cw[] = {0, 1, 3};
7879 WORD indices_ccw[] = {0, 2, 3};
7880 unsigned int i;
7881 DWORD color;
7883 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7884 if(depthstencil == NULL) {
7885 skip("No depth stencil buffer\n");
7886 return;
7888 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7889 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7890 IDirect3DSurface9_Release(depthstencil);
7891 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7892 skip("No 4 or 8 bit stencil surface\n");
7893 return;
7896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7898 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7905 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7907 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7910 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7912 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7919 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7921 /* First pass: Fill the stencil buffer with some values... */
7922 hr = IDirect3DDevice9_BeginScene(device);
7923 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7924 if(SUCCEEDED(hr))
7926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7927 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7928 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7929 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7930 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7931 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7934 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7937 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7938 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7939 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7940 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7943 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7944 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7945 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7946 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7947 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7950 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7951 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7952 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7953 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7954 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7956 hr = IDirect3DDevice9_EndScene(device);
7957 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7962 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7964 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7966 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7968 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7970 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7972 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7974 /* 2nd pass: Make the stencil values visible */
7975 hr = IDirect3DDevice9_BeginScene(device);
7976 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7977 if(SUCCEEDED(hr))
7979 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7980 for(i = 0; i < 16; i++) {
7981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7982 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7984 painter[0].diffuse = (i * 16); /* Creates shades of blue */
7985 painter[1].diffuse = (i * 16);
7986 painter[2].diffuse = (i * 16);
7987 painter[3].diffuse = (i * 16);
7988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7989 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7991 hr = IDirect3DDevice9_EndScene(device);
7992 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7995 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7996 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7999 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8001 color = getPixelColor(device, 160, 420);
8002 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8003 color = getPixelColor(device, 160, 300);
8004 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8006 color = getPixelColor(device, 480, 420);
8007 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8008 color = getPixelColor(device, 480, 300);
8009 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8011 color = getPixelColor(device, 160, 180);
8012 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8013 color = getPixelColor(device, 160, 60);
8014 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8016 color = getPixelColor(device, 480, 180);
8017 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8018 color = getPixelColor(device, 480, 60);
8019 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8022 static void vpos_register_test(IDirect3DDevice9 *device)
8024 HRESULT hr;
8025 DWORD color;
8026 const DWORD shader_code[] = {
8027 0xffff0300, /* ps_3_0 */
8028 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8029 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8030 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8031 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8032 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8033 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8034 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8035 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8036 0x0000ffff /* end */
8038 const DWORD shader_frac_code[] = {
8039 0xffff0300, /* ps_3_0 */
8040 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8041 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8042 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8043 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8044 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8045 0x0000ffff /* end */
8047 IDirect3DPixelShader9 *shader, *shader_frac;
8048 IDirect3DSurface9 *surface = NULL, *backbuffer;
8049 const float quad[] = {
8050 -1.0, -1.0, 0.1, 0.0, 0.0,
8051 1.0, -1.0, 0.1, 1.0, 0.0,
8052 -1.0, 1.0, 0.1, 0.0, 1.0,
8053 1.0, 1.0, 0.1, 1.0, 1.0,
8055 D3DLOCKED_RECT lr;
8056 float constant[4] = {1.0, 0.0, 320, 240};
8057 DWORD *pos;
8059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8060 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8061 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8062 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8063 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8064 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8065 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8066 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8067 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8068 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8069 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8070 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8072 hr = IDirect3DDevice9_BeginScene(device);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8074 if(SUCCEEDED(hr)) {
8075 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8076 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8079 hr = IDirect3DDevice9_EndScene(device);
8080 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8083 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8084 /* This has to be pixel exact */
8085 color = getPixelColor(device, 319, 239);
8086 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8087 color = getPixelColor(device, 320, 239);
8088 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8089 color = getPixelColor(device, 319, 240);
8090 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8091 color = getPixelColor(device, 320, 240);
8092 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8094 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8095 &surface, NULL);
8096 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8097 hr = IDirect3DDevice9_BeginScene(device);
8098 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8099 if(SUCCEEDED(hr)) {
8100 constant[2] = 16; constant[3] = 16;
8101 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8103 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8104 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8106 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8107 hr = IDirect3DDevice9_EndScene(device);
8108 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8110 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8111 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8113 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8114 color = *pos & 0x00ffffff;
8115 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8116 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8117 color = *pos & 0x00ffffff;
8118 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8119 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8120 color = *pos & 0x00ffffff;
8121 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8122 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8123 color = *pos & 0x00ffffff;
8124 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8126 hr = IDirect3DSurface9_UnlockRect(surface);
8127 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8129 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8130 * have full control over the multisampling setting inside this test
8132 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8133 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8134 hr = IDirect3DDevice9_BeginScene(device);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8136 if(SUCCEEDED(hr)) {
8137 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8138 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8140 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8141 hr = IDirect3DDevice9_EndScene(device);
8142 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8144 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8147 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8148 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8150 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8151 color = *pos & 0x00ffffff;
8152 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8154 hr = IDirect3DSurface9_UnlockRect(surface);
8155 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8157 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8158 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8159 IDirect3DPixelShader9_Release(shader);
8160 IDirect3DPixelShader9_Release(shader_frac);
8161 if(surface) IDirect3DSurface9_Release(surface);
8162 IDirect3DSurface9_Release(backbuffer);
8165 static void pointsize_test(IDirect3DDevice9 *device)
8167 HRESULT hr;
8168 D3DCAPS9 caps;
8169 D3DMATRIX matrix;
8170 D3DMATRIX identity;
8171 float ptsize, ptsize_orig;
8172 DWORD color;
8174 const float vertices[] = {
8175 64, 64, 0.1,
8176 128, 64, 0.1,
8177 192, 64, 0.1,
8178 256, 64, 0.1,
8179 320, 64, 0.1,
8180 384, 64, 0.1
8183 /* 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 */
8184 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;
8185 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;
8186 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;
8187 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;
8189 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;
8190 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;
8191 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;
8192 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;
8194 memset(&caps, 0, sizeof(caps));
8195 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8196 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8197 if(caps.MaxPointSize < 32.0) {
8198 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8199 return;
8202 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8203 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8204 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8207 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8208 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8209 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8211 hr = IDirect3DDevice9_BeginScene(device);
8212 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8213 if(SUCCEEDED(hr)) {
8214 ptsize = 16.0;
8215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8216 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8218 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8220 ptsize = 32.0;
8221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8222 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8223 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8224 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8226 ptsize = 31.5;
8227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8228 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8230 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8232 if(caps.MaxPointSize >= 64.0) {
8233 ptsize = 64.0;
8234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8235 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8237 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8239 ptsize = 63.75;
8240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8243 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8246 ptsize = 1.0;
8247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8248 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8250 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8252 hr = IDirect3DDevice9_EndScene(device);
8253 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8255 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8256 color = getPixelColor(device, 64-9, 64-9);
8257 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8258 color = getPixelColor(device, 64-8, 64-8);
8259 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8260 color = getPixelColor(device, 64-7, 64-7);
8261 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8262 color = getPixelColor(device, 64+7, 64+7);
8263 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8264 color = getPixelColor(device, 64+8, 64+8);
8265 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8266 color = getPixelColor(device, 64+9, 64+9);
8267 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8269 color = getPixelColor(device, 128-17, 64-17);
8270 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8271 color = getPixelColor(device, 128-16, 64-16);
8272 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8273 color = getPixelColor(device, 128-15, 64-15);
8274 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8275 color = getPixelColor(device, 128+15, 64+15);
8276 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8277 color = getPixelColor(device, 128+16, 64+16);
8278 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8279 color = getPixelColor(device, 128+17, 64+17);
8280 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8282 color = getPixelColor(device, 192-17, 64-17);
8283 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8284 color = getPixelColor(device, 192-16, 64-16);
8285 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8286 color = getPixelColor(device, 192-15, 64-15);
8287 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8288 color = getPixelColor(device, 192+15, 64+15);
8289 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8290 color = getPixelColor(device, 192+16, 64+16);
8291 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8292 color = getPixelColor(device, 192+17, 64+17);
8293 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8295 if(caps.MaxPointSize >= 64.0) {
8296 color = getPixelColor(device, 256-33, 64-33);
8297 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8298 color = getPixelColor(device, 256-32, 64-32);
8299 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8300 color = getPixelColor(device, 256-31, 64-31);
8301 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8302 color = getPixelColor(device, 256+31, 64+31);
8303 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8304 color = getPixelColor(device, 256+32, 64+32);
8305 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8306 color = getPixelColor(device, 256+33, 64+33);
8307 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8309 color = getPixelColor(device, 384-33, 64-33);
8310 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8311 color = getPixelColor(device, 384-32, 64-32);
8312 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8313 color = getPixelColor(device, 384-31, 64-31);
8314 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8315 color = getPixelColor(device, 384+31, 64+31);
8316 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8317 color = getPixelColor(device, 384+32, 64+32);
8318 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8319 color = getPixelColor(device, 384+33, 64+33);
8320 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8323 color = getPixelColor(device, 320-1, 64-1);
8324 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8325 color = getPixelColor(device, 320-0, 64-0);
8326 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8327 color = getPixelColor(device, 320+1, 64+1);
8328 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8331 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8332 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8333 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8336 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8338 HRESULT hr;
8339 IDirect3DPixelShader9 *ps;
8340 IDirect3DTexture9 *tex1, *tex2;
8341 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8342 D3DCAPS9 caps;
8343 DWORD color;
8344 DWORD shader_code[] = {
8345 0xffff0300, /* ps_3_0 */
8346 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8347 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8348 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8349 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8350 0x0000ffff /* END */
8352 float quad[] = {
8353 -1.0, -1.0, 0.1,
8354 1.0, -1.0, 0.1,
8355 -1.0, 1.0, 0.1,
8356 1.0, 1.0, 0.1,
8358 float texquad[] = {
8359 -1.0, -1.0, 0.1, 0.0, 0.0,
8360 0.0, -1.0, 0.1, 1.0, 0.0,
8361 -1.0, 1.0, 0.1, 0.0, 1.0,
8362 0.0, 1.0, 0.1, 1.0, 1.0,
8364 0.0, -1.0, 0.1, 0.0, 0.0,
8365 1.0, -1.0, 0.1, 1.0, 0.0,
8366 0.0, 1.0, 0.1, 0.0, 1.0,
8367 1.0, 1.0, 0.1, 1.0, 1.0,
8370 memset(&caps, 0, sizeof(caps));
8371 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8372 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8373 if(caps.NumSimultaneousRTs < 2) {
8374 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8375 return;
8378 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8379 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8381 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8382 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8383 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8385 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8386 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8388 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8389 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8390 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8391 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8392 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8393 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8395 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8396 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8397 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8398 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8399 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8400 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8401 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8402 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8404 hr = IDirect3DDevice9_BeginScene(device);
8405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8406 if(SUCCEEDED(hr)) {
8407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8408 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8410 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8412 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8413 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8414 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8415 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8416 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8417 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8419 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8422 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8424 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8425 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8427 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8429 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8430 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8432 hr = IDirect3DDevice9_EndScene(device);
8433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8436 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8437 color = getPixelColor(device, 160, 240);
8438 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8439 color = getPixelColor(device, 480, 240);
8440 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8442 IDirect3DPixelShader9_Release(ps);
8443 IDirect3DTexture9_Release(tex1);
8444 IDirect3DTexture9_Release(tex2);
8445 IDirect3DSurface9_Release(surf1);
8446 IDirect3DSurface9_Release(surf2);
8447 IDirect3DSurface9_Release(backbuf);
8450 struct formats {
8451 const char *fmtName;
8452 D3DFORMAT textureFormat;
8453 DWORD resultColorBlending;
8454 DWORD resultColorNoBlending;
8457 const struct formats test_formats[] = {
8458 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8459 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8460 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8461 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8462 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8463 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8464 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8465 { NULL, 0 }
8468 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8470 HRESULT hr;
8471 IDirect3DTexture9 *offscreenTexture = NULL;
8472 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8473 IDirect3D9 *d3d = NULL;
8474 DWORD color;
8475 DWORD r0, g0, b0, r1, g1, b1;
8476 int fmt_index;
8478 static const float quad[][5] = {
8479 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8480 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8481 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8482 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8485 /* Quad with R=0x10, G=0x20 */
8486 static const struct vertex quad1[] = {
8487 {-1.0f, -1.0f, 0.1f, 0x80102000},
8488 {-1.0f, 1.0f, 0.1f, 0x80102000},
8489 { 1.0f, -1.0f, 0.1f, 0x80102000},
8490 { 1.0f, 1.0f, 0.1f, 0x80102000},
8493 /* Quad with R=0x20, G=0x10 */
8494 static const struct vertex quad2[] = {
8495 {-1.0f, -1.0f, 0.1f, 0x80201000},
8496 {-1.0f, 1.0f, 0.1f, 0x80201000},
8497 { 1.0f, -1.0f, 0.1f, 0x80201000},
8498 { 1.0f, 1.0f, 0.1f, 0x80201000},
8501 IDirect3DDevice9_GetDirect3D(device, &d3d);
8503 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8504 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8505 if(!backbuffer) {
8506 goto out;
8509 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8511 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8512 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8513 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8514 continue;
8517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8518 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8520 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8521 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8522 if(!offscreenTexture) {
8523 continue;
8526 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8527 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8528 if(!offscreen) {
8529 continue;
8532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8533 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8535 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8536 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8537 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8538 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8539 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8540 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8541 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8542 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8544 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8546 /* Below we will draw two quads with different colors and try to blend them together.
8547 * The result color is compared with the expected outcome.
8549 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8550 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8551 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8552 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8553 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8556 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8558 /* Draw a quad using color 0x0010200 */
8559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8560 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8562 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8564 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8566 /* Draw a quad using color 0x0020100 */
8567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8568 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8570 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8572 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8574 /* We don't want to blend the result on the backbuffer */
8575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8578 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8579 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8580 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8581 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8582 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8584 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8585 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8587 /* This time with the texture */
8588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8589 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8591 IDirect3DDevice9_EndScene(device);
8593 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8596 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8597 /* Compare the color of the center quad with our expectation */
8598 color = getPixelColor(device, 320, 240);
8599 r0 = (color & 0x00ff0000) >> 16;
8600 g0 = (color & 0x0000ff00) >> 8;
8601 b0 = (color & 0x000000ff) >> 0;
8603 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8604 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8605 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8607 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8608 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8609 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8610 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8611 } else {
8612 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8613 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8614 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8615 color = getPixelColor(device, 320, 240);
8616 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);
8619 IDirect3DDevice9_SetTexture(device, 0, NULL);
8620 if(offscreenTexture) {
8621 IDirect3DTexture9_Release(offscreenTexture);
8623 if(offscreen) {
8624 IDirect3DSurface9_Release(offscreen);
8628 out:
8629 /* restore things */
8630 if(backbuffer) {
8631 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8632 IDirect3DSurface9_Release(backbuffer);
8636 static void tssargtemp_test(IDirect3DDevice9 *device)
8638 HRESULT hr;
8639 DWORD color;
8640 static const struct vertex quad[] = {
8641 {-1.0, -1.0, 0.1, 0x00ff0000},
8642 { 1.0, -1.0, 0.1, 0x00ff0000},
8643 {-1.0, 1.0, 0.1, 0x00ff0000},
8644 { 1.0, 1.0, 0.1, 0x00ff0000}
8646 D3DCAPS9 caps;
8648 memset(&caps, 0, sizeof(caps));
8649 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8650 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8651 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8652 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8653 return;
8656 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8657 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8659 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8660 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8661 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8662 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8664 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8665 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8666 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8667 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8668 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8669 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8671 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8672 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8673 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8674 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8675 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8676 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8678 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8679 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8681 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8682 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8683 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8684 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8686 hr = IDirect3DDevice9_BeginScene(device);
8687 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8688 if(SUCCEEDED(hr)) {
8690 hr = IDirect3DDevice9_EndScene(device);
8691 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8693 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8695 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8696 color = getPixelColor(device, 320, 240);
8697 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8699 /* Set stage 1 back to default */
8700 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8701 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8703 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8704 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8705 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8706 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8707 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8708 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8709 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8712 struct testdata
8714 DWORD idxVertex; /* number of instances in the first stream */
8715 DWORD idxColor; /* number of instances in the second stream */
8716 DWORD idxInstance; /* should be 1 ?? */
8717 DWORD color1; /* color 1 instance */
8718 DWORD color2; /* color 2 instance */
8719 DWORD color3; /* color 3 instance */
8720 DWORD color4; /* color 4 instance */
8721 WORD strVertex; /* specify which stream to use 0-2*/
8722 WORD strColor;
8723 WORD strInstance;
8726 static const struct testdata testcases[]=
8728 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8729 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8730 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8731 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8732 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8733 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8734 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8735 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8736 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8737 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8738 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8739 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8740 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8741 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8742 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8744 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8745 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8749 /* Drawing Indexed Geometry with instances*/
8750 static void stream_test(IDirect3DDevice9 *device)
8752 IDirect3DVertexBuffer9 *vb = NULL;
8753 IDirect3DVertexBuffer9 *vb2 = NULL;
8754 IDirect3DVertexBuffer9 *vb3 = NULL;
8755 IDirect3DIndexBuffer9 *ib = NULL;
8756 IDirect3DVertexDeclaration9 *pDecl = NULL;
8757 IDirect3DVertexShader9 *shader = NULL;
8758 HRESULT hr;
8759 BYTE *data;
8760 DWORD color;
8761 DWORD ind;
8762 int i;
8764 const DWORD shader_code[] =
8766 0xfffe0101, /* vs_1_1 */
8767 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8768 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8769 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8770 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8771 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8772 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8773 0x0000ffff
8776 const float quad[][3] =
8778 {-0.5f, -0.5f, 1.1f}, /*0 */
8779 {-0.5f, 0.5f, 1.1f}, /*1 */
8780 { 0.5f, -0.5f, 1.1f}, /*2 */
8781 { 0.5f, 0.5f, 1.1f}, /*3 */
8784 const float vertcolor[][4] =
8786 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8787 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8788 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8789 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8792 /* 4 position for 4 instances */
8793 const float instancepos[][3] =
8795 {-0.6f,-0.6f, 0.0f},
8796 { 0.6f,-0.6f, 0.0f},
8797 { 0.6f, 0.6f, 0.0f},
8798 {-0.6f, 0.6f, 0.0f},
8801 short indices[] = {0, 1, 2, 1, 2, 3};
8803 D3DVERTEXELEMENT9 decl[] =
8805 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8806 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8807 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8808 D3DDECL_END()
8811 /* set the default value because it isn't done in wine? */
8812 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8813 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8815 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8816 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8817 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8819 /* check wrong cases */
8820 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8821 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8822 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8823 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8824 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8825 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8826 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8827 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8828 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8829 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8830 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8831 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8832 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8833 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8834 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8835 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8836 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8837 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8838 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8839 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8841 /* set the default value back */
8842 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8843 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8845 /* create all VertexBuffers*/
8846 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8847 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8848 if(!vb) {
8849 skip("Failed to create a vertex buffer\n");
8850 return;
8852 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8853 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8854 if(!vb2) {
8855 skip("Failed to create a vertex buffer\n");
8856 goto out;
8858 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8859 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8860 if(!vb3) {
8861 skip("Failed to create a vertex buffer\n");
8862 goto out;
8865 /* create IndexBuffer*/
8866 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8867 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8868 if(!ib) {
8869 skip("Failed to create a index buffer\n");
8870 goto out;
8873 /* copy all Buffers (Vertex + Index)*/
8874 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8875 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8876 memcpy(data, quad, sizeof(quad));
8877 hr = IDirect3DVertexBuffer9_Unlock(vb);
8878 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8879 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8880 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8881 memcpy(data, vertcolor, sizeof(vertcolor));
8882 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8883 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8884 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8885 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8886 memcpy(data, instancepos, sizeof(instancepos));
8887 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8888 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8889 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8890 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8891 memcpy(data, indices, sizeof(indices));
8892 hr = IDirect3DIndexBuffer9_Unlock(ib);
8893 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8895 /* create VertexShader */
8896 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8897 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8898 if(!shader) {
8899 skip("Failed to create a vetex shader\n");
8900 goto out;
8903 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8904 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8906 hr = IDirect3DDevice9_SetIndices(device, ib);
8907 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8909 /* run all tests */
8910 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8912 struct testdata act = testcases[i];
8913 decl[0].Stream = act.strVertex;
8914 decl[1].Stream = act.strColor;
8915 decl[2].Stream = act.strInstance;
8916 /* create VertexDeclarations */
8917 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8918 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8921 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8923 hr = IDirect3DDevice9_BeginScene(device);
8924 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8925 if(SUCCEEDED(hr))
8927 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8930 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8931 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8932 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8933 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8935 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8936 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8937 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8938 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8940 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8941 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8942 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8943 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8945 /* don't know if this is right (1*3 and 4*1)*/
8946 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8947 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8948 hr = IDirect3DDevice9_EndScene(device);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8951 /* set all StreamSource && StreamSourceFreq back to default */
8952 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8953 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8954 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8955 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8956 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8957 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8958 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8959 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8960 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8961 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8962 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8963 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8966 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8967 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8969 hr = IDirect3DVertexDeclaration9_Release(pDecl);
8970 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8972 color = getPixelColor(device, 160, 360);
8973 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8974 color = getPixelColor(device, 480, 360);
8975 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8976 color = getPixelColor(device, 480, 120);
8977 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8978 color = getPixelColor(device, 160, 120);
8979 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8982 hr = IDirect3DDevice9_SetIndices(device, NULL);
8983 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8985 out:
8986 if(vb) IDirect3DVertexBuffer9_Release(vb);
8987 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8988 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8989 if(ib)IDirect3DIndexBuffer9_Release(ib);
8990 if(shader)IDirect3DVertexShader9_Release(shader);
8993 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8994 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8995 IDirect3DTexture9 *dsttex = NULL;
8996 HRESULT hr;
8997 DWORD color;
8998 D3DRECT r1 = {0, 0, 50, 50 };
8999 D3DRECT r2 = {50, 0, 100, 50 };
9000 D3DRECT r3 = {50, 50, 100, 100};
9001 D3DRECT r4 = {0, 50, 50, 100};
9002 const float quad[] = {
9003 -1.0, -1.0, 0.1, 0.0, 0.0,
9004 1.0, -1.0, 0.1, 1.0, 0.0,
9005 -1.0, 1.0, 0.1, 0.0, 1.0,
9006 1.0, 1.0, 0.1, 1.0, 1.0,
9009 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9010 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
9012 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9013 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
9014 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9015 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
9017 if(!src || !dsttex) {
9018 skip("One or more test resources could not be created\n");
9019 goto cleanup;
9022 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9023 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
9025 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9026 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9028 /* Clear the StretchRect destination for debugging */
9029 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9030 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9031 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9034 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9035 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9037 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9038 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9039 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9041 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9042 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9043 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9046 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9047 * the target -> texture GL blit path
9049 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9050 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9051 IDirect3DSurface9_Release(dst);
9053 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9054 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9056 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9057 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9059 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9060 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9061 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9062 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9065 hr = IDirect3DDevice9_BeginScene(device);
9066 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9067 if(SUCCEEDED(hr)) {
9068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9069 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9070 hr = IDirect3DDevice9_EndScene(device);
9071 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9076 color = getPixelColor(device, 160, 360);
9077 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9078 color = getPixelColor(device, 480, 360);
9079 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9080 color = getPixelColor(device, 480, 120);
9081 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9082 color = getPixelColor(device, 160, 120);
9083 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9085 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9086 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9087 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9088 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9090 cleanup:
9091 if(src) IDirect3DSurface9_Release(src);
9092 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9093 if(dsttex) IDirect3DTexture9_Release(dsttex);
9096 static void texop_test(IDirect3DDevice9 *device)
9098 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9099 IDirect3DTexture9 *texture = NULL;
9100 D3DLOCKED_RECT locked_rect;
9101 D3DCOLOR color;
9102 D3DCAPS9 caps;
9103 HRESULT hr;
9104 int i;
9106 static const struct {
9107 float x, y, z;
9108 float s, t;
9109 D3DCOLOR diffuse;
9110 } quad[] = {
9111 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9112 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9113 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9114 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9117 static const D3DVERTEXELEMENT9 decl_elements[] = {
9118 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9119 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9120 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9121 D3DDECL_END()
9124 static const struct {
9125 D3DTEXTUREOP op;
9126 const char *name;
9127 DWORD caps_flag;
9128 D3DCOLOR result;
9129 } test_data[] = {
9130 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9131 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9132 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9133 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9134 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9135 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9136 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9137 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9138 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9139 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9140 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9141 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9142 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9143 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9144 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9145 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9146 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9147 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9148 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9149 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9150 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9151 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9152 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9155 memset(&caps, 0, sizeof(caps));
9156 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9157 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9159 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9160 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9161 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9162 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9164 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9165 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9166 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9167 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9168 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9169 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9170 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9171 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9172 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9174 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9175 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9176 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9177 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9178 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9179 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9181 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9182 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9185 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9187 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9189 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9192 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9194 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9196 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9198 skip("tex operation %s not supported\n", test_data[i].name);
9199 continue;
9202 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9203 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x (%s)\n",
9204 test_data[i].name, hr, DXGetErrorString9(hr));
9206 hr = IDirect3DDevice9_BeginScene(device);
9207 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9210 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9212 hr = IDirect3DDevice9_EndScene(device);
9213 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9215 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9216 ok(SUCCEEDED(hr), "Present failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9218 color = getPixelColor(device, 320, 240);
9219 ok(color_match(color, test_data[i].result, 1), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9220 test_data[i].name, color, test_data[i].result);
9223 if (texture) IDirect3DTexture9_Release(texture);
9224 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9227 START_TEST(visual)
9229 IDirect3DDevice9 *device_ptr;
9230 D3DCAPS9 caps;
9231 HRESULT hr;
9232 DWORD color;
9234 d3d9_handle = LoadLibraryA("d3d9.dll");
9235 if (!d3d9_handle)
9237 skip("Could not load d3d9.dll\n");
9238 return;
9241 device_ptr = init_d3d9();
9242 if (!device_ptr)
9244 skip("Creating the device failed\n");
9245 return;
9248 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9250 /* Check for the reliability of the returned data */
9251 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9252 if(FAILED(hr))
9254 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9255 goto cleanup;
9257 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9259 color = getPixelColor(device_ptr, 1, 1);
9260 if(color !=0x00ff0000)
9262 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9263 goto cleanup;
9266 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9267 if(FAILED(hr))
9269 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9270 goto cleanup;
9272 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9274 color = getPixelColor(device_ptr, 639, 479);
9275 if(color != 0x0000ddee)
9277 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9278 goto cleanup;
9281 /* Now execute the real tests */
9282 stretchrect_test(device_ptr);
9283 lighting_test(device_ptr);
9284 clear_test(device_ptr);
9285 fog_test(device_ptr);
9286 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9288 test_cube_wrap(device_ptr);
9289 } else {
9290 skip("No cube texture support\n");
9292 z_range_test(device_ptr);
9293 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9295 maxmip_test(device_ptr);
9297 else
9299 skip("No mipmap support\n");
9301 offscreen_test(device_ptr);
9302 alpha_test(device_ptr);
9303 shademode_test(device_ptr);
9304 srgbtexture_test(device_ptr);
9305 release_buffer_test(device_ptr);
9306 float_texture_test(device_ptr);
9307 g16r16_texture_test(device_ptr);
9308 pixelshader_blending_test(device_ptr);
9309 texture_transform_flags_test(device_ptr);
9310 autogen_mipmap_test(device_ptr);
9311 fixed_function_decl_test(device_ptr);
9312 conditional_np2_repeat_test(device_ptr);
9313 fixed_function_bumpmap_test(device_ptr);
9314 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9315 stencil_cull_test(device_ptr);
9316 } else {
9317 skip("No two sided stencil support\n");
9319 pointsize_test(device_ptr);
9320 tssargtemp_test(device_ptr);
9321 np2_stretch_rect_test(device_ptr);
9323 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9325 test_constant_clamp_vs(device_ptr);
9326 test_compare_instructions(device_ptr);
9328 else skip("No vs_1_1 support\n");
9330 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9332 test_mova(device_ptr);
9333 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9334 test_vshader_input(device_ptr);
9335 test_vshader_float16(device_ptr);
9336 stream_test(device_ptr);
9337 } else {
9338 skip("No vs_3_0 support\n");
9341 else skip("No vs_2_0 support\n");
9343 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9345 fog_with_shader_test(device_ptr);
9346 fog_srgbwrite_test(device_ptr);
9348 else skip("No vs_1_1 and ps_1_1 support\n");
9350 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9352 texbem_test(device_ptr);
9353 texdepth_test(device_ptr);
9354 texkill_test(device_ptr);
9355 x8l8v8u8_test(device_ptr);
9356 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9357 constant_clamp_ps_test(device_ptr);
9358 cnd_test(device_ptr);
9359 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9360 dp2add_ps_test(device_ptr);
9361 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9362 nested_loop_test(device_ptr);
9363 fixed_function_varying_test(device_ptr);
9364 vFace_register_test(device_ptr);
9365 vpos_register_test(device_ptr);
9366 multiple_rendertargets_test(device_ptr);
9367 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9368 vshader_version_varying_test(device_ptr);
9369 pshader_version_varying_test(device_ptr);
9370 } else {
9371 skip("No vs_3_0 support\n");
9373 } else {
9374 skip("No ps_3_0 support\n");
9376 } else {
9377 skip("No ps_2_0 support\n");
9381 else skip("No ps_1_1 support\n");
9382 texop_test(device_ptr);
9384 cleanup:
9385 if(device_ptr) {
9386 ULONG ref;
9388 D3DPRESENT_PARAMETERS present_parameters;
9389 IDirect3DSwapChain9 *swapchain;
9390 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9391 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9392 IDirect3DSwapChain9_Release(swapchain);
9393 ref = IDirect3DDevice9_Release(device_ptr);
9394 DestroyWindow(present_parameters.hDeviceWindow);
9395 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);