push 7f8c39dca3a5819e8ef115eebf7abed537de3a22
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob611a589963c312d92d9b5f0c1e672708a8e7b748
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(color_match(color, test_data[i].color[j], 13),
1467 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1468 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1472 /* reset states */
1473 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1474 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1475 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1476 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1477 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1478 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1480 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1482 IDirect3DVertexShader9_Release(vertex_shader[1]);
1483 IDirect3DVertexShader9_Release(vertex_shader[2]);
1484 IDirect3DPixelShader9_Release(pixel_shader[1]);
1485 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1488 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1489 unsigned int i, x, y;
1490 HRESULT hr;
1491 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1492 D3DLOCKED_RECT locked_rect;
1494 /* Generate the textures */
1495 for(i=0; i<2; i++)
1497 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1498 D3DPOOL_MANAGED, &texture[i], NULL);
1499 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1501 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1502 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1503 for (y = 0; y < 128; ++y)
1505 if(i)
1506 { /* Set up black texture with 2x2 texel white spot in the middle */
1507 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1508 for (x = 0; x < 128; ++x)
1510 if(y>62 && y<66 && x>62 && x<66)
1511 *ptr++ = 0xffffffff;
1512 else
1513 *ptr++ = 0xff000000;
1516 else
1517 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1518 * (if multiplied with bumpenvmat)
1520 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1521 for (x = 0; x < 128; ++x)
1523 if(abs(x-64)>abs(y-64))
1525 if(x < 64)
1526 *ptr++ = 0xc000;
1527 else
1528 *ptr++ = 0x4000;
1530 else
1532 if(y < 64)
1533 *ptr++ = 0x0040;
1534 else
1535 *ptr++ = 0x00c0;
1540 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1541 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1543 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1544 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1546 /* Disable texture filtering */
1547 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1548 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1549 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1550 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1552 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1553 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1554 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1555 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1559 /* test the behavior of the texbem instruction
1560 * with normal 2D and projective 2D textures
1562 static void texbem_test(IDirect3DDevice9 *device)
1564 HRESULT hr;
1565 DWORD color;
1566 int i;
1568 static const DWORD pixel_shader_code[] = {
1569 0xffff0101, /* ps_1_1*/
1570 0x00000042, 0xb00f0000, /* tex t0*/
1571 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1572 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1573 0x0000ffff
1575 static const DWORD double_texbem_code[] = {
1576 0xffff0103, /* ps_1_3 */
1577 0x00000042, 0xb00f0000, /* tex t0 */
1578 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1579 0x00000042, 0xb00f0002, /* tex t2 */
1580 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1581 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1582 0x0000ffff /* end */
1586 static const float quad[][7] = {
1587 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1588 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1589 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1590 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1592 static const float quad_proj[][9] = {
1593 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1594 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1595 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1596 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1599 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1600 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1601 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1602 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1603 D3DDECL_END()
1605 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1606 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1607 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1608 D3DDECL_END()
1609 } };
1611 /* use asymmetric matrix to test loading */
1612 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1614 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1615 IDirect3DPixelShader9 *pixel_shader = NULL;
1616 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1617 D3DLOCKED_RECT locked_rect;
1619 generate_bumpmap_textures(device);
1621 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1622 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1623 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1624 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1625 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1627 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1628 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1630 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1631 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1633 for(i=0; i<2; i++)
1635 if(i)
1637 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1638 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1641 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1642 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1643 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1644 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1646 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1647 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1648 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1649 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1651 hr = IDirect3DDevice9_BeginScene(device);
1652 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1654 if(!i)
1655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1656 else
1657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1658 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1660 hr = IDirect3DDevice9_EndScene(device);
1661 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1663 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1664 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1666 color = getPixelColor(device, 320-32, 240);
1667 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
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, 240-32);
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);
1675 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1676 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1677 IDirect3DPixelShader9_Release(pixel_shader);
1679 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1680 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1681 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1684 /* clean up */
1685 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1686 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1688 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1689 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1691 for(i=0; i<2; i++)
1693 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1694 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1695 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1696 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1697 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1698 IDirect3DTexture9_Release(texture);
1701 /* Test double texbem */
1702 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1703 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1704 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1705 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1706 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1707 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1708 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1709 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1711 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1712 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1713 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1714 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1716 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1717 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1719 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1720 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1721 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1722 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1723 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1724 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1727 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1728 #define tex 0x00ff0000
1729 #define tex1 0x0000ff00
1730 #define origin 0x000000ff
1731 static const DWORD pixel_data[] = {
1732 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1733 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1734 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1735 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1736 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1737 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1738 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1739 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1741 #undef tex1
1742 #undef tex2
1743 #undef origin
1745 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1746 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1747 for(i = 0; i < 8; i++) {
1748 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1750 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1751 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1754 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1755 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1756 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1757 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1758 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1759 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1760 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1761 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1762 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1763 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1765 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1767 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1768 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1769 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1770 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1771 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1772 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1774 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1775 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1776 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1777 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1778 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1779 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1781 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1782 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1783 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1784 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1785 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1786 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1787 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1788 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1790 hr = IDirect3DDevice9_BeginScene(device);
1791 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1792 if(SUCCEEDED(hr)) {
1793 static const float double_quad[] = {
1794 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1795 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1796 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1797 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1801 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1802 hr = IDirect3DDevice9_EndScene(device);
1803 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1806 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1807 color = getPixelColor(device, 320, 240);
1808 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1810 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1811 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1812 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1813 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1814 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1815 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1816 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1817 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1818 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1819 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1821 IDirect3DPixelShader9_Release(pixel_shader);
1822 IDirect3DTexture9_Release(texture);
1823 IDirect3DTexture9_Release(texture1);
1824 IDirect3DTexture9_Release(texture2);
1827 static void z_range_test(IDirect3DDevice9 *device)
1829 const struct vertex quad[] =
1831 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1832 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1833 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1834 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1836 const struct vertex quad2[] =
1838 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1839 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1840 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1841 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1844 const struct tvertex quad3[] =
1846 { 0, 240, 1.1f, 1.0, 0xffffff00},
1847 { 0, 480, 1.1f, 1.0, 0xffffff00},
1848 { 640, 240, -1.1f, 1.0, 0xffffff00},
1849 { 640, 480, -1.1f, 1.0, 0xffffff00},
1851 const struct tvertex quad4[] =
1853 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1854 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1855 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1856 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1858 HRESULT hr;
1859 DWORD color;
1860 IDirect3DVertexShader9 *shader;
1861 IDirect3DVertexDeclaration9 *decl;
1862 D3DCAPS9 caps;
1863 const DWORD shader_code[] = {
1864 0xfffe0101, /* vs_1_1 */
1865 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1866 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1867 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1868 0x0000ffff /* end */
1870 static const D3DVERTEXELEMENT9 decl_elements[] = {
1871 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1872 D3DDECL_END()
1874 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1875 * then call Present. Then clear the color buffer to make sure it has some defined content
1876 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1877 * by the depth value.
1879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1880 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1884 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1885 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1892 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1893 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1895 hr = IDirect3DDevice9_BeginScene(device);
1896 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1897 if(hr == D3D_OK)
1899 /* Test the untransformed vertex path */
1900 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1901 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1905 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1907 /* Test the transformed vertex path */
1908 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1909 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1912 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1915 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1916 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1918 hr = IDirect3DDevice9_EndScene(device);
1919 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1922 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1923 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1925 /* Do not test the exact corner pixels, but go pretty close to them */
1927 /* Clipped because z > 1.0 */
1928 color = getPixelColor(device, 28, 238);
1929 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1930 color = getPixelColor(device, 28, 241);
1931 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1933 /* Not clipped, > z buffer clear value(0.75) */
1934 color = getPixelColor(device, 31, 238);
1935 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1936 color = getPixelColor(device, 31, 241);
1937 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1938 color = getPixelColor(device, 100, 238);
1939 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1940 color = getPixelColor(device, 100, 241);
1941 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1943 /* Not clipped, < z buffer clear value */
1944 color = getPixelColor(device, 104, 238);
1945 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1946 color = getPixelColor(device, 104, 241);
1947 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1948 color = getPixelColor(device, 318, 238);
1949 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1950 color = getPixelColor(device, 318, 241);
1951 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1953 /* Clipped because z < 0.0 */
1954 color = getPixelColor(device, 321, 238);
1955 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1956 color = getPixelColor(device, 321, 241);
1957 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1959 /* Test the shader path */
1960 IDirect3DDevice9_GetDeviceCaps(device, &caps);
1961 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1962 skip("Vertex shaders not supported\n");
1963 goto out;
1965 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1966 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1967 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1968 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1972 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1973 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1974 IDirect3DDevice9_SetVertexShader(device, shader);
1975 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1977 hr = IDirect3DDevice9_BeginScene(device);
1978 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1979 if(hr == D3D_OK)
1981 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1982 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1983 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1985 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1988 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1990 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1992 hr = IDirect3DDevice9_EndScene(device);
1993 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1996 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1997 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1998 IDirect3DDevice9_SetVertexShader(device, NULL);
1999 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
2001 IDirect3DVertexDeclaration9_Release(decl);
2002 IDirect3DVertexShader9_Release(shader);
2004 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2005 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2006 /* Z < 1.0 */
2007 color = getPixelColor(device, 28, 238);
2008 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2010 /* 1.0 < z < 0.75 */
2011 color = getPixelColor(device, 31, 238);
2012 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2013 color = getPixelColor(device, 100, 238);
2014 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2016 /* 0.75 < z < 0.0 */
2017 color = getPixelColor(device, 104, 238);
2018 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2019 color = getPixelColor(device, 318, 238);
2020 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2022 /* 0.0 < z */
2023 color = getPixelColor(device, 321, 238);
2024 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2026 out:
2027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2028 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2030 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2035 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2037 D3DSURFACE_DESC desc;
2038 D3DLOCKED_RECT l;
2039 HRESULT hr;
2040 unsigned int x, y;
2041 DWORD *mem;
2043 memset(&desc, 0, sizeof(desc));
2044 memset(&l, 0, sizeof(l));
2045 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2046 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2047 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2048 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2049 if(FAILED(hr)) return;
2051 for(y = 0; y < desc.Height; y++)
2053 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2054 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2056 mem[x] = color;
2059 hr = IDirect3DSurface9_UnlockRect(surface);
2060 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2063 /* This tests a variety of possible StretchRect() situations */
2064 static void stretchrect_test(IDirect3DDevice9 *device)
2066 HRESULT hr;
2067 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2068 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2069 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2070 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2071 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2072 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2073 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2074 IDirect3DSurface9 *orig_rt = NULL;
2075 DWORD color;
2077 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2078 ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2079 if(!orig_rt) {
2080 goto out;
2083 /* Create our temporary surfaces in system memory */
2084 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2085 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2086 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2087 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2089 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2090 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2091 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2092 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, 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_offscreen_dest64, NULL);
2095 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2097 /* Create render target surfaces */
2098 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2099 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2100 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, 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_rt_dest64, NULL );
2103 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2105 /* Create render target textures */
2106 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2107 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2108 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, 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_rt_dest64, NULL);
2111 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2112 if (tex_rt32) {
2113 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2114 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2116 if (tex_rt64) {
2117 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2118 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2120 if (tex_rt_dest64) {
2121 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2122 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2125 /* Create regular textures in D3DPOOL_DEFAULT */
2126 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2127 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2128 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, 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, &tex_dest64, NULL);
2131 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2132 if (tex32) {
2133 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2134 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2136 if (tex64) {
2137 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2138 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2140 if (tex_dest64) {
2141 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2142 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2145 /*********************************************************************
2146 * Tests for when the source parameter is an offscreen plain surface *
2147 *********************************************************************/
2149 /* Fill the offscreen 64x64 surface with green */
2150 if (surf_offscreen64)
2151 fill_surface(surf_offscreen64, 0xff00ff00);
2153 /* offscreenplain ==> offscreenplain, same size */
2154 if(surf_offscreen64 && surf_offscreen_dest64) {
2155 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2156 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2158 if (hr == D3D_OK) {
2159 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2160 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2164 /* offscreenplain ==> rendertarget texture, same size */
2165 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2166 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2167 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2169 /* We can't lock rendertarget textures, so copy to our temp surface first */
2170 if (hr == D3D_OK) {
2171 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2172 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2175 if (hr == D3D_OK) {
2176 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2177 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2181 /* offscreenplain ==> rendertarget surface, same size */
2182 if(surf_offscreen64 && surf_rt_dest64) {
2183 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2184 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2186 if (hr == D3D_OK) {
2187 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2188 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2192 /* offscreenplain ==> texture, same size (should fail) */
2193 if(surf_offscreen64 && surf_tex_dest64) {
2194 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2195 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2198 /* Fill the smaller offscreen surface with red */
2199 fill_surface(surf_offscreen32, 0xffff0000);
2201 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2202 if(surf_offscreen32 && surf_offscreen64) {
2203 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2204 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2207 /* offscreenplain ==> rendertarget texture, scaling */
2208 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2209 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2210 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2212 /* We can't lock rendertarget textures, so copy to our temp surface first */
2213 if (hr == D3D_OK) {
2214 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2215 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2218 if (hr == D3D_OK) {
2219 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2220 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2224 /* offscreenplain ==> rendertarget surface, scaling */
2225 if(surf_offscreen32 && surf_rt_dest64) {
2226 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2227 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2229 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2230 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2233 /* offscreenplain ==> texture, scaling (should fail) */
2234 if(surf_offscreen32 && surf_tex_dest64) {
2235 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2236 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2239 /************************************************************
2240 * Tests for when the source parameter is a regular texture *
2241 ************************************************************/
2243 /* Fill the surface of the regular texture with blue */
2244 if (surf_tex64 && surf_temp64) {
2245 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2246 fill_surface(surf_temp64, 0xff0000ff);
2247 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2248 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2251 /* texture ==> offscreenplain, same size */
2252 if(surf_tex64 && surf_offscreen64) {
2253 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2254 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2257 /* texture ==> rendertarget texture, same size */
2258 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2259 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2260 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2262 /* We can't lock rendertarget textures, so copy to our temp surface first */
2263 if (hr == D3D_OK) {
2264 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2265 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2268 if (hr == D3D_OK) {
2269 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2270 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2274 /* texture ==> rendertarget surface, same size */
2275 if(surf_tex64 && surf_rt_dest64) {
2276 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2277 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2279 if (hr == D3D_OK) {
2280 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2281 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2285 /* texture ==> texture, same size (should fail) */
2286 if(surf_tex64 && surf_tex_dest64) {
2287 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2288 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2291 /* Fill the surface of the smaller regular texture with red */
2292 if (surf_tex32 && surf_temp32) {
2293 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2294 fill_surface(surf_temp32, 0xffff0000);
2295 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2296 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2299 /* texture ==> offscreenplain, scaling (should fail) */
2300 if(surf_tex32 && surf_offscreen64) {
2301 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2302 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2305 /* texture ==> rendertarget texture, scaling */
2306 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2307 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2308 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2310 /* We can't lock rendertarget textures, so copy to our temp surface first */
2311 if (hr == D3D_OK) {
2312 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2313 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2316 if (hr == D3D_OK) {
2317 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2318 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2322 /* texture ==> rendertarget surface, scaling */
2323 if(surf_tex32 && surf_rt_dest64) {
2324 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2325 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2327 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2328 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2331 /* texture ==> texture, scaling (should fail) */
2332 if(surf_tex32 && surf_tex_dest64) {
2333 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2334 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2337 /*****************************************************************
2338 * Tests for when the source parameter is a rendertarget texture *
2339 *****************************************************************/
2341 /* Fill the surface of the rendertarget texture with white */
2342 if (surf_tex_rt64 && surf_temp64) {
2343 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2344 fill_surface(surf_temp64, 0xffffffff);
2345 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2346 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2349 /* rendertarget texture ==> offscreenplain, same size */
2350 if(surf_tex_rt64 && surf_offscreen64) {
2351 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2352 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2355 /* rendertarget texture ==> rendertarget texture, same size */
2356 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2357 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2358 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2360 /* We can't lock rendertarget textures, so copy to our temp surface first */
2361 if (hr == D3D_OK) {
2362 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2363 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2366 if (hr == D3D_OK) {
2367 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2368 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2372 /* rendertarget texture ==> rendertarget surface, same size */
2373 if(surf_tex_rt64 && surf_rt_dest64) {
2374 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2375 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2377 if (hr == D3D_OK) {
2378 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2379 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2383 /* rendertarget texture ==> texture, same size (should fail) */
2384 if(surf_tex_rt64 && surf_tex_dest64) {
2385 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2386 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2389 /* Fill the surface of the smaller rendertarget texture with red */
2390 if (surf_tex_rt32 && surf_temp32) {
2391 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2392 fill_surface(surf_temp32, 0xffff0000);
2393 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2394 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2397 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2398 if(surf_tex_rt32 && surf_offscreen64) {
2399 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2400 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2403 /* rendertarget texture ==> rendertarget texture, scaling */
2404 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2405 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2406 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2408 /* We can't lock rendertarget textures, so copy to our temp surface first */
2409 if (hr == D3D_OK) {
2410 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2411 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2414 if (hr == D3D_OK) {
2415 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2416 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2420 /* rendertarget texture ==> rendertarget surface, scaling */
2421 if(surf_tex_rt32 && surf_rt_dest64) {
2422 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2423 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2425 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2426 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2429 /* rendertarget texture ==> texture, scaling (should fail) */
2430 if(surf_tex_rt32 && surf_tex_dest64) {
2431 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2432 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2435 /*****************************************************************
2436 * Tests for when the source parameter is a rendertarget surface *
2437 *****************************************************************/
2439 /* Fill the surface of the rendertarget surface with black */
2440 if (surf_rt64)
2441 fill_surface(surf_rt64, 0xff000000);
2443 /* rendertarget texture ==> offscreenplain, same size */
2444 if(surf_rt64 && surf_offscreen64) {
2445 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2446 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2449 /* rendertarget surface ==> rendertarget texture, same size */
2450 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2451 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2452 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2454 /* We can't lock rendertarget textures, so copy to our temp surface first */
2455 if (hr == D3D_OK) {
2456 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2457 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2460 if (hr == D3D_OK) {
2461 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2462 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2466 /* rendertarget surface ==> rendertarget surface, same size */
2467 if(surf_rt64 && surf_rt_dest64) {
2468 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2469 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2471 if (hr == D3D_OK) {
2472 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2473 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2477 /* rendertarget surface ==> texture, same size (should fail) */
2478 if(surf_rt64 && surf_tex_dest64) {
2479 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2480 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2483 /* Fill the surface of the smaller rendertarget texture with red */
2484 if (surf_rt32)
2485 fill_surface(surf_rt32, 0xffff0000);
2487 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2488 if(surf_rt32 && surf_offscreen64) {
2489 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2490 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2493 /* rendertarget surface ==> rendertarget texture, scaling */
2494 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2495 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2496 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2498 /* We can't lock rendertarget textures, so copy to our temp surface first */
2499 if (hr == D3D_OK) {
2500 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2501 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2504 if (hr == D3D_OK) {
2505 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2506 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2510 /* rendertarget surface ==> rendertarget surface, scaling */
2511 if(surf_rt32 && surf_rt_dest64) {
2512 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2513 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2515 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2516 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2519 /* rendertarget surface ==> texture, scaling (should fail) */
2520 if(surf_rt32 && surf_tex_dest64) {
2521 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2522 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2525 /* TODO: Test when source and destination RECT parameters are given... */
2526 /* TODO: Test format conversions */
2529 out:
2530 /* Clean up */
2531 if (surf_rt32)
2532 IDirect3DSurface9_Release(surf_rt32);
2533 if (surf_rt64)
2534 IDirect3DSurface9_Release(surf_rt64);
2535 if (surf_rt_dest64)
2536 IDirect3DSurface9_Release(surf_rt_dest64);
2537 if (surf_temp32)
2538 IDirect3DSurface9_Release(surf_temp32);
2539 if (surf_temp64)
2540 IDirect3DSurface9_Release(surf_temp64);
2541 if (surf_offscreen32)
2542 IDirect3DSurface9_Release(surf_offscreen32);
2543 if (surf_offscreen64)
2544 IDirect3DSurface9_Release(surf_offscreen64);
2545 if (surf_offscreen_dest64)
2546 IDirect3DSurface9_Release(surf_offscreen_dest64);
2548 if (tex_rt32) {
2549 if (surf_tex_rt32)
2550 IDirect3DSurface9_Release(surf_tex_rt32);
2551 IDirect3DTexture9_Release(tex_rt32);
2553 if (tex_rt64) {
2554 if (surf_tex_rt64)
2555 IDirect3DSurface9_Release(surf_tex_rt64);
2556 IDirect3DTexture9_Release(tex_rt64);
2558 if (tex_rt_dest64) {
2559 if (surf_tex_rt_dest64)
2560 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2561 IDirect3DTexture9_Release(tex_rt_dest64);
2563 if (tex32) {
2564 if (surf_tex32)
2565 IDirect3DSurface9_Release(surf_tex32);
2566 IDirect3DTexture9_Release(tex32);
2568 if (tex64) {
2569 if (surf_tex64)
2570 IDirect3DSurface9_Release(surf_tex64);
2571 IDirect3DTexture9_Release(tex64);
2573 if (tex_dest64) {
2574 if (surf_tex_dest64)
2575 IDirect3DSurface9_Release(surf_tex_dest64);
2576 IDirect3DTexture9_Release(tex_dest64);
2579 if (orig_rt) {
2580 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2581 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2582 IDirect3DSurface9_Release(orig_rt);
2586 static void maxmip_test(IDirect3DDevice9 *device)
2588 IDirect3DTexture9 *texture = NULL;
2589 IDirect3DSurface9 *surface = NULL;
2590 HRESULT hr;
2591 DWORD color;
2592 const float quads[] = {
2593 -1.0, -1.0, 0.0, 0.0, 0.0,
2594 -1.0, 0.0, 0.0, 0.0, 1.0,
2595 0.0, -1.0, 0.0, 1.0, 0.0,
2596 0.0, 0.0, 0.0, 1.0, 1.0,
2598 0.0, -1.0, 0.0, 0.0, 0.0,
2599 0.0, 0.0, 0.0, 0.0, 1.0,
2600 1.0, -1.0, 0.0, 1.0, 0.0,
2601 1.0, 0.0, 0.0, 1.0, 1.0,
2603 0.0, 0.0, 0.0, 0.0, 0.0,
2604 0.0, 1.0, 0.0, 0.0, 1.0,
2605 1.0, 0.0, 0.0, 1.0, 0.0,
2606 1.0, 1.0, 0.0, 1.0, 1.0,
2608 -1.0, 0.0, 0.0, 0.0, 0.0,
2609 -1.0, 1.0, 0.0, 0.0, 1.0,
2610 0.0, 0.0, 0.0, 1.0, 0.0,
2611 0.0, 1.0, 0.0, 1.0, 1.0,
2614 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2615 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2617 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2618 &texture, NULL);
2619 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2620 if(!texture)
2622 skip("Failed to create test texture\n");
2623 return;
2626 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2627 fill_surface(surface, 0xffff0000);
2628 IDirect3DSurface9_Release(surface);
2629 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2630 fill_surface(surface, 0xff00ff00);
2631 IDirect3DSurface9_Release(surface);
2632 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2633 fill_surface(surface, 0xff0000ff);
2634 IDirect3DSurface9_Release(surface);
2636 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2637 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2638 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2639 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2641 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2642 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2644 hr = IDirect3DDevice9_BeginScene(device);
2645 if(SUCCEEDED(hr))
2647 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2648 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2650 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2652 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2653 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2655 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2657 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2658 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2660 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2662 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2663 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2665 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2666 hr = IDirect3DDevice9_EndScene(device);
2669 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2670 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2671 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2672 color = getPixelColor(device, 160, 360);
2673 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2674 color = getPixelColor(device, 160, 120);
2675 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2676 color = getPixelColor(device, 480, 120);
2677 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2678 color = getPixelColor(device, 480, 360);
2679 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2681 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2682 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2684 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2685 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2687 hr = IDirect3DDevice9_BeginScene(device);
2688 if(SUCCEEDED(hr))
2690 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2691 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2693 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2695 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2696 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2698 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2700 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2701 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2705 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2706 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2707 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2708 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2709 hr = IDirect3DDevice9_EndScene(device);
2712 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2713 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2714 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2715 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2717 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2718 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2719 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2720 * samples from the highest level in the texture(level 2)
2722 color = getPixelColor(device, 160, 360);
2723 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2724 color = getPixelColor(device, 160, 120);
2725 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2726 color = getPixelColor(device, 480, 120);
2727 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2728 color = getPixelColor(device, 480, 360);
2729 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2731 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2732 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2733 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2734 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2735 IDirect3DTexture9_Release(texture);
2738 static void release_buffer_test(IDirect3DDevice9 *device)
2740 IDirect3DVertexBuffer9 *vb = NULL;
2741 IDirect3DIndexBuffer9 *ib = NULL;
2742 HRESULT hr;
2743 BYTE *data;
2744 long ref;
2746 static const struct vertex quad[] = {
2747 {-1.0, -1.0, 0.1, 0xffff0000},
2748 {-1.0, 1.0, 0.1, 0xffff0000},
2749 { 1.0, 1.0, 0.1, 0xffff0000},
2751 {-1.0, -1.0, 0.1, 0xff00ff00},
2752 {-1.0, 1.0, 0.1, 0xff00ff00},
2753 { 1.0, 1.0, 0.1, 0xff00ff00}
2755 short indices[] = {3, 4, 5};
2757 /* Index and vertex buffers should always be creatable */
2758 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2759 D3DPOOL_MANAGED, &vb, NULL);
2760 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2761 if(!vb) {
2762 skip("Failed to create a vertex buffer\n");
2763 return;
2765 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2766 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2767 if(!ib) {
2768 skip("Failed to create an index buffer\n");
2769 return;
2772 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2773 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2774 memcpy(data, quad, sizeof(quad));
2775 hr = IDirect3DVertexBuffer9_Unlock(vb);
2776 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2778 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2779 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2780 memcpy(data, indices, sizeof(indices));
2781 hr = IDirect3DIndexBuffer9_Unlock(ib);
2782 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2784 hr = IDirect3DDevice9_SetIndices(device, ib);
2785 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2786 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2787 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2789 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2791 /* Now destroy the bound index buffer and draw again */
2792 ref = IDirect3DIndexBuffer9_Release(ib);
2793 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2796 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2798 hr = IDirect3DDevice9_BeginScene(device);
2799 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2800 if(SUCCEEDED(hr))
2802 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2803 * making assumptions about the indices or vertices
2805 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2806 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2807 hr = IDirect3DDevice9_EndScene(device);
2808 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2812 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2814 hr = IDirect3DDevice9_SetIndices(device, NULL);
2815 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2816 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2817 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2819 /* Index buffer was already destroyed as part of the test */
2820 IDirect3DVertexBuffer9_Release(vb);
2823 static void float_texture_test(IDirect3DDevice9 *device)
2825 IDirect3D9 *d3d = NULL;
2826 HRESULT hr;
2827 IDirect3DTexture9 *texture = NULL;
2828 D3DLOCKED_RECT lr;
2829 float *data;
2830 DWORD color;
2831 float quad[] = {
2832 -1.0, -1.0, 0.1, 0.0, 0.0,
2833 -1.0, 1.0, 0.1, 0.0, 1.0,
2834 1.0, -1.0, 0.1, 1.0, 0.0,
2835 1.0, 1.0, 0.1, 1.0, 1.0,
2838 memset(&lr, 0, sizeof(lr));
2839 IDirect3DDevice9_GetDirect3D(device, &d3d);
2840 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2841 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2842 skip("D3DFMT_R32F textures not supported\n");
2843 goto out;
2846 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2847 D3DPOOL_MANAGED, &texture, NULL);
2848 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2849 if(!texture) {
2850 skip("Failed to create R32F texture\n");
2851 goto out;
2854 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2855 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2856 data = lr.pBits;
2857 *data = 0.0;
2858 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2859 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2861 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2862 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2864 hr = IDirect3DDevice9_BeginScene(device);
2865 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2866 if(SUCCEEDED(hr))
2868 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2869 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2872 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2874 hr = IDirect3DDevice9_EndScene(device);
2875 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2877 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2878 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2880 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2881 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2883 color = getPixelColor(device, 240, 320);
2884 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2886 out:
2887 if(texture) IDirect3DTexture9_Release(texture);
2888 IDirect3D9_Release(d3d);
2891 static void g16r16_texture_test(IDirect3DDevice9 *device)
2893 IDirect3D9 *d3d = NULL;
2894 HRESULT hr;
2895 IDirect3DTexture9 *texture = NULL;
2896 D3DLOCKED_RECT lr;
2897 DWORD *data;
2898 DWORD color, red, green, blue;
2899 float quad[] = {
2900 -1.0, -1.0, 0.1, 0.0, 0.0,
2901 -1.0, 1.0, 0.1, 0.0, 1.0,
2902 1.0, -1.0, 0.1, 1.0, 0.0,
2903 1.0, 1.0, 0.1, 1.0, 1.0,
2906 memset(&lr, 0, sizeof(lr));
2907 IDirect3DDevice9_GetDirect3D(device, &d3d);
2908 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2909 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2910 skip("D3DFMT_G16R16 textures not supported\n");
2911 goto out;
2914 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2915 D3DPOOL_MANAGED, &texture, NULL);
2916 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2917 if(!texture) {
2918 skip("Failed to create D3DFMT_G16R16 texture\n");
2919 goto out;
2922 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2923 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2924 data = lr.pBits;
2925 *data = 0x0f00f000;
2926 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2927 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2929 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2930 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2932 hr = IDirect3DDevice9_BeginScene(device);
2933 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2934 if(SUCCEEDED(hr))
2936 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2937 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2939 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2940 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2942 hr = IDirect3DDevice9_EndScene(device);
2943 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2945 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2946 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2948 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2949 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2951 color = getPixelColor(device, 240, 320);
2952 red = (color & 0x00ff0000) >> 16;
2953 green = (color & 0x0000ff00) >> 8;
2954 blue = (color & 0x000000ff) >> 0;
2955 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2956 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2958 out:
2959 if(texture) IDirect3DTexture9_Release(texture);
2960 IDirect3D9_Release(d3d);
2963 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2965 HRESULT hr;
2966 IDirect3D9 *d3d;
2967 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2968 D3DCAPS9 caps;
2969 IDirect3DTexture9 *texture = NULL;
2970 IDirect3DVolumeTexture9 *volume = NULL;
2971 unsigned int x, y, z;
2972 D3DLOCKED_RECT lr;
2973 D3DLOCKED_BOX lb;
2974 DWORD color;
2975 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2976 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2977 0.0, 1.0, 0.0, 0.0,
2978 0.0, 0.0, 1.0, 0.0,
2979 0.0, 0.0, 0.0, 1.0};
2980 static const D3DVERTEXELEMENT9 decl_elements[] = {
2981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2983 D3DDECL_END()
2985 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2987 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2988 D3DDECL_END()
2990 static const D3DVERTEXELEMENT9 decl_elements3[] = {
2991 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2992 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2993 D3DDECL_END()
2995 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2996 0x00, 0xff, 0x00, 0x00,
2997 0x00, 0x00, 0x00, 0x00,
2998 0x00, 0x00, 0x00, 0x00};
3000 memset(&lr, 0, sizeof(lr));
3001 memset(&lb, 0, sizeof(lb));
3002 IDirect3DDevice9_GetDirect3D(device, &d3d);
3003 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3004 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3005 fmt = D3DFMT_A16B16G16R16;
3007 IDirect3D9_Release(d3d);
3009 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3010 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3011 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3012 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3013 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3015 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3016 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
3017 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3018 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
3019 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3020 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3021 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3022 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3023 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3024 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3025 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3026 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3027 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3028 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3030 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3034 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3035 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3036 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3037 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3039 if(!texture) {
3040 skip("Failed to create the test texture\n");
3041 return;
3044 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3045 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3046 * 1.0 in red and green for the x and y coords
3048 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3049 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3050 for(y = 0; y < caps.MaxTextureHeight; y++) {
3051 for(x = 0; x < caps.MaxTextureWidth; x++) {
3052 double r_f = (double) y / (double) caps.MaxTextureHeight;
3053 double g_f = (double) x / (double) caps.MaxTextureWidth;
3054 if(fmt == D3DFMT_A16B16G16R16) {
3055 unsigned short r, g;
3056 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3057 r = (unsigned short) (r_f * 65536.0);
3058 g = (unsigned short) (g_f * 65536.0);
3059 dst[0] = r;
3060 dst[1] = g;
3061 dst[2] = 0;
3062 dst[3] = 65535;
3063 } else {
3064 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3065 unsigned char r = (unsigned char) (r_f * 255.0);
3066 unsigned char g = (unsigned char) (g_f * 255.0);
3067 dst[0] = 0;
3068 dst[1] = g;
3069 dst[2] = r;
3070 dst[3] = 255;
3074 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3075 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3076 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3077 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3079 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3080 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3081 hr = IDirect3DDevice9_BeginScene(device);
3082 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3083 if(SUCCEEDED(hr))
3085 float quad1[] = {
3086 -1.0, -1.0, 0.1, 1.0, 1.0,
3087 -1.0, 0.0, 0.1, 1.0, 1.0,
3088 0.0, -1.0, 0.1, 1.0, 1.0,
3089 0.0, 0.0, 0.1, 1.0, 1.0,
3091 float quad2[] = {
3092 -1.0, 0.0, 0.1, 1.0, 1.0,
3093 -1.0, 1.0, 0.1, 1.0, 1.0,
3094 0.0, 0.0, 0.1, 1.0, 1.0,
3095 0.0, 1.0, 0.1, 1.0, 1.0,
3097 float quad3[] = {
3098 0.0, 0.0, 0.1, 0.5, 0.5,
3099 0.0, 1.0, 0.1, 0.5, 0.5,
3100 1.0, 0.0, 0.1, 0.5, 0.5,
3101 1.0, 1.0, 0.1, 0.5, 0.5,
3103 float quad4[] = {
3104 320, 480, 0.1, 1.0, 0.0, 1.0,
3105 320, 240, 0.1, 1.0, 0.0, 1.0,
3106 640, 480, 0.1, 1.0, 0.0, 1.0,
3107 640, 240, 0.1, 1.0, 0.0, 1.0,
3109 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3110 0.0, 0.0, 0.0, 0.0,
3111 0.0, 0.0, 0.0, 0.0,
3112 0.0, 0.0, 0.0, 0.0};
3114 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3115 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3116 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3118 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3120 /* What happens with transforms enabled? */
3121 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3122 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3124 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3126 /* What happens if 4 coords are used, but only 2 given ?*/
3127 mat[8] = 1.0;
3128 mat[13] = 1.0;
3129 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3130 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3131 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3134 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3136 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3137 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3138 * due to the coords in the vertices. (turns out red, indeed)
3140 memset(mat, 0, sizeof(mat));
3141 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3143 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3144 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3145 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3146 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3148 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3150 hr = IDirect3DDevice9_EndScene(device);
3151 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3153 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3154 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3155 color = getPixelColor(device, 160, 360);
3156 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3157 color = getPixelColor(device, 160, 120);
3158 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3159 color = getPixelColor(device, 480, 120);
3160 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3161 color = getPixelColor(device, 480, 360);
3162 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3165 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3167 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3168 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3169 hr = IDirect3DDevice9_BeginScene(device);
3170 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3171 if(SUCCEEDED(hr))
3173 float quad1[] = {
3174 -1.0, -1.0, 0.1, 0.8, 0.2,
3175 -1.0, 0.0, 0.1, 0.8, 0.2,
3176 0.0, -1.0, 0.1, 0.8, 0.2,
3177 0.0, 0.0, 0.1, 0.8, 0.2,
3179 float quad2[] = {
3180 -1.0, 0.0, 0.1, 0.5, 1.0,
3181 -1.0, 1.0, 0.1, 0.5, 1.0,
3182 0.0, 0.0, 0.1, 0.5, 1.0,
3183 0.0, 1.0, 0.1, 0.5, 1.0,
3185 float quad3[] = {
3186 0.0, 0.0, 0.1, 0.5, 1.0,
3187 0.0, 1.0, 0.1, 0.5, 1.0,
3188 1.0, 0.0, 0.1, 0.5, 1.0,
3189 1.0, 1.0, 0.1, 0.5, 1.0,
3191 float quad4[] = {
3192 0.0, -1.0, 0.1, 0.8, 0.2,
3193 0.0, 0.0, 0.1, 0.8, 0.2,
3194 1.0, -1.0, 0.1, 0.8, 0.2,
3195 1.0, 0.0, 0.1, 0.8, 0.2,
3197 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3198 0.0, 0.0, 0.0, 0.0,
3199 0.0, 1.0, 0.0, 0.0,
3200 0.0, 0.0, 0.0, 0.0};
3202 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3204 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3206 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3207 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3210 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3212 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3213 * it behaves like COUNT2 because normal textures require 2 coords
3215 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3216 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3218 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3220 /* Just to be sure, the same as quad2 above */
3221 memset(mat, 0, sizeof(mat));
3222 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3223 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3224 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3225 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3227 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3229 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3230 * used? And what happens to the first?
3232 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3233 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3235 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3237 hr = IDirect3DDevice9_EndScene(device);
3238 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3240 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3241 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3242 color = getPixelColor(device, 160, 360);
3243 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3244 color = getPixelColor(device, 160, 120);
3245 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3246 color = getPixelColor(device, 480, 120);
3247 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3248 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3249 color = getPixelColor(device, 480, 360);
3250 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3251 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3253 IDirect3DTexture9_Release(texture);
3255 /* Test projected textures, without any fancy matrices */
3256 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3257 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3258 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3259 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3260 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3261 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3262 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3265 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3266 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3267 for(x = 0; x < 4; x++) {
3268 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3270 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3271 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3272 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3273 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3275 hr = IDirect3DDevice9_BeginScene(device);
3276 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3277 if(SUCCEEDED(hr))
3279 const float proj_quads[] = {
3280 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3281 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3282 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3283 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3284 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3285 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3286 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3287 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3290 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3293 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3295 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3296 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3298 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3300 hr = IDirect3DDevice9_EndScene(device);
3301 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3304 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3305 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3306 IDirect3DTexture9_Release(texture);
3308 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3309 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3310 color = getPixelColor(device, 158, 118);
3311 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3312 color = getPixelColor(device, 162, 118);
3313 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3314 color = getPixelColor(device, 158, 122);
3315 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3316 color = getPixelColor(device, 162, 122);
3317 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3319 color = getPixelColor(device, 158, 178);
3320 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3321 color = getPixelColor(device, 162, 178);
3322 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3323 color = getPixelColor(device, 158, 182);
3324 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3325 color = getPixelColor(device, 162, 182);
3326 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3328 color = getPixelColor(device, 318, 118);
3329 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3330 color = getPixelColor(device, 322, 118);
3331 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3332 color = getPixelColor(device, 318, 122);
3333 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3334 color = getPixelColor(device, 322, 122);
3335 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3337 color = getPixelColor(device, 318, 178);
3338 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3339 color = getPixelColor(device, 322, 178);
3340 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3341 color = getPixelColor(device, 318, 182);
3342 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3343 color = getPixelColor(device, 322, 182);
3344 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3346 color = getPixelColor(device, 238, 298);
3347 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3348 color = getPixelColor(device, 242, 298);
3349 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3350 color = getPixelColor(device, 238, 302);
3351 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3352 color = getPixelColor(device, 242, 302);
3353 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3355 color = getPixelColor(device, 238, 388);
3356 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3357 color = getPixelColor(device, 242, 388);
3358 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3359 color = getPixelColor(device, 238, 392);
3360 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3361 color = getPixelColor(device, 242, 392);
3362 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3364 color = getPixelColor(device, 478, 298);
3365 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3366 color = getPixelColor(device, 482, 298);
3367 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3368 color = getPixelColor(device, 478, 302);
3369 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3370 color = getPixelColor(device, 482, 302);
3371 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3373 color = getPixelColor(device, 478, 388);
3374 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3375 color = getPixelColor(device, 482, 388);
3376 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3377 color = getPixelColor(device, 478, 392);
3378 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3379 color = getPixelColor(device, 482, 392);
3380 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3383 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3384 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3385 * Thus watch out if sampling from texels between 0 and 1.
3387 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3388 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3389 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3390 if(!volume) {
3391 skip("Failed to create a volume texture\n");
3392 goto out;
3395 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3396 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3397 for(z = 0; z < 32; z++) {
3398 for(y = 0; y < 32; y++) {
3399 for(x = 0; x < 32; x++) {
3400 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3401 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3402 float r_f = (float) x / 31.0;
3403 float g_f = (float) y / 31.0;
3404 float b_f = (float) z / 31.0;
3406 if(fmt == D3DFMT_A16B16G16R16) {
3407 unsigned short *mem_s = mem;
3408 mem_s[0] = r_f * 65535.0;
3409 mem_s[1] = g_f * 65535.0;
3410 mem_s[2] = b_f * 65535.0;
3411 mem_s[3] = 65535;
3412 } else {
3413 unsigned char *mem_c = mem;
3414 mem_c[0] = b_f * 255.0;
3415 mem_c[1] = g_f * 255.0;
3416 mem_c[2] = r_f * 255.0;
3417 mem_c[3] = 255;
3422 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3423 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3425 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3426 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3428 hr = IDirect3DDevice9_BeginScene(device);
3429 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3430 if(SUCCEEDED(hr))
3432 float quad1[] = {
3433 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3434 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3435 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3436 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3438 float quad2[] = {
3439 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3440 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3441 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3442 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3444 float quad3[] = {
3445 0.0, 0.0, 0.1, 0.0, 0.0,
3446 0.0, 1.0, 0.1, 0.0, 0.0,
3447 1.0, 0.0, 0.1, 0.0, 0.0,
3448 1.0, 1.0, 0.1, 0.0, 0.0
3450 float quad4[] = {
3451 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3452 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3453 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3454 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3456 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3457 0.0, 0.0, 1.0, 0.0,
3458 0.0, 1.0, 0.0, 0.0,
3459 0.0, 0.0, 0.0, 1.0};
3460 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3461 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3463 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3464 * values
3466 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3468 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3471 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3473 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3474 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3475 * otherwise the w will be missing(blue).
3476 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3477 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3479 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3480 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3482 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3484 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3485 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3486 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3487 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3490 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3492 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3494 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3495 * disable. ATI extends it up to the amount of values needed for the volume texture
3497 memset(mat, 0, sizeof(mat));
3498 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3499 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3500 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3502 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3503 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3505 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3507 hr = IDirect3DDevice9_EndScene(device);
3508 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3510 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3511 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3513 color = getPixelColor(device, 160, 360);
3514 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3515 color = getPixelColor(device, 160, 120);
3516 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3517 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3518 color = getPixelColor(device, 480, 120);
3519 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3520 color = getPixelColor(device, 480, 360);
3521 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3523 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3524 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3525 hr = IDirect3DDevice9_BeginScene(device);
3526 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3527 if(SUCCEEDED(hr))
3529 float quad1[] = {
3530 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3531 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3532 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3533 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3535 float quad2[] = {
3536 -1.0, 0.0, 0.1,
3537 -1.0, 1.0, 0.1,
3538 0.0, 0.0, 0.1,
3539 0.0, 1.0, 0.1,
3541 float quad3[] = {
3542 0.0, 0.0, 0.1, 1.0,
3543 0.0, 1.0, 0.1, 1.0,
3544 1.0, 0.0, 0.1, 1.0,
3545 1.0, 1.0, 0.1, 1.0
3547 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3548 0.0, 0.0, 0.0, 0.0,
3549 0.0, 0.0, 0.0, 0.0,
3550 0.0, 1.0, 0.0, 0.0};
3551 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3552 1.0, 0.0, 0.0, 0.0,
3553 0.0, 1.0, 0.0, 0.0,
3554 0.0, 0.0, 1.0, 0.0};
3555 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3556 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3558 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3560 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3561 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3562 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3563 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3564 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3565 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3567 /* None passed */
3568 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3569 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3570 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3573 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3575 /* 4 used, 1 passed */
3576 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3577 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3578 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3581 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3583 hr = IDirect3DDevice9_EndScene(device);
3584 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3586 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3587 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3588 color = getPixelColor(device, 160, 360);
3589 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3590 color = getPixelColor(device, 160, 120);
3591 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3592 color = getPixelColor(device, 480, 120);
3593 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3594 /* Quad4: unused */
3596 IDirect3DVolumeTexture9_Release(volume);
3598 out:
3599 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3600 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3601 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3602 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3603 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3604 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3605 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3606 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3607 IDirect3DVertexDeclaration9_Release(decl);
3608 IDirect3DVertexDeclaration9_Release(decl2);
3609 IDirect3DVertexDeclaration9_Release(decl3);
3612 static void texdepth_test(IDirect3DDevice9 *device)
3614 IDirect3DPixelShader9 *shader;
3615 HRESULT hr;
3616 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3617 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3618 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3619 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3620 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3621 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3622 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3623 DWORD shader_code[] = {
3624 0xffff0104, /* ps_1_4 */
3625 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3626 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3627 0x0000fffd, /* phase */
3628 0x00000057, 0x800f0005, /* texdepth r5 */
3629 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3630 0x0000ffff /* end */
3632 DWORD color;
3633 float vertex[] = {
3634 -1.0, -1.0, 0.0,
3635 1.0, -1.0, 1.0,
3636 -1.0, 1.0, 0.0,
3637 1.0, 1.0, 1.0
3640 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3641 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3644 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3646 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3651 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3653 /* Fill the depth buffer with a gradient */
3654 hr = IDirect3DDevice9_BeginScene(device);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3656 if(SUCCEEDED(hr))
3658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3659 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3660 hr = IDirect3DDevice9_EndScene(device);
3661 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3664 /* Now perform the actual tests. Same geometry, but with the shader */
3665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3666 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3669 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3670 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3672 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3673 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3674 hr = IDirect3DDevice9_BeginScene(device);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3676 if(SUCCEEDED(hr))
3678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3679 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3681 hr = IDirect3DDevice9_EndScene(device);
3682 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3685 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3686 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3687 color = getPixelColor(device, 158, 240);
3688 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3689 color = getPixelColor(device, 162, 240);
3690 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3692 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3694 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3695 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3696 hr = IDirect3DDevice9_BeginScene(device);
3697 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3698 if(SUCCEEDED(hr))
3700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3701 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3703 hr = IDirect3DDevice9_EndScene(device);
3704 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3707 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3708 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3709 color = getPixelColor(device, 318, 240);
3710 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3711 color = getPixelColor(device, 322, 240);
3712 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3714 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3716 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3718 hr = IDirect3DDevice9_BeginScene(device);
3719 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3720 if(SUCCEEDED(hr))
3722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3723 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3725 hr = IDirect3DDevice9_EndScene(device);
3726 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3728 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3729 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3731 color = getPixelColor(device, 1, 240);
3732 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3734 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3736 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3737 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3738 hr = IDirect3DDevice9_BeginScene(device);
3739 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3740 if(SUCCEEDED(hr))
3742 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3743 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3745 hr = IDirect3DDevice9_EndScene(device);
3746 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3748 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3749 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3750 color = getPixelColor(device, 318, 240);
3751 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3752 color = getPixelColor(device, 322, 240);
3753 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3755 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3757 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3758 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3759 hr = IDirect3DDevice9_BeginScene(device);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3761 if(SUCCEEDED(hr))
3763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3764 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3766 hr = IDirect3DDevice9_EndScene(device);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3769 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3772 color = getPixelColor(device, 1, 240);
3773 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3775 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3777 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3778 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3779 hr = IDirect3DDevice9_BeginScene(device);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3781 if(SUCCEEDED(hr))
3783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3784 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3786 hr = IDirect3DDevice9_EndScene(device);
3787 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3789 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3790 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3792 color = getPixelColor(device, 638, 240);
3793 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3797 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3799 hr = IDirect3DDevice9_BeginScene(device);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3801 if(SUCCEEDED(hr))
3803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3804 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3806 hr = IDirect3DDevice9_EndScene(device);
3807 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3809 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3810 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3812 color = getPixelColor(device, 638, 240);
3813 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3815 /* Cleanup */
3816 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3817 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3818 IDirect3DPixelShader9_Release(shader);
3820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3821 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3823 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3826 static void texkill_test(IDirect3DDevice9 *device)
3828 IDirect3DPixelShader9 *shader;
3829 HRESULT hr;
3830 DWORD color;
3832 const float vertex[] = {
3833 /* bottom top right left */
3834 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3835 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3836 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3837 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3840 DWORD shader_code_11[] = {
3841 0xffff0101, /* ps_1_1 */
3842 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3843 0x00000041, 0xb00f0000, /* texkill t0 */
3844 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3845 0x0000ffff /* end */
3847 DWORD shader_code_20[] = {
3848 0xffff0200, /* ps_2_0 */
3849 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3850 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3851 0x01000041, 0xb00f0000, /* texkill t0 */
3852 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3853 0x0000ffff /* end */
3856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3857 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3858 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3859 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3861 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3863 hr = IDirect3DDevice9_BeginScene(device);
3864 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3865 if(SUCCEEDED(hr))
3867 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3868 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3870 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3871 hr = IDirect3DDevice9_EndScene(device);
3872 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3874 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3875 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3876 color = getPixelColor(device, 63, 46);
3877 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3878 color = getPixelColor(device, 66, 46);
3879 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3880 color = getPixelColor(device, 63, 49);
3881 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3882 color = getPixelColor(device, 66, 49);
3883 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3885 color = getPixelColor(device, 578, 46);
3886 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3887 color = getPixelColor(device, 575, 46);
3888 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3889 color = getPixelColor(device, 578, 49);
3890 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3891 color = getPixelColor(device, 575, 49);
3892 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3894 color = getPixelColor(device, 63, 430);
3895 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3896 color = getPixelColor(device, 63, 433);
3897 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3898 color = getPixelColor(device, 66, 433);
3899 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3900 color = getPixelColor(device, 66, 430);
3901 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3903 color = getPixelColor(device, 578, 430);
3904 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3905 color = getPixelColor(device, 578, 433);
3906 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3907 color = getPixelColor(device, 575, 433);
3908 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3909 color = getPixelColor(device, 575, 430);
3910 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3912 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3914 IDirect3DPixelShader9_Release(shader);
3916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3917 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3918 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3919 if(FAILED(hr)) {
3920 skip("Failed to create 2.0 test shader, most likely not supported\n");
3921 return;
3924 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3925 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3926 hr = IDirect3DDevice9_BeginScene(device);
3927 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3928 if(SUCCEEDED(hr))
3930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3931 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3932 hr = IDirect3DDevice9_EndScene(device);
3933 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3935 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3937 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3938 color = getPixelColor(device, 63, 46);
3939 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3940 color = getPixelColor(device, 66, 46);
3941 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3942 color = getPixelColor(device, 63, 49);
3943 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3944 color = getPixelColor(device, 66, 49);
3945 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3947 color = getPixelColor(device, 578, 46);
3948 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3949 color = getPixelColor(device, 575, 46);
3950 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3951 color = getPixelColor(device, 578, 49);
3952 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3953 color = getPixelColor(device, 575, 49);
3954 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3956 color = getPixelColor(device, 63, 430);
3957 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3958 color = getPixelColor(device, 63, 433);
3959 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3960 color = getPixelColor(device, 66, 433);
3961 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3962 color = getPixelColor(device, 66, 430);
3963 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3965 color = getPixelColor(device, 578, 430);
3966 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3967 color = getPixelColor(device, 578, 433);
3968 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3969 color = getPixelColor(device, 575, 433);
3970 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3971 color = getPixelColor(device, 575, 430);
3972 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3974 /* Cleanup */
3975 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3976 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3977 IDirect3DPixelShader9_Release(shader);
3980 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3982 IDirect3D9 *d3d9;
3983 HRESULT hr;
3984 IDirect3DTexture9 *texture;
3985 IDirect3DPixelShader9 *shader;
3986 IDirect3DPixelShader9 *shader2;
3987 D3DLOCKED_RECT lr;
3988 DWORD color;
3989 DWORD shader_code[] = {
3990 0xffff0101, /* ps_1_1 */
3991 0x00000042, 0xb00f0000, /* tex t0 */
3992 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3993 0x0000ffff /* end */
3995 DWORD shader_code2[] = {
3996 0xffff0101, /* ps_1_1 */
3997 0x00000042, 0xb00f0000, /* tex t0 */
3998 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
3999 0x0000ffff /* end */
4002 float quad[] = {
4003 -1.0, -1.0, 0.1, 0.5, 0.5,
4004 1.0, -1.0, 0.1, 0.5, 0.5,
4005 -1.0, 1.0, 0.1, 0.5, 0.5,
4006 1.0, 1.0, 0.1, 0.5, 0.5,
4009 memset(&lr, 0, sizeof(lr));
4010 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4011 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4012 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4013 IDirect3D9_Release(d3d9);
4014 if(FAILED(hr)) {
4015 skip("No D3DFMT_X8L8V8U8 support\n");
4018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4019 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4021 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4022 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4023 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4024 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4025 *((DWORD *) lr.pBits) = 0x11ca3141;
4026 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4027 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4029 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4031 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4034 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4035 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4036 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4038 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4041 hr = IDirect3DDevice9_BeginScene(device);
4042 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4043 if(SUCCEEDED(hr))
4045 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4046 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4048 hr = IDirect3DDevice9_EndScene(device);
4049 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4052 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4053 color = getPixelColor(device, 578, 430);
4054 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4055 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4057 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4058 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4059 hr = IDirect3DDevice9_BeginScene(device);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4061 if(SUCCEEDED(hr))
4063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4064 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4066 hr = IDirect3DDevice9_EndScene(device);
4067 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4069 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4070 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4071 color = getPixelColor(device, 578, 430);
4072 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4074 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4075 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4076 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4077 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4078 IDirect3DPixelShader9_Release(shader);
4079 IDirect3DPixelShader9_Release(shader2);
4080 IDirect3DTexture9_Release(texture);
4083 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4085 HRESULT hr;
4086 IDirect3D9 *d3d;
4087 IDirect3DTexture9 *texture = NULL;
4088 IDirect3DSurface9 *surface;
4089 DWORD color;
4090 const RECT r1 = {256, 256, 512, 512};
4091 const RECT r2 = {512, 256, 768, 512};
4092 const RECT r3 = {256, 512, 512, 768};
4093 const RECT r4 = {512, 512, 768, 768};
4094 unsigned int x, y;
4095 D3DLOCKED_RECT lr;
4096 memset(&lr, 0, sizeof(lr));
4098 IDirect3DDevice9_GetDirect3D(device, &d3d);
4099 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4100 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4101 skip("No autogenmipmap support\n");
4102 IDirect3D9_Release(d3d);
4103 return;
4105 IDirect3D9_Release(d3d);
4107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4108 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4110 /* Make the mipmap big, so that a smaller mipmap is used
4112 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4113 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4114 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4116 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4117 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4118 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4119 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4120 for(y = 0; y < 1024; y++) {
4121 for(x = 0; x < 1024; x++) {
4122 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4123 POINT pt;
4125 pt.x = x;
4126 pt.y = y;
4127 if(PtInRect(&r1, pt)) {
4128 *dst = 0xffff0000;
4129 } else if(PtInRect(&r2, pt)) {
4130 *dst = 0xff00ff00;
4131 } else if(PtInRect(&r3, pt)) {
4132 *dst = 0xff0000ff;
4133 } else if(PtInRect(&r4, pt)) {
4134 *dst = 0xff000000;
4135 } else {
4136 *dst = 0xffffffff;
4140 hr = IDirect3DSurface9_UnlockRect(surface);
4141 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4142 IDirect3DSurface9_Release(surface);
4144 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4145 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4146 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4149 hr = IDirect3DDevice9_BeginScene(device);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4151 if(SUCCEEDED(hr)) {
4152 const float quad[] = {
4153 -0.5, -0.5, 0.1, 0.0, 0.0,
4154 -0.5, 0.5, 0.1, 0.0, 1.0,
4155 0.5, -0.5, 0.1, 1.0, 0.0,
4156 0.5, 0.5, 0.1, 1.0, 1.0
4159 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4161 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4162 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4163 hr = IDirect3DDevice9_EndScene(device);
4164 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4166 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4167 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4168 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4169 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4170 IDirect3DTexture9_Release(texture);
4172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4173 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4174 color = getPixelColor(device, 200, 200);
4175 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4176 color = getPixelColor(device, 280, 200);
4177 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4178 color = getPixelColor(device, 360, 200);
4179 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4180 color = getPixelColor(device, 440, 200);
4181 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4182 color = getPixelColor(device, 200, 270);
4183 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4184 color = getPixelColor(device, 280, 270);
4185 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4186 color = getPixelColor(device, 360, 270);
4187 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4188 color = getPixelColor(device, 440, 270);
4189 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4192 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4194 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4195 IDirect3DVertexDeclaration9 *decl;
4196 HRESULT hr;
4197 DWORD color;
4198 DWORD shader_code_11[] = {
4199 0xfffe0101, /* vs_1_1 */
4200 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4201 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4202 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4203 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4204 0x0000ffff /* end */
4206 DWORD shader_code_11_2[] = {
4207 0xfffe0101, /* vs_1_1 */
4208 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4209 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4210 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4211 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4212 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4213 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4214 0x0000ffff /* end */
4216 DWORD shader_code_20[] = {
4217 0xfffe0200, /* vs_2_0 */
4218 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4219 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4220 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4221 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4222 0x0000ffff /* end */
4224 DWORD shader_code_20_2[] = {
4225 0xfffe0200, /* vs_2_0 */
4226 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4227 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4228 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4229 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4230 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4231 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4232 0x0000ffff /* end */
4234 static const D3DVERTEXELEMENT9 decl_elements[] = {
4235 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4236 D3DDECL_END()
4238 float quad1[] = {
4239 -1.0, -1.0, 0.1,
4240 0.0, -1.0, 0.1,
4241 -1.0, 0.0, 0.1,
4242 0.0, 0.0, 0.1
4244 float quad2[] = {
4245 0.0, -1.0, 0.1,
4246 1.0, -1.0, 0.1,
4247 0.0, 0.0, 0.1,
4248 1.0, 0.0, 0.1
4250 float quad3[] = {
4251 0.0, 0.0, 0.1,
4252 1.0, 0.0, 0.1,
4253 0.0, 1.0, 0.1,
4254 1.0, 1.0, 0.1
4256 float quad4[] = {
4257 -1.0, 0.0, 0.1,
4258 0.0, 0.0, 0.1,
4259 -1.0, 1.0, 0.1,
4260 0.0, 1.0, 0.1
4262 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4263 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4266 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4268 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4269 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4270 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4272 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4273 if(FAILED(hr)) shader_20 = NULL;
4274 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4275 if(FAILED(hr)) shader_20_2 = NULL;
4276 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4277 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4279 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4280 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4281 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4283 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4284 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4286 hr = IDirect3DDevice9_BeginScene(device);
4287 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4288 if(SUCCEEDED(hr))
4290 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4291 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4293 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4295 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4296 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4298 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4300 if(shader_20) {
4301 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4304 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4307 if(shader_20_2) {
4308 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4309 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4311 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4314 hr = IDirect3DDevice9_EndScene(device);
4315 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4317 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4318 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4320 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4321 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4322 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4323 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4325 color = getPixelColor(device, 160, 360);
4326 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4327 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4328 color = getPixelColor(device, 480, 360);
4329 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4330 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4331 if(shader_20) {
4332 color = getPixelColor(device, 160, 120);
4333 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4334 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4336 if(shader_20_2) {
4337 color = getPixelColor(device, 480, 120);
4338 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4339 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4342 IDirect3DVertexDeclaration9_Release(decl);
4343 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4344 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4345 IDirect3DVertexShader9_Release(shader_11_2);
4346 IDirect3DVertexShader9_Release(shader_11);
4349 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4351 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4352 HRESULT hr;
4353 DWORD color;
4354 DWORD shader_code_11[] = {
4355 0xffff0101, /* ps_1_1 */
4356 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4357 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4358 0x0000ffff /* end */
4360 DWORD shader_code_12[] = {
4361 0xffff0102, /* ps_1_2 */
4362 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4363 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4364 0x0000ffff /* end */
4366 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4367 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4368 * During development of this test, 1.3 shaders were verified too
4370 DWORD shader_code_14[] = {
4371 0xffff0104, /* ps_1_4 */
4372 /* Try to make one constant local. It gets clamped too, although the binary contains
4373 * the bigger numbers
4375 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4376 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4377 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4378 0x0000ffff /* end */
4380 DWORD shader_code_20[] = {
4381 0xffff0200, /* ps_2_0 */
4382 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4383 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4384 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4385 0x0000ffff /* end */
4387 float quad1[] = {
4388 -1.0, -1.0, 0.1,
4389 0.0, -1.0, 0.1,
4390 -1.0, 0.0, 0.1,
4391 0.0, 0.0, 0.1
4393 float quad2[] = {
4394 0.0, -1.0, 0.1,
4395 1.0, -1.0, 0.1,
4396 0.0, 0.0, 0.1,
4397 1.0, 0.0, 0.1
4399 float quad3[] = {
4400 0.0, 0.0, 0.1,
4401 1.0, 0.0, 0.1,
4402 0.0, 1.0, 0.1,
4403 1.0, 1.0, 0.1
4405 float quad4[] = {
4406 -1.0, 0.0, 0.1,
4407 0.0, 0.0, 0.1,
4408 -1.0, 1.0, 0.1,
4409 0.0, 1.0, 0.1
4411 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4412 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4414 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4415 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4417 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4418 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4419 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4420 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4421 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4422 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4423 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4424 if(FAILED(hr)) shader_20 = NULL;
4426 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4427 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4428 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4429 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4430 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4431 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4433 hr = IDirect3DDevice9_BeginScene(device);
4434 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4435 if(SUCCEEDED(hr))
4437 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4438 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4440 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4442 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4443 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4445 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4448 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4450 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4452 if(shader_20) {
4453 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4454 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4456 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4459 hr = IDirect3DDevice9_EndScene(device);
4460 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4462 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4463 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4465 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4466 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4468 color = getPixelColor(device, 160, 360);
4469 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4470 "quad 1 has color %08x, expected 0x00808000\n", color);
4471 color = getPixelColor(device, 480, 360);
4472 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4473 "quad 2 has color %08x, expected 0x00808000\n", color);
4474 color = getPixelColor(device, 480, 120);
4475 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4476 "quad 3 has color %08x, expected 0x00808000\n", color);
4477 if(shader_20) {
4478 color = getPixelColor(device, 160, 120);
4479 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4480 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4483 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4484 IDirect3DPixelShader9_Release(shader_14);
4485 IDirect3DPixelShader9_Release(shader_12);
4486 IDirect3DPixelShader9_Release(shader_11);
4489 static void dp2add_ps_test(IDirect3DDevice9 *device)
4491 IDirect3DPixelShader9 *shader_dp2add = NULL;
4492 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4493 HRESULT hr;
4494 DWORD color;
4496 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4497 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4498 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4499 * r0 first.
4500 * The result here for the r,g,b components should be roughly 0.5:
4501 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4502 static const DWORD shader_code_dp2add[] = {
4503 0xffff0200, /* ps_2_0 */
4504 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4506 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4507 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4509 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4510 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4511 0x0000ffff /* end */
4514 /* Test the _sat modifier, too. Result here should be:
4515 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4516 * _SAT: ==> 1.0
4517 * ADD: (1.0 + -0.5) = 0.5
4519 static const DWORD shader_code_dp2add_sat[] = {
4520 0xffff0200, /* ps_2_0 */
4521 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4523 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4524 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4525 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4527 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4528 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4529 0x0000ffff /* end */
4532 const float quad[] = {
4533 -1.0, -1.0, 0.1,
4534 1.0, -1.0, 0.1,
4535 -1.0, 1.0, 0.1,
4536 1.0, 1.0, 0.1
4540 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4541 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4543 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4544 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4546 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4549 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4550 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4552 if (shader_dp2add) {
4554 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4555 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4557 hr = IDirect3DDevice9_BeginScene(device);
4558 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4559 if(SUCCEEDED(hr))
4561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4562 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4564 hr = IDirect3DDevice9_EndScene(device);
4565 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4568 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4570 color = getPixelColor(device, 360, 240);
4571 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4573 IDirect3DPixelShader9_Release(shader_dp2add);
4574 } else {
4575 skip("dp2add shader creation failed\n");
4578 if (shader_dp2add_sat) {
4580 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4581 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4583 hr = IDirect3DDevice9_BeginScene(device);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4585 if(SUCCEEDED(hr))
4587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4588 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4590 hr = IDirect3DDevice9_EndScene(device);
4591 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4593 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4594 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4596 color = getPixelColor(device, 360, 240);
4597 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4599 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4600 } else {
4601 skip("dp2add shader creation failed\n");
4604 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4605 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4608 static void cnd_test(IDirect3DDevice9 *device)
4610 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4611 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4612 HRESULT hr;
4613 DWORD color;
4614 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4615 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4616 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4618 DWORD shader_code_11[] = {
4619 0xffff0101, /* ps_1_1 */
4620 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4621 0x00000040, 0xb00f0000, /* texcoord t0 */
4622 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4623 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4624 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4625 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4626 0x0000ffff /* end */
4628 DWORD shader_code_12[] = {
4629 0xffff0102, /* ps_1_2 */
4630 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4631 0x00000040, 0xb00f0000, /* texcoord t0 */
4632 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4633 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4634 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4635 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4636 0x0000ffff /* end */
4638 DWORD shader_code_13[] = {
4639 0xffff0103, /* ps_1_3 */
4640 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4641 0x00000040, 0xb00f0000, /* texcoord t0 */
4642 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4643 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4644 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4645 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4646 0x0000ffff /* end */
4648 DWORD shader_code_14[] = {
4649 0xffff0104, /* ps_1_3 */
4650 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4651 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4652 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4653 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4654 0x0000ffff /* end */
4657 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4658 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4659 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4660 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4661 * native CreatePixelShader returns an error.
4663 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4664 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4665 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4666 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4668 DWORD shader_code_11_coissue[] = {
4669 0xffff0101, /* ps_1_1 */
4670 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4671 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4672 0x00000040, 0xb00f0000, /* texcoord t0 */
4673 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4674 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4675 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4676 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4677 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4678 /* 0x40000000 = D3DSI_COISSUE */
4679 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4680 0x0000ffff /* end */
4682 DWORD shader_code_12_coissue[] = {
4683 0xffff0102, /* ps_1_2 */
4684 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4685 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4686 0x00000040, 0xb00f0000, /* texcoord t0 */
4687 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4688 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4689 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4690 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4691 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4692 /* 0x40000000 = D3DSI_COISSUE */
4693 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4694 0x0000ffff /* end */
4696 DWORD shader_code_13_coissue[] = {
4697 0xffff0103, /* ps_1_3 */
4698 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4699 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4700 0x00000040, 0xb00f0000, /* texcoord t0 */
4701 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4702 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4703 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4704 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4705 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4706 /* 0x40000000 = D3DSI_COISSUE */
4707 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4708 0x0000ffff /* end */
4710 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4711 * compare against 0.5
4713 DWORD shader_code_14_coissue[] = {
4714 0xffff0104, /* ps_1_4 */
4715 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4716 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4717 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4718 /* 0x40000000 = D3DSI_COISSUE */
4719 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4720 0x0000ffff /* end */
4722 float quad1[] = {
4723 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4724 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4725 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4726 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4728 float quad2[] = {
4729 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4730 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4731 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4732 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4734 float quad3[] = {
4735 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4736 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4737 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4738 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4740 float quad4[] = {
4741 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4742 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4743 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4744 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4746 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4747 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4748 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4749 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4751 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4752 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4754 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4755 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4756 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4757 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4760 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4762 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4763 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4764 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4765 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4766 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4767 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4768 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4771 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4772 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4773 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4774 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4775 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4776 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4778 hr = IDirect3DDevice9_BeginScene(device);
4779 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4780 if(SUCCEEDED(hr))
4782 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4783 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4785 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4787 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4793 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4795 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4797 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4800 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4802 hr = IDirect3DDevice9_EndScene(device);
4803 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4806 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4808 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4809 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4811 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4812 color = getPixelColor(device, 158, 118);
4813 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4814 color = getPixelColor(device, 162, 118);
4815 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4816 color = getPixelColor(device, 158, 122);
4817 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4818 color = getPixelColor(device, 162, 122);
4819 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4821 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4822 color = getPixelColor(device, 158, 358);
4823 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4824 color = getPixelColor(device, 162, 358);
4825 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4826 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4827 color = getPixelColor(device, 158, 362);
4828 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4829 color = getPixelColor(device, 162, 362);
4830 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4831 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4833 /* 1.2 shader */
4834 color = getPixelColor(device, 478, 358);
4835 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4836 color = getPixelColor(device, 482, 358);
4837 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4838 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4839 color = getPixelColor(device, 478, 362);
4840 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4841 color = getPixelColor(device, 482, 362);
4842 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4843 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4845 /* 1.3 shader */
4846 color = getPixelColor(device, 478, 118);
4847 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4848 color = getPixelColor(device, 482, 118);
4849 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4850 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4851 color = getPixelColor(device, 478, 122);
4852 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4853 color = getPixelColor(device, 482, 122);
4854 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4855 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4858 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4859 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4860 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4861 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4864 hr = IDirect3DDevice9_BeginScene(device);
4865 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4866 if(SUCCEEDED(hr))
4868 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4869 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4871 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4873 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4874 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4876 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4878 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4879 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4881 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4883 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4884 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4886 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4888 hr = IDirect3DDevice9_EndScene(device);
4889 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4891 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4892 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4894 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4895 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4897 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4898 * that we swapped the values in c1 and c2 to make the other tests return some color
4900 color = getPixelColor(device, 158, 118);
4901 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4902 color = getPixelColor(device, 162, 118);
4903 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4904 color = getPixelColor(device, 158, 122);
4905 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4906 color = getPixelColor(device, 162, 122);
4907 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4909 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4910 color = getPixelColor(device, 158, 358);
4911 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4912 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4913 color = getPixelColor(device, 162, 358);
4914 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4915 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4916 color = getPixelColor(device, 158, 362);
4917 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4918 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4919 color = getPixelColor(device, 162, 362);
4920 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4921 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4923 /* 1.2 shader */
4924 color = getPixelColor(device, 478, 358);
4925 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4926 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4927 color = getPixelColor(device, 482, 358);
4928 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4929 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4930 color = getPixelColor(device, 478, 362);
4931 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4932 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4933 color = getPixelColor(device, 482, 362);
4934 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4935 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4937 /* 1.3 shader */
4938 color = getPixelColor(device, 478, 118);
4939 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4940 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4941 color = getPixelColor(device, 482, 118);
4942 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4943 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4944 color = getPixelColor(device, 478, 122);
4945 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4946 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4947 color = getPixelColor(device, 482, 122);
4948 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4949 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4951 IDirect3DPixelShader9_Release(shader_14_coissue);
4952 IDirect3DPixelShader9_Release(shader_13_coissue);
4953 IDirect3DPixelShader9_Release(shader_12_coissue);
4954 IDirect3DPixelShader9_Release(shader_11_coissue);
4955 IDirect3DPixelShader9_Release(shader_14);
4956 IDirect3DPixelShader9_Release(shader_13);
4957 IDirect3DPixelShader9_Release(shader_12);
4958 IDirect3DPixelShader9_Release(shader_11);
4961 static void nested_loop_test(IDirect3DDevice9 *device) {
4962 const DWORD shader_code[] = {
4963 0xffff0300, /* ps_3_0 */
4964 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4965 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4966 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
4967 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4968 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4969 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4970 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
4971 0x0000001d, /* endloop */
4972 0x0000001d, /* endloop */
4973 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4974 0x0000ffff /* end */
4976 IDirect3DPixelShader9 *shader;
4977 HRESULT hr;
4978 DWORD color;
4979 const float quad[] = {
4980 -1.0, -1.0, 0.1,
4981 1.0, -1.0, 0.1,
4982 -1.0, 1.0, 0.1,
4983 1.0, 1.0, 0.1
4986 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4987 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4988 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4989 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4990 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4992 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4993 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4995 hr = IDirect3DDevice9_BeginScene(device);
4996 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4997 if(SUCCEEDED(hr))
4999 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5000 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5001 hr = IDirect3DDevice9_EndScene(device);
5002 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5004 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5005 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5007 color = getPixelColor(device, 360, 240);
5008 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5009 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5011 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5012 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
5013 IDirect3DPixelShader9_Release(shader);
5016 struct varying_test_struct
5018 const DWORD *shader_code;
5019 IDirect3DPixelShader9 *shader;
5020 DWORD color, color_rhw;
5021 const char *name;
5022 BOOL todo, todo_rhw;
5025 struct hugeVertex
5027 float pos_x, pos_y, pos_z, rhw;
5028 float weight_1, weight_2, weight_3, weight_4;
5029 float index_1, index_2, index_3, index_4;
5030 float normal_1, normal_2, normal_3, normal_4;
5031 float fog_1, fog_2, fog_3, fog_4;
5032 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5033 float tangent_1, tangent_2, tangent_3, tangent_4;
5034 float binormal_1, binormal_2, binormal_3, binormal_4;
5035 float depth_1, depth_2, depth_3, depth_4;
5036 DWORD diffuse, specular;
5039 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5040 /* dcl_position: fails to compile */
5041 const DWORD blendweight_code[] = {
5042 0xffff0300, /* ps_3_0 */
5043 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5044 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5045 0x0000ffff /* end */
5047 const DWORD blendindices_code[] = {
5048 0xffff0300, /* ps_3_0 */
5049 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5050 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5051 0x0000ffff /* end */
5053 const DWORD normal_code[] = {
5054 0xffff0300, /* ps_3_0 */
5055 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5056 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5057 0x0000ffff /* end */
5059 /* psize: fails? */
5060 const DWORD texcoord0_code[] = {
5061 0xffff0300, /* ps_3_0 */
5062 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5063 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5064 0x0000ffff /* end */
5066 const DWORD tangent_code[] = {
5067 0xffff0300, /* ps_3_0 */
5068 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5069 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5070 0x0000ffff /* end */
5072 const DWORD binormal_code[] = {
5073 0xffff0300, /* ps_3_0 */
5074 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5075 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5076 0x0000ffff /* end */
5078 /* tessfactor: fails */
5079 /* positiont: fails */
5080 const DWORD color_code[] = {
5081 0xffff0300, /* ps_3_0 */
5082 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5083 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5084 0x0000ffff /* end */
5086 const DWORD fog_code[] = {
5087 0xffff0300, /* ps_3_0 */
5088 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5089 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5090 0x0000ffff /* end */
5092 const DWORD depth_code[] = {
5093 0xffff0300, /* ps_3_0 */
5094 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5095 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5096 0x0000ffff /* end */
5098 const DWORD specular_code[] = {
5099 0xffff0300, /* ps_3_0 */
5100 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5101 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5102 0x0000ffff /* end */
5104 /* sample: fails */
5106 struct varying_test_struct tests[] = {
5107 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5108 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5109 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5110 /* Why does dx not forward the texcoord? */
5111 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5112 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5113 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5114 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5115 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5116 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5117 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5119 /* Declare a monster vertex type :-) */
5120 static const D3DVERTEXELEMENT9 decl_elements[] = {
5121 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5122 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5123 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5124 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5125 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5126 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5127 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5128 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5129 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5130 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5131 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5132 D3DDECL_END()
5134 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5135 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5136 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5137 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5138 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5139 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5140 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5141 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5142 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5143 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5144 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5145 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5146 D3DDECL_END()
5148 struct hugeVertex data[4] = {
5150 -1.0, -1.0, 0.1, 1.0,
5151 0.1, 0.1, 0.1, 0.1,
5152 0.2, 0.2, 0.2, 0.2,
5153 0.3, 0.3, 0.3, 0.3,
5154 0.4, 0.4, 0.4, 0.4,
5155 0.50, 0.55, 0.55, 0.55,
5156 0.6, 0.6, 0.6, 0.7,
5157 0.7, 0.7, 0.7, 0.6,
5158 0.8, 0.8, 0.8, 0.8,
5159 0xe6e6e6e6, /* 0.9 * 256 */
5160 0x224488ff /* Nothing special */
5163 1.0, -1.0, 0.1, 1.0,
5164 0.1, 0.1, 0.1, 0.1,
5165 0.2, 0.2, 0.2, 0.2,
5166 0.3, 0.3, 0.3, 0.3,
5167 0.4, 0.4, 0.4, 0.4,
5168 0.50, 0.55, 0.55, 0.55,
5169 0.6, 0.6, 0.6, 0.7,
5170 0.7, 0.7, 0.7, 0.6,
5171 0.8, 0.8, 0.8, 0.8,
5172 0xe6e6e6e6, /* 0.9 * 256 */
5173 0x224488ff /* Nothing special */
5176 -1.0, 1.0, 0.1, 1.0,
5177 0.1, 0.1, 0.1, 0.1,
5178 0.2, 0.2, 0.2, 0.2,
5179 0.3, 0.3, 0.3, 0.3,
5180 0.4, 0.4, 0.4, 0.4,
5181 0.50, 0.55, 0.55, 0.55,
5182 0.6, 0.6, 0.6, 0.7,
5183 0.7, 0.7, 0.7, 0.6,
5184 0.8, 0.8, 0.8, 0.8,
5185 0xe6e6e6e6, /* 0.9 * 256 */
5186 0x224488ff /* Nothing special */
5189 1.0, 1.0, 0.1, 1.0,
5190 0.1, 0.1, 0.1, 0.1,
5191 0.2, 0.2, 0.2, 0.2,
5192 0.3, 0.3, 0.3, 0.3,
5193 0.4, 0.4, 0.4, 0.4,
5194 0.50, 0.55, 0.55, 0.55,
5195 0.6, 0.6, 0.6, 0.7,
5196 0.7, 0.7, 0.7, 0.6,
5197 0.8, 0.8, 0.8, 0.8,
5198 0xe6e6e6e6, /* 0.9 * 256 */
5199 0x224488ff /* Nothing special */
5202 struct hugeVertex data2[4];
5203 IDirect3DVertexDeclaration9 *decl;
5204 IDirect3DVertexDeclaration9 *decl2;
5205 HRESULT hr;
5206 unsigned int i;
5207 DWORD color, r, g, b, r_e, g_e, b_e;
5208 BOOL drawok;
5210 memcpy(data2, data, sizeof(data2));
5211 data2[0].pos_x = 0; data2[0].pos_y = 0;
5212 data2[1].pos_x = 640; data2[1].pos_y = 0;
5213 data2[2].pos_x = 0; data2[2].pos_y = 480;
5214 data2[3].pos_x = 640; data2[3].pos_y = 480;
5216 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5217 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5218 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5219 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5220 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5223 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5225 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5226 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5227 tests[i].name, DXGetErrorString9(hr));
5230 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5232 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5233 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5235 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5236 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5238 hr = IDirect3DDevice9_BeginScene(device);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5240 drawok = FALSE;
5241 if(SUCCEEDED(hr))
5243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5244 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5245 drawok = SUCCEEDED(hr);
5246 hr = IDirect3DDevice9_EndScene(device);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5249 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5250 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5252 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5253 * the failure and do not check the color if it failed
5255 if(!drawok) {
5256 continue;
5259 color = getPixelColor(device, 360, 240);
5260 r = color & 0x00ff0000 >> 16;
5261 g = color & 0x0000ff00 >> 8;
5262 b = color & 0x000000ff;
5263 r_e = tests[i].color & 0x00ff0000 >> 16;
5264 g_e = tests[i].color & 0x0000ff00 >> 8;
5265 b_e = tests[i].color & 0x000000ff;
5267 if(tests[i].todo) {
5268 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5269 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5270 tests[i].name, color, tests[i].color);
5271 } else {
5272 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5273 "Test %s returned color 0x%08x, expected 0x%08x\n",
5274 tests[i].name, color, tests[i].color);
5278 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5279 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5280 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5283 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5285 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5288 hr = IDirect3DDevice9_BeginScene(device);
5289 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5290 if(SUCCEEDED(hr))
5292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5293 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5294 hr = IDirect3DDevice9_EndScene(device);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5297 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5298 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5300 color = getPixelColor(device, 360, 240);
5301 r = color & 0x00ff0000 >> 16;
5302 g = color & 0x0000ff00 >> 8;
5303 b = color & 0x000000ff;
5304 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5305 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5306 b_e = tests[i].color_rhw & 0x000000ff;
5308 if(tests[i].todo_rhw) {
5309 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5310 * pipeline
5312 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5313 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5314 tests[i].name, color, tests[i].color_rhw);
5315 } else {
5316 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5317 "Test %s returned color 0x%08x, expected 0x%08x\n",
5318 tests[i].name, color, tests[i].color_rhw);
5322 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5324 IDirect3DPixelShader9_Release(tests[i].shader);
5327 IDirect3DVertexDeclaration9_Release(decl2);
5328 IDirect3DVertexDeclaration9_Release(decl);
5331 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5332 static const DWORD ps_code[] = {
5333 0xffff0300, /* ps_3_0 */
5334 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5335 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5336 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5337 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5338 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5339 0x0200001f, 0x80000003, 0x900f0006,
5340 0x0200001f, 0x80000006, 0x900f0007,
5341 0x0200001f, 0x80000001, 0x900f0008,
5342 0x0200001f, 0x8000000c, 0x900f0009,
5344 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5345 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5346 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5347 0x0000001d, /* endloop */
5348 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5349 0x0000ffff /* end */
5351 static const DWORD vs_1_code[] = {
5352 0xfffe0101, /* vs_1_1 */
5353 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5354 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5355 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5356 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5357 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5358 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5359 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5360 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5361 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5362 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5363 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5364 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5365 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5366 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5367 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5368 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5369 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5370 0x0000ffff
5372 DWORD vs_2_code[] = {
5373 0xfffe0200, /* vs_2_0 */
5374 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5375 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
5376 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
5377 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0 */
5378 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5379 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5380 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5381 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5382 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5383 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5384 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5385 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5386 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5387 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5388 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5389 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5390 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5391 0x0000ffff /* end */
5393 /* TODO: Define normal, tangent, blendweight and depth here */
5394 static const DWORD vs_3_code[] = {
5395 0xfffe0300, /* vs_3_0 */
5396 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5397 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5398 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5399 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5400 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5401 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5402 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5403 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5404 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5405 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5406 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5407 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5408 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5409 0x0000ffff /* end */
5411 float quad1[] = {
5412 -1.0, -1.0, 0.1,
5413 0.0, -1.0, 0.1,
5414 -1.0, 0.0, 0.1,
5415 0.0, 0.0, 0.1
5417 float quad2[] = {
5418 0.0, -1.0, 0.1,
5419 1.0, -1.0, 0.1,
5420 0.0, 0.0, 0.1,
5421 1.0, 0.0, 0.1
5423 float quad3[] = {
5424 -1.0, 0.0, 0.1,
5425 0.0, 0.0, 0.1,
5426 -1.0, 1.0, 0.1,
5427 0.0, 1.0, 0.1
5430 HRESULT hr;
5431 DWORD color;
5432 IDirect3DPixelShader9 *pixelshader = NULL;
5433 IDirect3DVertexShader9 *vs_1_shader = NULL;
5434 IDirect3DVertexShader9 *vs_2_shader = NULL;
5435 IDirect3DVertexShader9 *vs_3_shader = NULL;
5437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5439 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5440 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5441 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5442 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5443 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5444 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5445 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5446 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5447 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5448 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5449 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5451 hr = IDirect3DDevice9_BeginScene(device);
5452 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5453 if(SUCCEEDED(hr))
5455 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5456 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5458 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5460 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5461 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5463 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5465 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5466 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5467 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5468 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5470 hr = IDirect3DDevice9_EndScene(device);
5471 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5473 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5474 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5476 color = getPixelColor(device, 160, 120);
5477 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5478 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5479 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5480 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5481 color = getPixelColor(device, 160, 360);
5482 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5483 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5484 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5485 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5486 color = getPixelColor(device, 480, 360);
5487 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5488 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5489 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5490 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5492 /* cleanup */
5493 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5494 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5495 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5496 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5497 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5498 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5499 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5500 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5503 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5504 static const DWORD vs_code[] = {
5505 0xfffe0300, /* vs_3_0 */
5506 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5507 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5508 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5509 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5510 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5511 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5512 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5513 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5514 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5515 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5516 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5517 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5518 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5520 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5521 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5522 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5523 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5524 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5525 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5526 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5527 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5528 0x0000ffff /* end */
5530 static const DWORD ps_1_code[] = {
5531 0xffff0104, /* ps_1_4 */
5532 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5533 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5534 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5535 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5536 0x0000ffff /* end */
5538 static const DWORD ps_2_code[] = {
5539 0xffff0200, /* ps_2_0 */
5540 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5541 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5542 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5544 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5545 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5546 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5547 0x0000ffff /* end */
5549 static const DWORD ps_3_code[] = {
5550 0xffff0300, /* ps_3_0 */
5551 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5552 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5553 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5555 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5556 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5557 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5558 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5559 0x0000ffff /* end */
5562 float quad1[] = {
5563 -1.0, -1.0, 0.1,
5564 0.0, -1.0, 0.1,
5565 -1.0, 0.0, 0.1,
5566 0.0, 0.0, 0.1
5568 float quad2[] = {
5569 0.0, -1.0, 0.1,
5570 1.0, -1.0, 0.1,
5571 0.0, 0.0, 0.1,
5572 1.0, 0.0, 0.1
5574 float quad3[] = {
5575 -1.0, 0.0, 0.1,
5576 0.0, 0.0, 0.1,
5577 -1.0, 1.0, 0.1,
5578 0.0, 1.0, 0.1
5580 float quad4[] = {
5581 0.0, 0.0, 0.1,
5582 1.0, 0.0, 0.1,
5583 0.0, 1.0, 0.1,
5584 1.0, 1.0, 0.1
5587 HRESULT hr;
5588 DWORD color;
5589 IDirect3DVertexShader9 *vertexshader = NULL;
5590 IDirect3DPixelShader9 *ps_1_shader = NULL;
5591 IDirect3DPixelShader9 *ps_2_shader = NULL;
5592 IDirect3DPixelShader9 *ps_3_shader = NULL;
5593 IDirect3DTexture9 *texture = NULL;
5594 D3DLOCKED_RECT lr;
5595 unsigned int x, y;
5597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5599 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5600 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5601 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5602 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5603 for(y = 0; y < 512; y++) {
5604 for(x = 0; x < 512; x++) {
5605 double r_f = (double) x / (double) 512;
5606 double g_f = (double) y / (double) 512;
5607 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5608 unsigned short r = (unsigned short) (r_f * 65535.0);
5609 unsigned short g = (unsigned short) (g_f * 65535.0);
5610 dst[0] = r;
5611 dst[1] = g;
5612 dst[2] = 0;
5613 dst[3] = 65535;
5616 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5617 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5619 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5620 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5621 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5622 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5623 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5625 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5626 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5627 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5628 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5629 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5631 hr = IDirect3DDevice9_BeginScene(device);
5632 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5633 if(SUCCEEDED(hr))
5635 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5636 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5638 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5640 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5641 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5643 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5645 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5646 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5648 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5650 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5651 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5652 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5653 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5654 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5655 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5656 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5657 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5659 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5661 hr = IDirect3DDevice9_EndScene(device);
5662 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5664 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5665 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5667 color = getPixelColor(device, 160, 120);
5668 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5669 (color & 0x0000ff00) == 0x0000ff00 &&
5670 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5671 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5672 color = getPixelColor(device, 160, 360);
5673 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5674 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5675 (color & 0x000000ff) == 0x00000000,
5676 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5677 color = getPixelColor(device, 480, 360);
5678 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5679 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5680 (color & 0x000000ff) == 0x00000000,
5681 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5682 color = getPixelColor(device, 480, 160);
5683 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5684 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5685 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5686 (color & 0x000000ff) == 0x00000000),
5687 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5689 /* cleanup */
5690 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5692 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5693 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5694 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5695 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5696 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5697 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5698 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5699 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5700 if(texture) IDirect3DTexture9_Release(texture);
5703 void test_compare_instructions(IDirect3DDevice9 *device)
5705 DWORD shader_sge_vec_code[] = {
5706 0xfffe0101, /* vs_1_1 */
5707 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5708 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5709 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5710 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5711 0x0000ffff /* end */
5713 DWORD shader_slt_vec_code[] = {
5714 0xfffe0101, /* vs_1_1 */
5715 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5716 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5717 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5718 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5719 0x0000ffff /* end */
5721 DWORD shader_sge_scalar_code[] = {
5722 0xfffe0101, /* vs_1_1 */
5723 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5724 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5725 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5726 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5727 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5728 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5729 0x0000ffff /* end */
5731 DWORD shader_slt_scalar_code[] = {
5732 0xfffe0101, /* vs_1_1 */
5733 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5734 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5735 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5736 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5737 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5738 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5739 0x0000ffff /* end */
5741 IDirect3DVertexShader9 *shader_sge_vec;
5742 IDirect3DVertexShader9 *shader_slt_vec;
5743 IDirect3DVertexShader9 *shader_sge_scalar;
5744 IDirect3DVertexShader9 *shader_slt_scalar;
5745 HRESULT hr, color;
5746 float quad1[] = {
5747 -1.0, -1.0, 0.1,
5748 0.0, -1.0, 0.1,
5749 -1.0, 0.0, 0.1,
5750 0.0, 0.0, 0.1
5752 float quad2[] = {
5753 0.0, -1.0, 0.1,
5754 1.0, -1.0, 0.1,
5755 0.0, 0.0, 0.1,
5756 1.0, 0.0, 0.1
5758 float quad3[] = {
5759 -1.0, 0.0, 0.1,
5760 0.0, 0.0, 0.1,
5761 -1.0, 1.0, 0.1,
5762 0.0, 1.0, 0.1
5764 float quad4[] = {
5765 0.0, 0.0, 0.1,
5766 1.0, 0.0, 0.1,
5767 0.0, 1.0, 0.1,
5768 1.0, 1.0, 0.1
5770 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5771 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5775 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5777 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5778 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5779 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5780 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5781 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5782 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5783 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5784 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5785 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5786 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5787 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5788 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5790 hr = IDirect3DDevice9_BeginScene(device);
5791 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5792 if(SUCCEEDED(hr))
5794 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5795 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5797 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5799 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5800 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5804 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5805 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5807 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5809 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5810 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5812 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5813 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5815 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5817 hr = IDirect3DDevice9_EndScene(device);
5818 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5821 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5822 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5824 color = getPixelColor(device, 160, 360);
5825 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5826 color = getPixelColor(device, 480, 360);
5827 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5828 color = getPixelColor(device, 160, 120);
5829 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5830 color = getPixelColor(device, 480, 160);
5831 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5833 IDirect3DVertexShader9_Release(shader_sge_vec);
5834 IDirect3DVertexShader9_Release(shader_slt_vec);
5835 IDirect3DVertexShader9_Release(shader_sge_scalar);
5836 IDirect3DVertexShader9_Release(shader_slt_scalar);
5839 void test_vshader_input(IDirect3DDevice9 *device)
5841 DWORD swapped_shader_code_3[] = {
5842 0xfffe0300, /* vs_3_0 */
5843 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5844 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5845 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5846 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5847 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5848 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5849 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5850 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5851 0x0000ffff /* end */
5853 DWORD swapped_shader_code_1[] = {
5854 0xfffe0101, /* vs_1_1 */
5855 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5856 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5857 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5858 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5859 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5860 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5861 0x0000ffff /* end */
5863 DWORD swapped_shader_code_2[] = {
5864 0xfffe0200, /* vs_2_0 */
5865 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5866 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5867 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5868 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5869 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5870 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5871 0x0000ffff /* end */
5873 DWORD texcoord_color_shader_code_3[] = {
5874 0xfffe0300, /* vs_3_0 */
5875 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5876 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5877 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5878 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5879 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5880 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5881 0x0000ffff /* end */
5883 DWORD texcoord_color_shader_code_2[] = {
5884 0xfffe0200, /* vs_2_0 */
5885 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5886 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5887 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5888 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5889 0x0000ffff /* end */
5891 DWORD texcoord_color_shader_code_1[] = {
5892 0xfffe0101, /* vs_1_1 */
5893 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5894 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5895 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5896 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5897 0x0000ffff /* end */
5899 DWORD color_color_shader_code_3[] = {
5900 0xfffe0300, /* vs_3_0 */
5901 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5902 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5903 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5904 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5905 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5906 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5907 0x0000ffff /* end */
5909 DWORD color_color_shader_code_2[] = {
5910 0xfffe0200, /* vs_2_0 */
5911 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5912 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5913 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5914 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5915 0x0000ffff /* end */
5917 DWORD color_color_shader_code_1[] = {
5918 0xfffe0101, /* vs_1_1 */
5919 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5920 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5921 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5922 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5923 0x0000ffff /* end */
5925 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5926 HRESULT hr;
5927 DWORD color, r, g, b;
5928 float quad1[] = {
5929 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5930 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5931 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5932 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5934 float quad2[] = {
5935 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5936 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5937 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5938 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5940 float quad3[] = {
5941 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5942 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5943 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5944 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5946 float quad4[] = {
5947 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5948 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5949 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5950 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5952 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5953 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5954 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5955 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5956 D3DDECL_END()
5958 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5959 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5960 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5961 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5962 D3DDECL_END()
5964 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5965 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5966 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5967 D3DDECL_END()
5969 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5970 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5971 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5972 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5973 D3DDECL_END()
5975 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5976 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5977 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5978 D3DDECL_END()
5980 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5982 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5983 D3DDECL_END()
5985 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5987 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5988 D3DDECL_END()
5990 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5991 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5992 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5993 D3DDECL_END()
5995 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5996 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5997 unsigned int i;
5998 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5999 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6001 struct vertex quad1_color[] = {
6002 {-1.0, -1.0, 0.1, 0x00ff8040},
6003 { 0.0, -1.0, 0.1, 0x00ff8040},
6004 {-1.0, 0.0, 0.1, 0x00ff8040},
6005 { 0.0, 0.0, 0.1, 0x00ff8040}
6007 struct vertex quad2_color[] = {
6008 { 0.0, -1.0, 0.1, 0x00ff8040},
6009 { 1.0, -1.0, 0.1, 0x00ff8040},
6010 { 0.0, 0.0, 0.1, 0x00ff8040},
6011 { 1.0, 0.0, 0.1, 0x00ff8040}
6013 struct vertex quad3_color[] = {
6014 {-1.0, 0.0, 0.1, 0x00ff8040},
6015 { 0.0, 0.0, 0.1, 0x00ff8040},
6016 {-1.0, 1.0, 0.1, 0x00ff8040},
6017 { 0.0, 1.0, 0.1, 0x00ff8040}
6019 float quad4_color[] = {
6020 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6021 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6022 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6023 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6026 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6027 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6028 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6030 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6032 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6033 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6035 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6036 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6037 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6039 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6040 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6041 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6042 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6044 for(i = 1; i <= 3; i++) {
6045 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6046 if(i == 3) {
6047 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6048 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6049 } else if(i == 2){
6050 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6051 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6052 } else if(i == 1) {
6053 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6054 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6057 hr = IDirect3DDevice9_BeginScene(device);
6058 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6059 if(SUCCEEDED(hr))
6061 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6062 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6064 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6065 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6067 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6069 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6070 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6072 if(i == 3 || i == 2) {
6073 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6074 } else if(i == 1) {
6075 /* Succeeds or fails, depending on SW or HW vertex processing */
6076 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6079 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6080 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6081 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6082 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6084 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6085 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6087 if(i == 3 || i == 2) {
6088 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6089 } else if(i == 1) {
6090 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6093 hr = IDirect3DDevice9_EndScene(device);
6094 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6097 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6098 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6100 if(i == 3 || i == 2) {
6101 color = getPixelColor(device, 160, 360);
6102 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6103 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6105 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6106 color = getPixelColor(device, 480, 360);
6107 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6108 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6109 color = getPixelColor(device, 160, 120);
6110 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6111 ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6112 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6114 color = getPixelColor(device, 480, 160);
6115 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6116 } else if(i == 1) {
6117 color = getPixelColor(device, 160, 360);
6118 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6119 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6120 color = getPixelColor(device, 480, 360);
6121 /* Accept the clear color as well in this case, since SW VP returns an error */
6122 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6123 color = getPixelColor(device, 160, 120);
6124 ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6125 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6126 color = getPixelColor(device, 480, 160);
6127 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6131 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6133 /* Now find out if the whole streams are re-read, or just the last active value for the
6134 * vertices is used.
6136 hr = IDirect3DDevice9_BeginScene(device);
6137 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6138 if(SUCCEEDED(hr))
6140 float quad1_modified[] = {
6141 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6142 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6143 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6144 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6146 float quad2_modified[] = {
6147 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6148 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6149 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6150 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6153 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6154 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6156 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6157 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6159 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6161 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6162 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6164 if(i == 3 || i == 2) {
6165 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6166 } else if(i == 1) {
6167 /* Succeeds or fails, depending on SW or HW vertex processing */
6168 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6171 hr = IDirect3DDevice9_EndScene(device);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6175 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6177 color = getPixelColor(device, 480, 350);
6178 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6179 * as well.
6181 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6182 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6183 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6184 * refrast's result.
6186 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6188 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6189 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6190 color = getPixelColor(device, 160, 120);
6192 IDirect3DDevice9_SetVertexShader(device, NULL);
6193 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6195 IDirect3DVertexShader9_Release(swapped_shader);
6198 for(i = 1; i <= 3; i++) {
6199 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6200 if(i == 3) {
6201 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6203 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6205 } else if(i == 2){
6206 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6207 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6208 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6209 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6210 } else if(i == 1) {
6211 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6212 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6213 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6214 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6217 hr = IDirect3DDevice9_BeginScene(device);
6218 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6219 if(SUCCEEDED(hr))
6221 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6222 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6223 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6224 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6226 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6228 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6231 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6232 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6233 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6234 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6236 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6238 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6240 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6241 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6243 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6245 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6246 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6248 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6250 hr = IDirect3DDevice9_EndScene(device);
6251 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6253 IDirect3DDevice9_SetVertexShader(device, NULL);
6254 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6257 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6259 color = getPixelColor(device, 160, 360);
6260 r = (color & 0x00ff0000) >> 16;
6261 g = (color & 0x0000ff00) >> 8;
6262 b = (color & 0x000000ff) >> 0;
6263 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6264 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6265 color = getPixelColor(device, 480, 360);
6266 r = (color & 0x00ff0000) >> 16;
6267 g = (color & 0x0000ff00) >> 8;
6268 b = (color & 0x000000ff) >> 0;
6269 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6270 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6271 color = getPixelColor(device, 160, 120);
6272 r = (color & 0x00ff0000) >> 16;
6273 g = (color & 0x0000ff00) >> 8;
6274 b = (color & 0x000000ff) >> 0;
6275 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6276 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6277 color = getPixelColor(device, 480, 160);
6278 r = (color & 0x00ff0000) >> 16;
6279 g = (color & 0x0000ff00) >> 8;
6280 b = (color & 0x000000ff) >> 0;
6281 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6282 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6284 IDirect3DVertexShader9_Release(texcoord_color_shader);
6285 IDirect3DVertexShader9_Release(color_color_shader);
6288 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6289 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6290 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6291 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6293 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6294 IDirect3DVertexDeclaration9_Release(decl_color_color);
6295 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6296 IDirect3DVertexDeclaration9_Release(decl_color_float);
6299 static void srgbtexture_test(IDirect3DDevice9 *device)
6301 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6302 * texture stage state to render a quad using that texture. The resulting
6303 * color components should be 0x36 (~ 0.21), per this formula:
6304 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6305 * This is true where srgb_color > 0.04045.
6307 IDirect3D9 *d3d = NULL;
6308 HRESULT hr;
6309 LPDIRECT3DTEXTURE9 texture = NULL;
6310 LPDIRECT3DSURFACE9 surface = NULL;
6311 D3DLOCKED_RECT lr;
6312 DWORD color;
6313 float quad[] = {
6314 -1.0, 1.0, 0.0, 0.0, 0.0,
6315 1.0, 1.0, 0.0, 1.0, 0.0,
6316 -1.0, -1.0, 0.0, 0.0, 1.0,
6317 1.0, -1.0, 0.0, 1.0, 1.0,
6321 memset(&lr, 0, sizeof(lr));
6322 IDirect3DDevice9_GetDirect3D(device, &d3d);
6323 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6324 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6325 D3DFMT_A8R8G8B8) != D3D_OK) {
6326 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6327 goto out;
6330 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6331 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6332 &texture, NULL);
6333 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6334 if(!texture) {
6335 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6336 goto out;
6338 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6339 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6341 fill_surface(surface, 0xff7f7f7f);
6342 IDirect3DSurface9_Release(surface);
6344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6345 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6346 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6349 hr = IDirect3DDevice9_BeginScene(device);
6350 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6351 if(SUCCEEDED(hr))
6353 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6356 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6361 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6363 hr = IDirect3DDevice9_EndScene(device);
6364 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6367 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6368 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6369 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6370 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6372 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6373 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6375 color = getPixelColor(device, 320, 240);
6376 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6378 out:
6379 if(texture) IDirect3DTexture9_Release(texture);
6380 IDirect3D9_Release(d3d);
6383 /* Return true if color is near the expected value */
6384 static int color_near(DWORD color, DWORD expected)
6386 const BYTE slop = 2;
6388 BYTE r, g, b;
6389 BYTE rx, gx, bx;
6390 r = (color & 0x00ff0000) >> 16;
6391 g = (color & 0x0000ff00) >> 8;
6392 b = (color & 0x000000ff);
6393 rx = (expected & 0x00ff0000) >> 16;
6394 gx = (expected & 0x0000ff00) >> 8;
6395 bx = (expected & 0x000000ff);
6397 return
6398 ((r >= (rx - slop)) && (r <= (rx + slop))) &&
6399 ((g >= (gx - slop)) && (g <= (gx + slop))) &&
6400 ((b >= (bx - slop)) && (b <= (bx + slop)));
6403 static void shademode_test(IDirect3DDevice9 *device)
6405 /* Render a quad and try all of the different fixed function shading models. */
6406 HRESULT hr;
6407 DWORD color0, color1;
6408 DWORD color0_gouraud = 0, color1_gouraud = 0;
6409 DWORD shademode = D3DSHADE_FLAT;
6410 DWORD primtype = D3DPT_TRIANGLESTRIP;
6411 LPVOID data = NULL;
6412 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6413 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6414 UINT i, j;
6415 struct vertex quad_strip[] =
6417 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6418 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6419 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6420 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6422 struct vertex quad_list[] =
6424 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6425 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6426 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6428 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6429 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6430 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6433 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6434 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6435 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6436 if (FAILED(hr)) goto bail;
6438 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6439 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6440 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6441 if (FAILED(hr)) goto bail;
6443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6444 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6446 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6447 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6449 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6450 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6451 memcpy(data, quad_strip, sizeof(quad_strip));
6452 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6453 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6455 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6456 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6457 memcpy(data, quad_list, sizeof(quad_list));
6458 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6459 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6461 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6462 * the color fixups we have to do for FLAT shading will be dependent on that. */
6463 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6464 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6466 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6467 for (j=0; j<2; j++) {
6469 /* Inner loop just changes the D3DRS_SHADEMODE */
6470 for (i=0; i<3; i++) {
6471 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6472 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6475 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6477 hr = IDirect3DDevice9_BeginScene(device);
6478 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6479 if(SUCCEEDED(hr))
6481 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6482 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6484 hr = IDirect3DDevice9_EndScene(device);
6485 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6488 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6489 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6491 /* Sample two spots from the output */
6492 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6493 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6494 switch(shademode) {
6495 case D3DSHADE_FLAT:
6496 /* Should take the color of the first vertex of each triangle */
6497 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6498 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6499 shademode = D3DSHADE_GOURAUD;
6500 break;
6501 case D3DSHADE_GOURAUD:
6502 /* Should be an interpolated blend */
6504 ok(color_near(color0, 0x000dca28),
6505 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6506 ok(color_near(color1, 0x000d45c7),
6507 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6509 color0_gouraud = color0;
6510 color1_gouraud = color1;
6512 shademode = D3DSHADE_PHONG;
6513 break;
6514 case D3DSHADE_PHONG:
6515 /* Should be the same as GOURAUD, since no hardware implements this */
6516 ok(color_near(color0, 0x000dca28),
6517 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6518 ok(color_near(color1, 0x000d45c7),
6519 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6521 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6522 color0_gouraud, color0);
6523 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6524 color1_gouraud, color1);
6525 break;
6528 /* Now, do it all over again with a TRIANGLELIST */
6529 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6530 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6531 primtype = D3DPT_TRIANGLELIST;
6532 shademode = D3DSHADE_FLAT;
6535 bail:
6536 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6537 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6538 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6539 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6541 if (vb_strip)
6542 IDirect3DVertexBuffer9_Release(vb_strip);
6543 if (vb_list)
6544 IDirect3DVertexBuffer9_Release(vb_list);
6548 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6550 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6551 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6552 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6553 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6554 * 0.73
6556 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6557 * so use shaders for this task
6559 IDirect3DPixelShader9 *pshader;
6560 IDirect3DVertexShader9 *vshader;
6561 IDirect3D9 *d3d;
6562 DWORD vshader_code[] = {
6563 0xfffe0101, /* vs_1_1 */
6564 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6565 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6566 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6567 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6568 0x0000ffff /* end */
6570 DWORD pshader_code[] = {
6571 0xffff0101, /* ps_1_1 */
6572 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6573 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6574 0x0000ffff /* end */
6576 const float quad[] = {
6577 -1.0, -1.0, 0.1,
6578 1.0, -1.0, 0.1,
6579 -1.0, 1.0, 0.1,
6580 1.0, 1.0, 0.1
6582 HRESULT hr;
6583 DWORD color;
6585 IDirect3DDevice9_GetDirect3D(device, &d3d);
6586 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6587 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6588 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6589 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6590 * works
6592 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6593 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6594 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6595 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6596 IDirect3D9_Release(d3d);
6597 return;
6599 IDirect3D9_Release(d3d);
6601 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6602 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6605 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6611 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6613 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6615 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6616 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6617 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6618 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6619 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6620 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6621 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6622 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6623 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6624 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6626 hr = IDirect3DDevice9_BeginScene(device);
6627 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6628 if(SUCCEEDED(hr)) {
6629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6630 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6632 hr = IDirect3DDevice9_EndScene(device);
6633 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6636 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6637 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6638 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6639 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6640 IDirect3DPixelShader9_Release(pshader);
6641 IDirect3DVertexShader9_Release(vshader);
6643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6644 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6646 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6648 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6649 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6650 color = getPixelColor(device, 160, 360);
6651 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6652 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6655 static void alpha_test(IDirect3DDevice9 *device)
6657 HRESULT hr;
6658 IDirect3DTexture9 *offscreenTexture;
6659 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6660 DWORD color;
6662 struct vertex quad1[] =
6664 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6665 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6666 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6667 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6669 struct vertex quad2[] =
6671 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6672 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6673 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6674 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6676 static const float composite_quad[][5] = {
6677 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6678 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6679 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6680 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6683 /* Clear the render target with alpha = 0.5 */
6684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6685 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6687 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6688 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6690 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6691 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6692 if(!backbuffer) {
6693 goto out;
6696 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6697 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6698 if(!offscreen) {
6699 goto out;
6702 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6703 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6705 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6706 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6707 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6708 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6709 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6710 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6711 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6712 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6718 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6720 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6722 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6726 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6729 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6731 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6733 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6735 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6736 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6737 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6738 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6739 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6740 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6741 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6744 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6746 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6748 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6751 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6753 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6755 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6757 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6758 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6760 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6761 * Disable alpha blending for the final composition
6763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6764 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6765 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6766 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6768 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6771 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6772 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6775 hr = IDirect3DDevice9_EndScene(device);
6776 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6779 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6781 color = getPixelColor(device, 160, 360);
6782 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6783 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6785 color = getPixelColor(device, 160, 120);
6786 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6787 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6789 color = getPixelColor(device, 480, 360);
6790 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6791 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6793 color = getPixelColor(device, 480, 120);
6794 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6795 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6797 out:
6798 /* restore things */
6799 if(backbuffer) {
6800 IDirect3DSurface9_Release(backbuffer);
6802 if(offscreenTexture) {
6803 IDirect3DTexture9_Release(offscreenTexture);
6805 if(offscreen) {
6806 IDirect3DSurface9_Release(offscreen);
6810 struct vertex_shortcolor {
6811 float x, y, z;
6812 unsigned short r, g, b, a;
6814 struct vertex_floatcolor {
6815 float x, y, z;
6816 float r, g, b, a;
6819 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6821 HRESULT hr;
6822 BOOL s_ok, ub_ok, f_ok;
6823 DWORD color, size, i;
6824 void *data;
6825 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6826 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6827 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6828 D3DDECL_END()
6830 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6831 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6832 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6833 D3DDECL_END()
6835 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6836 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6837 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6838 D3DDECL_END()
6840 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6841 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6842 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6843 D3DDECL_END()
6845 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6846 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6847 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6848 D3DDECL_END()
6850 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6851 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6852 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6853 D3DDECL_END()
6855 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6856 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6857 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6858 D3DDECL_END()
6860 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6861 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6862 IDirect3DVertexBuffer9 *vb, *vb2;
6863 struct vertex quad1[] = /* D3DCOLOR */
6865 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6866 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6867 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6868 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6870 struct vertex quad2[] = /* UBYTE4N */
6872 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6873 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6874 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6875 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6877 struct vertex_shortcolor quad3[] = /* short */
6879 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6880 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6881 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6882 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6884 struct vertex_floatcolor quad4[] =
6886 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6887 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6888 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6889 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6891 DWORD colors[] = {
6892 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6893 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6894 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6895 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6896 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6897 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6898 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6899 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6900 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6901 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6902 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
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,
6909 float quads[] = {
6910 -1.0, -1.0, 0.1,
6911 -1.0, 0.0, 0.1,
6912 0.0, -1.0, 0.1,
6913 0.0, 0.0, 0.1,
6915 0.0, -1.0, 0.1,
6916 0.0, 0.0, 0.1,
6917 1.0, -1.0, 0.1,
6918 1.0, 0.0, 0.1,
6920 0.0, 0.0, 0.1,
6921 0.0, 1.0, 0.1,
6922 1.0, 0.0, 0.1,
6923 1.0, 1.0, 0.1,
6925 -1.0, 0.0, 0.1,
6926 -1.0, 1.0, 0.1,
6927 0.0, 0.0, 0.1,
6928 0.0, 1.0, 0.1
6930 struct tvertex quad_transformed[] = {
6931 { 90, 110, 0.1, 2.0, 0x00ffff00},
6932 { 570, 110, 0.1, 2.0, 0x00ffff00},
6933 { 90, 300, 0.1, 2.0, 0x00ffff00},
6934 { 570, 300, 0.1, 2.0, 0x00ffff00}
6936 D3DCAPS9 caps;
6938 memset(&caps, 0, sizeof(caps));
6939 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6940 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6943 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6945 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6946 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6947 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6948 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6949 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6950 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6951 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6952 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6953 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6954 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6955 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6956 } else {
6957 trace("D3DDTCAPS_UBYTE4N not supported\n");
6958 dcl_ubyte_2 = NULL;
6959 dcl_ubyte = NULL;
6961 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6962 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6963 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6964 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6966 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6967 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6968 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6969 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6971 hr = IDirect3DDevice9_BeginScene(device);
6972 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6973 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6974 if(SUCCEEDED(hr)) {
6975 if(dcl_color) {
6976 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6977 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6979 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6982 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6983 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6984 * using software vertex processing. Doh!
6986 if(dcl_ubyte) {
6987 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6990 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6991 ub_ok = SUCCEEDED(hr);
6994 if(dcl_short) {
6995 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6996 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6998 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6999 s_ok = SUCCEEDED(hr);
7002 if(dcl_float) {
7003 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7004 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7005 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7006 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7007 f_ok = SUCCEEDED(hr);
7010 hr = IDirect3DDevice9_EndScene(device);
7011 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7014 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7015 if(dcl_short) {
7016 color = getPixelColor(device, 480, 360);
7017 ok(color == 0x000000ff || !s_ok,
7018 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7020 if(dcl_ubyte) {
7021 color = getPixelColor(device, 160, 120);
7022 ok(color == 0x0000ffff || !ub_ok,
7023 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7025 if(dcl_color) {
7026 color = getPixelColor(device, 160, 360);
7027 ok(color == 0x00ffff00,
7028 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7030 if(dcl_float) {
7031 color = getPixelColor(device, 480, 120);
7032 ok(color == 0x00ff0000 || !f_ok,
7033 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7036 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7037 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7038 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7039 * whether the immediate mode code works
7041 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7042 hr = IDirect3DDevice9_BeginScene(device);
7043 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7044 if(SUCCEEDED(hr)) {
7045 if(dcl_color) {
7046 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7047 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7048 memcpy(data, quad1, sizeof(quad1));
7049 hr = IDirect3DVertexBuffer9_Unlock(vb);
7050 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7051 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7052 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7053 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7054 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7055 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7056 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7059 if(dcl_ubyte) {
7060 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7061 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7062 memcpy(data, quad2, sizeof(quad2));
7063 hr = IDirect3DVertexBuffer9_Unlock(vb);
7064 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7065 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7066 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7067 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7068 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7069 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7070 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7071 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7072 ub_ok = SUCCEEDED(hr);
7075 if(dcl_short) {
7076 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7077 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7078 memcpy(data, quad3, sizeof(quad3));
7079 hr = IDirect3DVertexBuffer9_Unlock(vb);
7080 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7081 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7084 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7085 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7086 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7087 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7088 s_ok = SUCCEEDED(hr);
7091 if(dcl_float) {
7092 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7093 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7094 memcpy(data, quad4, sizeof(quad4));
7095 hr = IDirect3DVertexBuffer9_Unlock(vb);
7096 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7097 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7098 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7099 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7100 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7101 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7102 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7103 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7104 f_ok = SUCCEEDED(hr);
7107 hr = IDirect3DDevice9_EndScene(device);
7108 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7111 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7112 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7113 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7114 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7116 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7117 if(dcl_short) {
7118 color = getPixelColor(device, 480, 360);
7119 ok(color == 0x000000ff || !s_ok,
7120 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7122 if(dcl_ubyte) {
7123 color = getPixelColor(device, 160, 120);
7124 ok(color == 0x0000ffff || !ub_ok,
7125 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7127 if(dcl_color) {
7128 color = getPixelColor(device, 160, 360);
7129 ok(color == 0x00ffff00,
7130 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7132 if(dcl_float) {
7133 color = getPixelColor(device, 480, 120);
7134 ok(color == 0x00ff0000 || !f_ok,
7135 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7139 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7141 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7142 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7143 memcpy(data, quad_transformed, sizeof(quad_transformed));
7144 hr = IDirect3DVertexBuffer9_Unlock(vb);
7145 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7147 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7148 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7150 hr = IDirect3DDevice9_BeginScene(device);
7151 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7152 if(SUCCEEDED(hr)) {
7153 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7154 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7155 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7156 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7158 hr = IDirect3DDevice9_EndScene(device);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7162 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7163 color = getPixelColor(device, 88, 108);
7164 ok(color == 0x000000ff,
7165 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7166 color = getPixelColor(device, 92, 108);
7167 ok(color == 0x000000ff,
7168 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7169 color = getPixelColor(device, 88, 112);
7170 ok(color == 0x000000ff,
7171 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7172 color = getPixelColor(device, 92, 112);
7173 ok(color == 0x00ffff00,
7174 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7176 color = getPixelColor(device, 568, 108);
7177 ok(color == 0x000000ff,
7178 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7179 color = getPixelColor(device, 572, 108);
7180 ok(color == 0x000000ff,
7181 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7182 color = getPixelColor(device, 568, 112);
7183 ok(color == 0x00ffff00,
7184 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7185 color = getPixelColor(device, 572, 112);
7186 ok(color == 0x000000ff,
7187 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7189 color = getPixelColor(device, 88, 298);
7190 ok(color == 0x000000ff,
7191 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7192 color = getPixelColor(device, 92, 298);
7193 ok(color == 0x00ffff00,
7194 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7195 color = getPixelColor(device, 88, 302);
7196 ok(color == 0x000000ff,
7197 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7198 color = getPixelColor(device, 92, 302);
7199 ok(color == 0x000000ff,
7200 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7202 color = getPixelColor(device, 568, 298);
7203 ok(color == 0x00ffff00,
7204 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7205 color = getPixelColor(device, 572, 298);
7206 ok(color == 0x000000ff,
7207 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7208 color = getPixelColor(device, 568, 302);
7209 ok(color == 0x000000ff,
7210 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7211 color = getPixelColor(device, 572, 302);
7212 ok(color == 0x000000ff,
7213 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7215 /* This test is pointless without those two declarations: */
7216 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7217 skip("color-ubyte switching test declarations aren't supported\n");
7218 goto out;
7221 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7222 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7223 memcpy(data, quads, sizeof(quads));
7224 hr = IDirect3DVertexBuffer9_Unlock(vb);
7225 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7226 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7227 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7228 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7229 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7230 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7231 memcpy(data, colors, sizeof(colors));
7232 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7233 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7235 for(i = 0; i < 2; i++) {
7236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7239 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7240 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7241 if(i == 0) {
7242 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7243 } else {
7244 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7246 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7248 hr = IDirect3DDevice9_BeginScene(device);
7249 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7250 ub_ok = FALSE;
7251 if(SUCCEEDED(hr)) {
7252 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7253 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7254 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7255 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7256 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7257 ub_ok = SUCCEEDED(hr);
7259 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7260 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7261 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7262 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7264 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7265 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7266 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7267 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7268 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7269 ub_ok = (SUCCEEDED(hr) && ub_ok);
7271 hr = IDirect3DDevice9_EndScene(device);
7272 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7275 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7276 if(i == 0) {
7277 color = getPixelColor(device, 480, 360);
7278 ok(color == 0x00ff0000,
7279 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7280 color = getPixelColor(device, 160, 120);
7281 ok(color == 0x00ffffff,
7282 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7283 color = getPixelColor(device, 160, 360);
7284 ok(color == 0x000000ff || !ub_ok,
7285 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7286 color = getPixelColor(device, 480, 120);
7287 ok(color == 0x000000ff || !ub_ok,
7288 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7289 } else {
7290 color = getPixelColor(device, 480, 360);
7291 ok(color == 0x000000ff,
7292 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7293 color = getPixelColor(device, 160, 120);
7294 ok(color == 0x00ffffff,
7295 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7296 color = getPixelColor(device, 160, 360);
7297 ok(color == 0x00ff0000 || !ub_ok,
7298 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7299 color = getPixelColor(device, 480, 120);
7300 ok(color == 0x00ff0000 || !ub_ok,
7301 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7305 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7307 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7308 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7309 IDirect3DVertexBuffer9_Release(vb2);
7311 out:
7312 IDirect3DVertexBuffer9_Release(vb);
7313 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7314 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7315 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7316 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7317 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7318 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7319 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7322 struct vertex_float16color {
7323 float x, y, z;
7324 DWORD c1, c2;
7327 static void test_vshader_float16(IDirect3DDevice9 *device)
7329 HRESULT hr;
7330 DWORD color;
7331 void *data;
7332 static const D3DVERTEXELEMENT9 decl_elements[] = {
7333 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7334 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7335 D3DDECL_END()
7337 IDirect3DVertexDeclaration9 *vdecl = NULL;
7338 IDirect3DVertexBuffer9 *buffer = NULL;
7339 IDirect3DVertexShader9 *shader;
7340 DWORD shader_code[] = {
7341 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7342 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7343 0x90e40001, 0x0000ffff
7345 struct vertex_float16color quad[] = {
7346 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7347 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7348 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7349 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7351 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7352 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7353 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7354 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7356 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7357 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7358 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7359 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7361 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7362 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7363 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7364 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7367 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7368 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7370 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7371 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7372 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7373 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7374 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7375 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7377 hr = IDirect3DDevice9_BeginScene(device);
7378 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7379 if(SUCCEEDED(hr)) {
7380 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7381 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7383 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7385 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7387 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7389 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7391 hr = IDirect3DDevice9_EndScene(device);
7392 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7394 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7395 color = getPixelColor(device, 480, 360);
7396 ok(color == 0x00ff0000,
7397 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7398 color = getPixelColor(device, 160, 120);
7399 ok(color == 0x00000000,
7400 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7401 color = getPixelColor(device, 160, 360);
7402 ok(color == 0x0000ff00,
7403 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7404 color = getPixelColor(device, 480, 120);
7405 ok(color == 0x000000ff,
7406 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7408 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7409 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7411 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7412 D3DPOOL_MANAGED, &buffer, NULL);
7413 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7414 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7415 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7416 memcpy(data, quad, sizeof(quad));
7417 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7418 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7419 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7420 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7422 hr = IDirect3DDevice9_BeginScene(device);
7423 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7424 if(SUCCEEDED(hr)) {
7425 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7426 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7427 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7428 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7429 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7430 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7431 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7432 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7434 hr = IDirect3DDevice9_EndScene(device);
7435 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7438 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7439 color = getPixelColor(device, 480, 360);
7440 ok(color == 0x00ff0000,
7441 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7442 color = getPixelColor(device, 160, 120);
7443 ok(color == 0x00000000,
7444 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7445 color = getPixelColor(device, 160, 360);
7446 ok(color == 0x0000ff00,
7447 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7448 color = getPixelColor(device, 480, 120);
7449 ok(color == 0x000000ff,
7450 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7452 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7453 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7454 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7455 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7456 IDirect3DDevice9_SetVertexShader(device, NULL);
7457 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7459 IDirect3DVertexDeclaration9_Release(vdecl);
7460 IDirect3DVertexShader9_Release(shader);
7461 IDirect3DVertexBuffer9_Release(buffer);
7464 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7466 D3DCAPS9 caps;
7467 IDirect3DTexture9 *texture;
7468 HRESULT hr;
7469 D3DLOCKED_RECT rect;
7470 unsigned int x, y;
7471 DWORD *dst, color;
7472 const float quad[] = {
7473 -1.0, -1.0, 0.1, -0.2, -0.2,
7474 1.0, -1.0, 0.1, 1.2, -0.2,
7475 -1.0, 1.0, 0.1, -0.2, 1.2,
7476 1.0, 1.0, 0.1, 1.2, 1.2
7478 memset(&caps, 0, sizeof(caps));
7480 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7481 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7482 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7483 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7484 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7485 "Card has conditional NP2 support without power of two restriction set\n");
7486 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7487 return;
7488 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7489 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7490 return;
7493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7496 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7497 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7499 memset(&rect, 0, sizeof(rect));
7500 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7501 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7502 for(y = 0; y < 10; y++) {
7503 for(x = 0; x < 10; x++) {
7504 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7505 if(x == 0 || x == 9 || y == 0 || y == 9) {
7506 *dst = 0x00ff0000;
7507 } else {
7508 *dst = 0x000000ff;
7512 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7513 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7515 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7516 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7517 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7518 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7519 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7520 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7521 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7522 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7524 hr = IDirect3DDevice9_BeginScene(device);
7525 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7526 if(SUCCEEDED(hr)) {
7527 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7528 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7530 hr = IDirect3DDevice9_EndScene(device);
7531 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7534 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7536 color = getPixelColor(device, 1, 1);
7537 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7538 color = getPixelColor(device, 639, 479);
7539 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7541 color = getPixelColor(device, 135, 101);
7542 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7543 color = getPixelColor(device, 140, 101);
7544 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7545 color = getPixelColor(device, 135, 105);
7546 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7547 color = getPixelColor(device, 140, 105);
7548 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7550 color = getPixelColor(device, 135, 376);
7551 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7552 color = getPixelColor(device, 140, 376);
7553 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7554 color = getPixelColor(device, 135, 379);
7555 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7556 color = getPixelColor(device, 140, 379);
7557 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7559 color = getPixelColor(device, 500, 101);
7560 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7561 color = getPixelColor(device, 504, 101);
7562 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7563 color = getPixelColor(device, 500, 105);
7564 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7565 color = getPixelColor(device, 504, 105);
7566 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7568 color = getPixelColor(device, 500, 376);
7569 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7570 color = getPixelColor(device, 504, 376);
7571 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7572 color = getPixelColor(device, 500, 380);
7573 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7574 color = getPixelColor(device, 504, 380);
7575 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7577 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7578 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7579 IDirect3DTexture9_Release(texture);
7582 static void vFace_register_test(IDirect3DDevice9 *device)
7584 HRESULT hr;
7585 DWORD color;
7586 const DWORD shader_code[] = {
7587 0xffff0300, /* ps_3_0 */
7588 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7589 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7590 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7591 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7592 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7593 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7594 0x0000ffff /* END */
7596 IDirect3DPixelShader9 *shader;
7597 IDirect3DTexture9 *texture;
7598 IDirect3DSurface9 *surface, *backbuffer;
7599 const float quad[] = {
7600 -1.0, -1.0, 0.1,
7601 1.0, -1.0, 0.1,
7602 -1.0, 0.0, 0.1,
7604 1.0, -1.0, 0.1,
7605 1.0, 0.0, 0.1,
7606 -1.0, 0.0, 0.1,
7608 -1.0, 0.0, 0.1,
7609 -1.0, 1.0, 0.1,
7610 1.0, 0.0, 0.1,
7612 1.0, 0.0, 0.1,
7613 -1.0, 1.0, 0.1,
7614 1.0, 1.0, 0.1,
7616 const float blit[] = {
7617 0.0, -1.0, 0.1, 0.0, 0.0,
7618 1.0, -1.0, 0.1, 1.0, 0.0,
7619 0.0, 1.0, 0.1, 0.0, 1.0,
7620 1.0, 1.0, 0.1, 1.0, 1.0,
7623 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7624 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7625 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7626 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7627 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7628 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7629 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7630 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7632 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7633 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7636 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7637 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7639 hr = IDirect3DDevice9_BeginScene(device);
7640 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7641 if(SUCCEEDED(hr)) {
7642 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7643 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7644 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7646 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7648 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7649 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7652 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7654 /* Blit the texture onto the back buffer to make it visible */
7655 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7656 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7657 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7658 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7659 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7660 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7661 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7662 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7663 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7666 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7667 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7669 hr = IDirect3DDevice9_EndScene(device);
7670 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7673 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7674 color = getPixelColor(device, 160, 360);
7675 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7676 color = getPixelColor(device, 160, 120);
7677 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7678 color = getPixelColor(device, 480, 360);
7679 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7680 color = getPixelColor(device, 480, 120);
7681 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7683 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7684 IDirect3DDevice9_SetTexture(device, 0, NULL);
7685 IDirect3DPixelShader9_Release(shader);
7686 IDirect3DSurface9_Release(surface);
7687 IDirect3DSurface9_Release(backbuffer);
7688 IDirect3DTexture9_Release(texture);
7691 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7693 HRESULT hr;
7694 DWORD color;
7695 int i;
7696 D3DCAPS9 caps;
7698 static const float quad[][7] = {
7699 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7700 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7701 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7702 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7705 static const D3DVERTEXELEMENT9 decl_elements[] = {
7706 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7707 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7708 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7709 D3DDECL_END()
7712 /* use asymmetric matrix to test loading */
7713 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7715 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7716 IDirect3DTexture9 *texture = NULL;
7718 memset(&caps, 0, sizeof(caps));
7719 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7720 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7721 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7722 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7723 return;
7724 } else {
7725 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7726 * They report that it is not supported, but after that bump mapping works properly. So just test
7727 * if the format is generally supported, and check the BUMPENVMAP flag
7729 IDirect3D9 *d3d9;
7731 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7732 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7733 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7734 IDirect3D9_Release(d3d9);
7735 if(FAILED(hr)) {
7736 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7737 return;
7741 /* Generate the textures */
7742 generate_bumpmap_textures(device);
7744 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7745 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7746 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7747 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7748 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7749 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7750 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7751 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7753 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7754 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7755 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7756 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7757 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7758 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7760 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7761 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7762 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7763 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7764 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7765 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7767 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7768 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7770 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7771 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7774 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7777 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7778 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7779 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7780 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7782 hr = IDirect3DDevice9_BeginScene(device);
7783 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7786 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7788 hr = IDirect3DDevice9_EndScene(device);
7789 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7791 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7792 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7794 color = getPixelColor(device, 320-32, 240);
7795 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7796 color = getPixelColor(device, 320+32, 240);
7797 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7798 color = getPixelColor(device, 320, 240-32);
7799 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7800 color = getPixelColor(device, 320, 240+32);
7801 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7802 color = getPixelColor(device, 320, 240);
7803 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7804 color = getPixelColor(device, 320+32, 240+32);
7805 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7806 color = getPixelColor(device, 320-32, 240+32);
7807 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7808 color = getPixelColor(device, 320+32, 240-32);
7809 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7810 color = getPixelColor(device, 320-32, 240-32);
7811 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7813 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7814 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7815 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7817 for(i = 0; i < 2; i++) {
7818 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7819 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7820 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7821 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7822 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7823 IDirect3DTexture9_Release(texture); /* To destroy it */
7826 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7827 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7828 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7829 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7833 static void stencil_cull_test(IDirect3DDevice9 *device) {
7834 HRESULT hr;
7835 IDirect3DSurface9 *depthstencil = NULL;
7836 D3DSURFACE_DESC desc;
7837 float quad1[] = {
7838 -1.0, -1.0, 0.1,
7839 0.0, -1.0, 0.1,
7840 -1.0, 0.0, 0.1,
7841 0.0, 0.0, 0.1,
7843 float quad2[] = {
7844 0.0, -1.0, 0.1,
7845 1.0, -1.0, 0.1,
7846 0.0, 0.0, 0.1,
7847 1.0, 0.0, 0.1,
7849 float quad3[] = {
7850 0.0, 0.0, 0.1,
7851 1.0, 0.0, 0.1,
7852 0.0, 1.0, 0.1,
7853 1.0, 1.0, 0.1,
7855 float quad4[] = {
7856 -1.0, 0.0, 0.1,
7857 0.0, 0.0, 0.1,
7858 -1.0, 1.0, 0.1,
7859 0.0, 1.0, 0.1,
7861 struct vertex painter[] = {
7862 {-1.0, -1.0, 0.0, 0x00000000},
7863 { 1.0, -1.0, 0.0, 0x00000000},
7864 {-1.0, 1.0, 0.0, 0x00000000},
7865 { 1.0, 1.0, 0.0, 0x00000000},
7867 WORD indices_cw[] = {0, 1, 3};
7868 WORD indices_ccw[] = {0, 2, 3};
7869 unsigned int i;
7870 DWORD color;
7872 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7873 if(depthstencil == NULL) {
7874 skip("No depth stencil buffer\n");
7875 return;
7877 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7878 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7879 IDirect3DSurface9_Release(depthstencil);
7880 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7881 skip("No 4 or 8 bit stencil surface\n");
7882 return;
7885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7886 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7887 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7889 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7890 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7896 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7899 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7906 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7910 /* First pass: Fill the stencil buffer with some values... */
7911 hr = IDirect3DDevice9_BeginScene(device);
7912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7913 if(SUCCEEDED(hr))
7915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7917 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7918 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7919 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7920 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7923 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7925 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7926 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7927 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7928 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7929 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7932 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7933 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7934 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7935 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7936 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7939 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7940 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7941 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7942 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7943 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7945 hr = IDirect3DDevice9_EndScene(device);
7946 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7949 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7951 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7953 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7955 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7957 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7959 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7961 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7963 /* 2nd pass: Make the stencil values visible */
7964 hr = IDirect3DDevice9_BeginScene(device);
7965 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7966 if(SUCCEEDED(hr))
7968 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7969 for(i = 0; i < 16; i++) {
7970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7971 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7973 painter[0].diffuse = (i * 16); /* Creates shades of blue */
7974 painter[1].diffuse = (i * 16);
7975 painter[2].diffuse = (i * 16);
7976 painter[3].diffuse = (i * 16);
7977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7978 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7980 hr = IDirect3DDevice9_EndScene(device);
7981 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7984 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7985 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7988 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7990 color = getPixelColor(device, 160, 420);
7991 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7992 color = getPixelColor(device, 160, 300);
7993 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7995 color = getPixelColor(device, 480, 420);
7996 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7997 color = getPixelColor(device, 480, 300);
7998 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8000 color = getPixelColor(device, 160, 180);
8001 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8002 color = getPixelColor(device, 160, 60);
8003 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8005 color = getPixelColor(device, 480, 180);
8006 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8007 color = getPixelColor(device, 480, 60);
8008 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8011 static void vpos_register_test(IDirect3DDevice9 *device)
8013 HRESULT hr;
8014 DWORD color;
8015 const DWORD shader_code[] = {
8016 0xffff0300, /* ps_3_0 */
8017 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8018 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8019 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8020 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8021 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8022 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8023 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8024 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8025 0x0000ffff /* end */
8027 const DWORD shader_frac_code[] = {
8028 0xffff0300, /* ps_3_0 */
8029 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8030 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8031 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8032 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8033 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8034 0x0000ffff /* end */
8036 IDirect3DPixelShader9 *shader, *shader_frac;
8037 IDirect3DSurface9 *surface = NULL, *backbuffer;
8038 const float quad[] = {
8039 -1.0, -1.0, 0.1, 0.0, 0.0,
8040 1.0, -1.0, 0.1, 1.0, 0.0,
8041 -1.0, 1.0, 0.1, 0.0, 1.0,
8042 1.0, 1.0, 0.1, 1.0, 1.0,
8044 D3DLOCKED_RECT lr;
8045 float constant[4] = {1.0, 0.0, 320, 240};
8046 DWORD *pos;
8048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8049 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8050 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8051 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8052 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8053 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8054 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8055 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8056 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8057 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8058 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8059 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8061 hr = IDirect3DDevice9_BeginScene(device);
8062 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8063 if(SUCCEEDED(hr)) {
8064 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8065 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8067 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8068 hr = IDirect3DDevice9_EndScene(device);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8072 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8073 /* This has to be pixel exact */
8074 color = getPixelColor(device, 319, 239);
8075 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8076 color = getPixelColor(device, 320, 239);
8077 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8078 color = getPixelColor(device, 319, 240);
8079 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8080 color = getPixelColor(device, 320, 240);
8081 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8083 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8084 &surface, NULL);
8085 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8086 hr = IDirect3DDevice9_BeginScene(device);
8087 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8088 if(SUCCEEDED(hr)) {
8089 constant[2] = 16; constant[3] = 16;
8090 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8091 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8092 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8093 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8094 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8095 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8096 hr = IDirect3DDevice9_EndScene(device);
8097 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8099 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8100 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8102 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8103 color = *pos & 0x00ffffff;
8104 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8105 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8106 color = *pos & 0x00ffffff;
8107 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8108 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8109 color = *pos & 0x00ffffff;
8110 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8111 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8112 color = *pos & 0x00ffffff;
8113 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8115 hr = IDirect3DSurface9_UnlockRect(surface);
8116 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8118 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8119 * have full control over the multisampling setting inside this test
8121 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8122 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8123 hr = IDirect3DDevice9_BeginScene(device);
8124 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8125 if(SUCCEEDED(hr)) {
8126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8127 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8129 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8130 hr = IDirect3DDevice9_EndScene(device);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8133 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8136 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8137 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8139 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8140 color = *pos & 0x00ffffff;
8141 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8143 hr = IDirect3DSurface9_UnlockRect(surface);
8144 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8146 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8147 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8148 IDirect3DPixelShader9_Release(shader);
8149 IDirect3DPixelShader9_Release(shader_frac);
8150 if(surface) IDirect3DSurface9_Release(surface);
8151 IDirect3DSurface9_Release(backbuffer);
8154 static void pointsize_test(IDirect3DDevice9 *device)
8156 HRESULT hr;
8157 D3DCAPS9 caps;
8158 D3DMATRIX matrix;
8159 D3DMATRIX identity;
8160 float ptsize, ptsize_orig;
8161 DWORD color;
8163 const float vertices[] = {
8164 64, 64, 0.1,
8165 128, 64, 0.1,
8166 192, 64, 0.1,
8167 256, 64, 0.1,
8168 320, 64, 0.1,
8169 384, 64, 0.1
8172 /* 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 */
8173 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;
8174 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;
8175 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;
8176 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;
8178 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;
8179 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;
8180 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;
8181 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;
8183 memset(&caps, 0, sizeof(caps));
8184 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8185 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8186 if(caps.MaxPointSize < 32.0) {
8187 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8188 return;
8191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8192 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8193 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8194 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8195 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8196 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8197 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8198 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8200 hr = IDirect3DDevice9_BeginScene(device);
8201 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8202 if(SUCCEEDED(hr)) {
8203 ptsize = 16.0;
8204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8205 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8206 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8207 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8209 ptsize = 32.0;
8210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8211 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8213 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8215 ptsize = 31.5;
8216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8217 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8219 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8221 if(caps.MaxPointSize >= 64.0) {
8222 ptsize = 64.0;
8223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8224 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8226 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8228 ptsize = 63.75;
8229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8230 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8235 ptsize = 1.0;
8236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8237 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8238 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8239 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8241 hr = IDirect3DDevice9_EndScene(device);
8242 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8244 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8245 color = getPixelColor(device, 64-9, 64-9);
8246 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8247 color = getPixelColor(device, 64-8, 64-8);
8248 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8249 color = getPixelColor(device, 64-7, 64-7);
8250 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8251 color = getPixelColor(device, 64+7, 64+7);
8252 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8253 color = getPixelColor(device, 64+8, 64+8);
8254 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8255 color = getPixelColor(device, 64+9, 64+9);
8256 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8258 color = getPixelColor(device, 128-17, 64-17);
8259 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8260 color = getPixelColor(device, 128-16, 64-16);
8261 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8262 color = getPixelColor(device, 128-15, 64-15);
8263 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8264 color = getPixelColor(device, 128+15, 64+15);
8265 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8266 color = getPixelColor(device, 128+16, 64+16);
8267 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8268 color = getPixelColor(device, 128+17, 64+17);
8269 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8271 color = getPixelColor(device, 192-17, 64-17);
8272 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8273 color = getPixelColor(device, 192-16, 64-16);
8274 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8275 color = getPixelColor(device, 192-15, 64-15);
8276 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8277 color = getPixelColor(device, 192+15, 64+15);
8278 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8279 color = getPixelColor(device, 192+16, 64+16);
8280 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8281 color = getPixelColor(device, 192+17, 64+17);
8282 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8284 if(caps.MaxPointSize >= 64.0) {
8285 color = getPixelColor(device, 256-33, 64-33);
8286 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8287 color = getPixelColor(device, 256-32, 64-32);
8288 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8289 color = getPixelColor(device, 256-31, 64-31);
8290 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8291 color = getPixelColor(device, 256+31, 64+31);
8292 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8293 color = getPixelColor(device, 256+32, 64+32);
8294 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8295 color = getPixelColor(device, 256+33, 64+33);
8296 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8298 color = getPixelColor(device, 384-33, 64-33);
8299 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8300 color = getPixelColor(device, 384-32, 64-32);
8301 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8302 color = getPixelColor(device, 384-31, 64-31);
8303 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8304 color = getPixelColor(device, 384+31, 64+31);
8305 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8306 color = getPixelColor(device, 384+32, 64+32);
8307 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8308 color = getPixelColor(device, 384+33, 64+33);
8309 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8312 color = getPixelColor(device, 320-1, 64-1);
8313 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8314 color = getPixelColor(device, 320-0, 64-0);
8315 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8316 color = getPixelColor(device, 320+1, 64+1);
8317 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8320 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8321 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8322 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8325 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8327 HRESULT hr;
8328 IDirect3DPixelShader9 *ps;
8329 IDirect3DTexture9 *tex1, *tex2;
8330 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8331 D3DCAPS9 caps;
8332 DWORD color;
8333 DWORD shader_code[] = {
8334 0xffff0300, /* ps_3_0 */
8335 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8336 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8337 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8338 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8339 0x0000ffff /* END */
8341 float quad[] = {
8342 -1.0, -1.0, 0.1,
8343 1.0, -1.0, 0.1,
8344 -1.0, 1.0, 0.1,
8345 1.0, 1.0, 0.1,
8347 float texquad[] = {
8348 -1.0, -1.0, 0.1, 0.0, 0.0,
8349 0.0, -1.0, 0.1, 1.0, 0.0,
8350 -1.0, 1.0, 0.1, 0.0, 1.0,
8351 0.0, 1.0, 0.1, 1.0, 1.0,
8353 0.0, -1.0, 0.1, 0.0, 0.0,
8354 1.0, -1.0, 0.1, 1.0, 0.0,
8355 0.0, 1.0, 0.1, 0.0, 1.0,
8356 1.0, 1.0, 0.1, 1.0, 1.0,
8359 memset(&caps, 0, sizeof(caps));
8360 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8361 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8362 if(caps.NumSimultaneousRTs < 2) {
8363 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8364 return;
8367 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8368 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8370 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8372 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8373 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8374 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8375 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8377 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8378 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8379 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8380 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8381 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8382 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8384 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8385 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8386 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8387 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8388 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8389 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8390 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8391 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8393 hr = IDirect3DDevice9_BeginScene(device);
8394 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8395 if(SUCCEEDED(hr)) {
8396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8399 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8400 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8401 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8403 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8404 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8406 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8408 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8411 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8413 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8414 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8416 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8418 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8421 hr = IDirect3DDevice9_EndScene(device);
8422 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8425 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8426 color = getPixelColor(device, 160, 240);
8427 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8428 color = getPixelColor(device, 480, 240);
8429 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8431 IDirect3DPixelShader9_Release(ps);
8432 IDirect3DTexture9_Release(tex1);
8433 IDirect3DTexture9_Release(tex2);
8434 IDirect3DSurface9_Release(surf1);
8435 IDirect3DSurface9_Release(surf2);
8436 IDirect3DSurface9_Release(backbuf);
8439 struct formats {
8440 const char *fmtName;
8441 D3DFORMAT textureFormat;
8442 DWORD resultColorBlending;
8443 DWORD resultColorNoBlending;
8446 const struct formats test_formats[] = {
8447 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8448 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8449 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8450 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8451 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8452 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8453 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8454 { NULL, 0 }
8457 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8459 HRESULT hr;
8460 IDirect3DTexture9 *offscreenTexture = NULL;
8461 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8462 IDirect3D9 *d3d = NULL;
8463 DWORD color;
8464 DWORD r0, g0, b0, r1, g1, b1;
8465 int fmt_index;
8467 static const float quad[][5] = {
8468 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8469 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8470 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8471 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8474 /* Quad with R=0x10, G=0x20 */
8475 static const struct vertex quad1[] = {
8476 {-1.0f, -1.0f, 0.1f, 0x80102000},
8477 {-1.0f, 1.0f, 0.1f, 0x80102000},
8478 { 1.0f, -1.0f, 0.1f, 0x80102000},
8479 { 1.0f, 1.0f, 0.1f, 0x80102000},
8482 /* Quad with R=0x20, G=0x10 */
8483 static const struct vertex quad2[] = {
8484 {-1.0f, -1.0f, 0.1f, 0x80201000},
8485 {-1.0f, 1.0f, 0.1f, 0x80201000},
8486 { 1.0f, -1.0f, 0.1f, 0x80201000},
8487 { 1.0f, 1.0f, 0.1f, 0x80201000},
8490 IDirect3DDevice9_GetDirect3D(device, &d3d);
8492 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8493 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8494 if(!backbuffer) {
8495 goto out;
8498 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8500 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8501 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8502 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8503 continue;
8506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8507 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8509 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8510 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8511 if(!offscreenTexture) {
8512 continue;
8515 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8516 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8517 if(!offscreen) {
8518 continue;
8521 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8522 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8524 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8525 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8526 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8527 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8528 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8529 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8530 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8531 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8533 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8535 /* Below we will draw two quads with different colors and try to blend them together.
8536 * The result color is compared with the expected outcome.
8538 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8539 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8540 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8541 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8542 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8545 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8547 /* Draw a quad using color 0x0010200 */
8548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8551 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8553 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8555 /* Draw a quad using color 0x0020100 */
8556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8561 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8563 /* We don't want to blend the result on the backbuffer */
8564 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8565 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8567 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8568 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8569 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8570 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8571 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8573 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8574 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8576 /* This time with the texture */
8577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8578 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8580 IDirect3DDevice9_EndScene(device);
8582 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8585 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8586 /* Compare the color of the center quad with our expectation */
8587 color = getPixelColor(device, 320, 240);
8588 r0 = (color & 0x00ff0000) >> 16;
8589 g0 = (color & 0x0000ff00) >> 8;
8590 b0 = (color & 0x000000ff) >> 0;
8592 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8593 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8594 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8596 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8597 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8598 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8599 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8600 } else {
8601 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8602 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8603 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8604 color = getPixelColor(device, 320, 240);
8605 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);
8608 IDirect3DDevice9_SetTexture(device, 0, NULL);
8609 if(offscreenTexture) {
8610 IDirect3DTexture9_Release(offscreenTexture);
8612 if(offscreen) {
8613 IDirect3DSurface9_Release(offscreen);
8617 out:
8618 /* restore things */
8619 if(backbuffer) {
8620 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8621 IDirect3DSurface9_Release(backbuffer);
8625 static void tssargtemp_test(IDirect3DDevice9 *device)
8627 HRESULT hr;
8628 DWORD color;
8629 static const struct vertex quad[] = {
8630 {-1.0, -1.0, 0.1, 0x00ff0000},
8631 { 1.0, -1.0, 0.1, 0x00ff0000},
8632 {-1.0, 1.0, 0.1, 0x00ff0000},
8633 { 1.0, 1.0, 0.1, 0x00ff0000}
8635 D3DCAPS9 caps;
8637 memset(&caps, 0, sizeof(caps));
8638 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8639 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8640 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8641 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8642 return;
8645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8646 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8648 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8649 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8650 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8651 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8653 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8654 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8655 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8656 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8657 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8658 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8660 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8661 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8662 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8663 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8664 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8665 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8667 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8668 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8671 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8672 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8675 hr = IDirect3DDevice9_BeginScene(device);
8676 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8677 if(SUCCEEDED(hr)) {
8679 hr = IDirect3DDevice9_EndScene(device);
8680 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8682 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8684 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8685 color = getPixelColor(device, 320, 240);
8686 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8688 /* Set stage 1 back to default */
8689 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8690 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8691 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8692 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8693 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8694 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8695 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8696 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8697 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8698 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8701 struct testdata
8703 DWORD idxVertex; /* number of instances in the first stream */
8704 DWORD idxColor; /* number of instances in the second stream */
8705 DWORD idxInstance; /* should be 1 ?? */
8706 DWORD color1; /* color 1 instance */
8707 DWORD color2; /* color 2 instance */
8708 DWORD color3; /* color 3 instance */
8709 DWORD color4; /* color 4 instance */
8710 WORD strVertex; /* specify which stream to use 0-2*/
8711 WORD strColor;
8712 WORD strInstance;
8715 static const struct testdata testcases[]=
8717 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8718 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8719 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8720 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8721 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8722 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8723 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8724 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8725 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8726 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8727 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8728 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8729 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8730 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8731 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8733 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8734 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8738 /* Drawing Indexed Geometry with instances*/
8739 static void stream_test(IDirect3DDevice9 *device)
8741 IDirect3DVertexBuffer9 *vb = NULL;
8742 IDirect3DVertexBuffer9 *vb2 = NULL;
8743 IDirect3DVertexBuffer9 *vb3 = NULL;
8744 IDirect3DIndexBuffer9 *ib = NULL;
8745 IDirect3DVertexDeclaration9 *pDecl = NULL;
8746 IDirect3DVertexShader9 *shader = NULL;
8747 HRESULT hr;
8748 BYTE *data;
8749 DWORD color;
8750 DWORD ind;
8751 int i;
8753 const DWORD shader_code[] =
8755 0xfffe0101, /* vs_1_1 */
8756 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8757 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8758 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8759 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8760 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8761 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8762 0x0000ffff
8765 const float quad[][3] =
8767 {-0.5f, -0.5f, 1.1f}, /*0 */
8768 {-0.5f, 0.5f, 1.1f}, /*1 */
8769 { 0.5f, -0.5f, 1.1f}, /*2 */
8770 { 0.5f, 0.5f, 1.1f}, /*3 */
8773 const float vertcolor[][4] =
8775 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8776 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8777 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8778 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8781 /* 4 position for 4 instances */
8782 const float instancepos[][3] =
8784 {-0.6f,-0.6f, 0.0f},
8785 { 0.6f,-0.6f, 0.0f},
8786 { 0.6f, 0.6f, 0.0f},
8787 {-0.6f, 0.6f, 0.0f},
8790 short indices[] = {0, 1, 2, 1, 2, 3};
8792 D3DVERTEXELEMENT9 decl[] =
8794 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8795 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8796 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8797 D3DDECL_END()
8800 /* set the default value because it isn't done in wine? */
8801 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8802 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8804 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8805 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8806 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8808 /* check wrong cases */
8809 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8810 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8811 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8812 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8813 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8814 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8815 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8816 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8817 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8818 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8819 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8820 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8821 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8822 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8823 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8824 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8825 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8826 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8827 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8828 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8830 /* set the default value back */
8831 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8832 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8834 /* create all VertexBuffers*/
8835 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8836 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8837 if(!vb) {
8838 skip("Failed to create a vertex buffer\n");
8839 return;
8841 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8842 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8843 if(!vb2) {
8844 skip("Failed to create a vertex buffer\n");
8845 goto out;
8847 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8848 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8849 if(!vb3) {
8850 skip("Failed to create a vertex buffer\n");
8851 goto out;
8854 /* create IndexBuffer*/
8855 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8857 if(!ib) {
8858 skip("Failed to create a index buffer\n");
8859 goto out;
8862 /* copy all Buffers (Vertex + Index)*/
8863 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8864 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8865 memcpy(data, quad, sizeof(quad));
8866 hr = IDirect3DVertexBuffer9_Unlock(vb);
8867 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8868 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8869 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8870 memcpy(data, vertcolor, sizeof(vertcolor));
8871 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8872 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8873 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8874 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8875 memcpy(data, instancepos, sizeof(instancepos));
8876 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8877 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8878 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8879 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8880 memcpy(data, indices, sizeof(indices));
8881 hr = IDirect3DIndexBuffer9_Unlock(ib);
8882 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8884 /* create VertexShader */
8885 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8886 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8887 if(!shader) {
8888 skip("Failed to create a vetex shader\n");
8889 goto out;
8892 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8893 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8895 hr = IDirect3DDevice9_SetIndices(device, ib);
8896 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8898 /* run all tests */
8899 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8901 struct testdata act = testcases[i];
8902 decl[0].Stream = act.strVertex;
8903 decl[1].Stream = act.strColor;
8904 decl[2].Stream = act.strInstance;
8905 /* create VertexDeclarations */
8906 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8907 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8909 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8910 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8912 hr = IDirect3DDevice9_BeginScene(device);
8913 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8914 if(SUCCEEDED(hr))
8916 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8917 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8919 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8920 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8921 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8922 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8924 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8925 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8926 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8927 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8929 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8930 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8931 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8932 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8934 /* don't know if this is right (1*3 and 4*1)*/
8935 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8936 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8937 hr = IDirect3DDevice9_EndScene(device);
8938 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8940 /* set all StreamSource && StreamSourceFreq back to default */
8941 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8942 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8943 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8944 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8945 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8946 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8947 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8948 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8949 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8950 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8951 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8952 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8955 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8956 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8958 hr = IDirect3DVertexDeclaration9_Release(pDecl);
8959 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8961 color = getPixelColor(device, 160, 360);
8962 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8963 color = getPixelColor(device, 480, 360);
8964 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8965 color = getPixelColor(device, 480, 120);
8966 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8967 color = getPixelColor(device, 160, 120);
8968 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8971 hr = IDirect3DDevice9_SetIndices(device, NULL);
8972 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8974 out:
8975 if(vb) IDirect3DVertexBuffer9_Release(vb);
8976 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8977 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8978 if(ib)IDirect3DIndexBuffer9_Release(ib);
8979 if(shader)IDirect3DVertexShader9_Release(shader);
8982 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8983 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8984 IDirect3DTexture9 *dsttex = NULL;
8985 HRESULT hr;
8986 DWORD color;
8987 D3DRECT r1 = {0, 0, 50, 50 };
8988 D3DRECT r2 = {50, 0, 100, 50 };
8989 D3DRECT r3 = {50, 50, 100, 100};
8990 D3DRECT r4 = {0, 50, 50, 100};
8991 const float quad[] = {
8992 -1.0, -1.0, 0.1, 0.0, 0.0,
8993 1.0, -1.0, 0.1, 1.0, 0.0,
8994 -1.0, 1.0, 0.1, 0.0, 1.0,
8995 1.0, 1.0, 0.1, 1.0, 1.0,
8998 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8999 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
9001 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9002 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
9003 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9004 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
9006 if(!src || !dsttex) {
9007 skip("One or more test resources could not be created\n");
9008 goto cleanup;
9011 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9012 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
9014 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9015 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9017 /* Clear the StretchRect destination for debugging */
9018 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9019 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9020 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9021 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9023 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9024 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9026 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9027 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9028 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9029 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9030 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9031 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9032 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9035 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9036 * the target -> texture GL blit path
9038 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9039 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9040 IDirect3DSurface9_Release(dst);
9042 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9043 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9045 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9047 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9049 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9050 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9051 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9052 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9054 hr = IDirect3DDevice9_BeginScene(device);
9055 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9056 if(SUCCEEDED(hr)) {
9057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9058 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9059 hr = IDirect3DDevice9_EndScene(device);
9060 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9063 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9064 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9065 color = getPixelColor(device, 160, 360);
9066 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9067 color = getPixelColor(device, 480, 360);
9068 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9069 color = getPixelColor(device, 480, 120);
9070 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9071 color = getPixelColor(device, 160, 120);
9072 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9074 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9076 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9077 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9079 cleanup:
9080 if(src) IDirect3DSurface9_Release(src);
9081 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9082 if(dsttex) IDirect3DTexture9_Release(dsttex);
9085 static void texop_test(IDirect3DDevice9 *device)
9087 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9088 IDirect3DTexture9 *texture = NULL;
9089 D3DLOCKED_RECT locked_rect;
9090 D3DCOLOR color;
9091 D3DCAPS9 caps;
9092 HRESULT hr;
9093 int i;
9095 static const struct {
9096 float x, y, z;
9097 float s, t;
9098 D3DCOLOR diffuse;
9099 } quad[] = {
9100 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9101 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9102 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9103 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9106 static const D3DVERTEXELEMENT9 decl_elements[] = {
9107 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9108 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9109 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9110 D3DDECL_END()
9113 static const struct {
9114 D3DTEXTUREOP op;
9115 const char *name;
9116 DWORD caps_flag;
9117 D3DCOLOR result;
9118 } test_data[] = {
9119 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9120 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9121 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9122 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9123 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9124 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9125 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9126 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9127 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9128 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9129 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9130 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9131 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9132 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9133 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9134 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9135 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9136 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9137 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9138 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9139 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9140 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9141 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9144 memset(&caps, 0, sizeof(caps));
9145 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9146 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9148 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9149 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9150 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9151 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9153 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9154 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9155 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9156 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9157 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9158 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9159 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9160 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9161 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9163 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9164 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9165 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9166 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9167 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9168 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9170 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9171 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9174 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9176 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9178 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9180 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9181 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9183 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9185 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9187 skip("tex operation %s not supported\n", test_data[i].name);
9188 continue;
9191 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9192 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x (%s)\n",
9193 test_data[i].name, hr, DXGetErrorString9(hr));
9195 hr = IDirect3DDevice9_BeginScene(device);
9196 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9199 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9201 hr = IDirect3DDevice9_EndScene(device);
9202 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9204 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9205 ok(SUCCEEDED(hr), "Present failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9207 color = getPixelColor(device, 320, 240);
9208 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9209 test_data[i].name, color, test_data[i].result);
9212 if (texture) IDirect3DTexture9_Release(texture);
9213 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9216 START_TEST(visual)
9218 IDirect3DDevice9 *device_ptr;
9219 D3DCAPS9 caps;
9220 HRESULT hr;
9221 DWORD color;
9223 d3d9_handle = LoadLibraryA("d3d9.dll");
9224 if (!d3d9_handle)
9226 skip("Could not load d3d9.dll\n");
9227 return;
9230 device_ptr = init_d3d9();
9231 if (!device_ptr)
9233 skip("Creating the device failed\n");
9234 return;
9237 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9239 /* Check for the reliability of the returned data */
9240 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9241 if(FAILED(hr))
9243 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9244 goto cleanup;
9246 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9248 color = getPixelColor(device_ptr, 1, 1);
9249 if(color !=0x00ff0000)
9251 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9252 goto cleanup;
9255 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9256 if(FAILED(hr))
9258 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9259 goto cleanup;
9261 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9263 color = getPixelColor(device_ptr, 639, 479);
9264 if(color != 0x0000ddee)
9266 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9267 goto cleanup;
9270 /* Now execute the real tests */
9271 stretchrect_test(device_ptr);
9272 lighting_test(device_ptr);
9273 clear_test(device_ptr);
9274 fog_test(device_ptr);
9275 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9277 test_cube_wrap(device_ptr);
9278 } else {
9279 skip("No cube texture support\n");
9281 z_range_test(device_ptr);
9282 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9284 maxmip_test(device_ptr);
9286 else
9288 skip("No mipmap support\n");
9290 offscreen_test(device_ptr);
9291 alpha_test(device_ptr);
9292 shademode_test(device_ptr);
9293 srgbtexture_test(device_ptr);
9294 release_buffer_test(device_ptr);
9295 float_texture_test(device_ptr);
9296 g16r16_texture_test(device_ptr);
9297 pixelshader_blending_test(device_ptr);
9298 texture_transform_flags_test(device_ptr);
9299 autogen_mipmap_test(device_ptr);
9300 fixed_function_decl_test(device_ptr);
9301 conditional_np2_repeat_test(device_ptr);
9302 fixed_function_bumpmap_test(device_ptr);
9303 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9304 stencil_cull_test(device_ptr);
9305 } else {
9306 skip("No two sided stencil support\n");
9308 pointsize_test(device_ptr);
9309 tssargtemp_test(device_ptr);
9310 np2_stretch_rect_test(device_ptr);
9312 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9314 test_constant_clamp_vs(device_ptr);
9315 test_compare_instructions(device_ptr);
9317 else skip("No vs_1_1 support\n");
9319 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9321 test_mova(device_ptr);
9322 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9323 test_vshader_input(device_ptr);
9324 test_vshader_float16(device_ptr);
9325 stream_test(device_ptr);
9326 } else {
9327 skip("No vs_3_0 support\n");
9330 else skip("No vs_2_0 support\n");
9332 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9334 fog_with_shader_test(device_ptr);
9335 fog_srgbwrite_test(device_ptr);
9337 else skip("No vs_1_1 and ps_1_1 support\n");
9339 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9341 texbem_test(device_ptr);
9342 texdepth_test(device_ptr);
9343 texkill_test(device_ptr);
9344 x8l8v8u8_test(device_ptr);
9345 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9346 constant_clamp_ps_test(device_ptr);
9347 cnd_test(device_ptr);
9348 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9349 dp2add_ps_test(device_ptr);
9350 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9351 nested_loop_test(device_ptr);
9352 fixed_function_varying_test(device_ptr);
9353 vFace_register_test(device_ptr);
9354 vpos_register_test(device_ptr);
9355 multiple_rendertargets_test(device_ptr);
9356 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9357 vshader_version_varying_test(device_ptr);
9358 pshader_version_varying_test(device_ptr);
9359 } else {
9360 skip("No vs_3_0 support\n");
9362 } else {
9363 skip("No ps_3_0 support\n");
9365 } else {
9366 skip("No ps_2_0 support\n");
9370 else skip("No ps_1_1 support\n");
9371 texop_test(device_ptr);
9373 cleanup:
9374 if(device_ptr) {
9375 ULONG ref;
9377 D3DPRESENT_PARAMETERS present_parameters;
9378 IDirect3DSwapChain9 *swapchain;
9379 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9380 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9381 IDirect3DSwapChain9_Release(swapchain);
9382 ref = IDirect3DDevice9_Release(device_ptr);
9383 DestroyWindow(present_parameters.hDeviceWindow);
9384 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);