d3d9: Use color_match() in fog_with_shader_test().
[wine/gsoc_dplay.git] / dlls / d3d9 / tests / visual.c
blob1a9b5fc995a3fc5ae95ff1557d0a05edcf5a2864
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 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4895 * that we swapped the values in c1 and c2 to make the other tests return some color
4897 color = getPixelColor(device, 158, 118);
4898 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4899 color = getPixelColor(device, 162, 118);
4900 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4901 color = getPixelColor(device, 158, 122);
4902 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4903 color = getPixelColor(device, 162, 122);
4904 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4906 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4907 color = getPixelColor(device, 158, 358);
4908 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4909 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4910 color = getPixelColor(device, 162, 358);
4911 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4912 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4913 color = getPixelColor(device, 158, 362);
4914 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4915 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4916 color = getPixelColor(device, 162, 362);
4917 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4918 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4920 /* 1.2 shader */
4921 color = getPixelColor(device, 478, 358);
4922 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4923 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4924 color = getPixelColor(device, 482, 358);
4925 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4926 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4927 color = getPixelColor(device, 478, 362);
4928 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4929 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4930 color = getPixelColor(device, 482, 362);
4931 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4932 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4934 /* 1.3 shader */
4935 color = getPixelColor(device, 478, 118);
4936 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4937 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4938 color = getPixelColor(device, 482, 118);
4939 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4940 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4941 color = getPixelColor(device, 478, 122);
4942 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4943 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4944 color = getPixelColor(device, 482, 122);
4945 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4946 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4948 IDirect3DPixelShader9_Release(shader_14_coissue);
4949 IDirect3DPixelShader9_Release(shader_13_coissue);
4950 IDirect3DPixelShader9_Release(shader_12_coissue);
4951 IDirect3DPixelShader9_Release(shader_11_coissue);
4952 IDirect3DPixelShader9_Release(shader_14);
4953 IDirect3DPixelShader9_Release(shader_13);
4954 IDirect3DPixelShader9_Release(shader_12);
4955 IDirect3DPixelShader9_Release(shader_11);
4958 static void nested_loop_test(IDirect3DDevice9 *device) {
4959 const DWORD shader_code[] = {
4960 0xffff0300, /* ps_3_0 */
4961 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4962 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4963 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
4964 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4965 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4966 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4967 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
4968 0x0000001d, /* endloop */
4969 0x0000001d, /* endloop */
4970 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4971 0x0000ffff /* end */
4973 IDirect3DPixelShader9 *shader;
4974 HRESULT hr;
4975 DWORD color;
4976 const float quad[] = {
4977 -1.0, -1.0, 0.1,
4978 1.0, -1.0, 0.1,
4979 -1.0, 1.0, 0.1,
4980 1.0, 1.0, 0.1
4983 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4984 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4985 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4987 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4990 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4992 hr = IDirect3DDevice9_BeginScene(device);
4993 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4994 if(SUCCEEDED(hr))
4996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4997 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4998 hr = IDirect3DDevice9_EndScene(device);
4999 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5001 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5002 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5004 color = getPixelColor(device, 360, 240);
5005 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5006 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5008 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5009 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
5010 IDirect3DPixelShader9_Release(shader);
5013 struct varying_test_struct
5015 const DWORD *shader_code;
5016 IDirect3DPixelShader9 *shader;
5017 DWORD color, color_rhw;
5018 const char *name;
5019 BOOL todo, todo_rhw;
5022 struct hugeVertex
5024 float pos_x, pos_y, pos_z, rhw;
5025 float weight_1, weight_2, weight_3, weight_4;
5026 float index_1, index_2, index_3, index_4;
5027 float normal_1, normal_2, normal_3, normal_4;
5028 float fog_1, fog_2, fog_3, fog_4;
5029 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5030 float tangent_1, tangent_2, tangent_3, tangent_4;
5031 float binormal_1, binormal_2, binormal_3, binormal_4;
5032 float depth_1, depth_2, depth_3, depth_4;
5033 DWORD diffuse, specular;
5036 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5037 /* dcl_position: fails to compile */
5038 const DWORD blendweight_code[] = {
5039 0xffff0300, /* ps_3_0 */
5040 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5041 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5042 0x0000ffff /* end */
5044 const DWORD blendindices_code[] = {
5045 0xffff0300, /* ps_3_0 */
5046 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5047 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5048 0x0000ffff /* end */
5050 const DWORD normal_code[] = {
5051 0xffff0300, /* ps_3_0 */
5052 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5053 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5054 0x0000ffff /* end */
5056 /* psize: fails? */
5057 const DWORD texcoord0_code[] = {
5058 0xffff0300, /* ps_3_0 */
5059 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5060 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5061 0x0000ffff /* end */
5063 const DWORD tangent_code[] = {
5064 0xffff0300, /* ps_3_0 */
5065 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5066 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5067 0x0000ffff /* end */
5069 const DWORD binormal_code[] = {
5070 0xffff0300, /* ps_3_0 */
5071 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5072 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5073 0x0000ffff /* end */
5075 /* tessfactor: fails */
5076 /* positiont: fails */
5077 const DWORD color_code[] = {
5078 0xffff0300, /* ps_3_0 */
5079 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5080 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5081 0x0000ffff /* end */
5083 const DWORD fog_code[] = {
5084 0xffff0300, /* ps_3_0 */
5085 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5086 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5087 0x0000ffff /* end */
5089 const DWORD depth_code[] = {
5090 0xffff0300, /* ps_3_0 */
5091 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5092 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5093 0x0000ffff /* end */
5095 const DWORD specular_code[] = {
5096 0xffff0300, /* ps_3_0 */
5097 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5098 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5099 0x0000ffff /* end */
5101 /* sample: fails */
5103 struct varying_test_struct tests[] = {
5104 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5105 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5106 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5107 /* Why does dx not forward the texcoord? */
5108 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5109 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5110 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5111 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5112 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5113 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5114 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5116 /* Declare a monster vertex type :-) */
5117 static const D3DVERTEXELEMENT9 decl_elements[] = {
5118 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5119 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5120 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5121 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5122 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5123 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5124 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5125 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5126 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5127 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5128 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5129 D3DDECL_END()
5131 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5132 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5133 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5134 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5135 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5136 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5137 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5138 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5139 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5140 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5141 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5142 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5143 D3DDECL_END()
5145 struct hugeVertex data[4] = {
5147 -1.0, -1.0, 0.1, 1.0,
5148 0.1, 0.1, 0.1, 0.1,
5149 0.2, 0.2, 0.2, 0.2,
5150 0.3, 0.3, 0.3, 0.3,
5151 0.4, 0.4, 0.4, 0.4,
5152 0.50, 0.55, 0.55, 0.55,
5153 0.6, 0.6, 0.6, 0.7,
5154 0.7, 0.7, 0.7, 0.6,
5155 0.8, 0.8, 0.8, 0.8,
5156 0xe6e6e6e6, /* 0.9 * 256 */
5157 0x224488ff /* Nothing special */
5160 1.0, -1.0, 0.1, 1.0,
5161 0.1, 0.1, 0.1, 0.1,
5162 0.2, 0.2, 0.2, 0.2,
5163 0.3, 0.3, 0.3, 0.3,
5164 0.4, 0.4, 0.4, 0.4,
5165 0.50, 0.55, 0.55, 0.55,
5166 0.6, 0.6, 0.6, 0.7,
5167 0.7, 0.7, 0.7, 0.6,
5168 0.8, 0.8, 0.8, 0.8,
5169 0xe6e6e6e6, /* 0.9 * 256 */
5170 0x224488ff /* Nothing special */
5173 -1.0, 1.0, 0.1, 1.0,
5174 0.1, 0.1, 0.1, 0.1,
5175 0.2, 0.2, 0.2, 0.2,
5176 0.3, 0.3, 0.3, 0.3,
5177 0.4, 0.4, 0.4, 0.4,
5178 0.50, 0.55, 0.55, 0.55,
5179 0.6, 0.6, 0.6, 0.7,
5180 0.7, 0.7, 0.7, 0.6,
5181 0.8, 0.8, 0.8, 0.8,
5182 0xe6e6e6e6, /* 0.9 * 256 */
5183 0x224488ff /* Nothing special */
5186 1.0, 1.0, 0.1, 1.0,
5187 0.1, 0.1, 0.1, 0.1,
5188 0.2, 0.2, 0.2, 0.2,
5189 0.3, 0.3, 0.3, 0.3,
5190 0.4, 0.4, 0.4, 0.4,
5191 0.50, 0.55, 0.55, 0.55,
5192 0.6, 0.6, 0.6, 0.7,
5193 0.7, 0.7, 0.7, 0.6,
5194 0.8, 0.8, 0.8, 0.8,
5195 0xe6e6e6e6, /* 0.9 * 256 */
5196 0x224488ff /* Nothing special */
5199 struct hugeVertex data2[4];
5200 IDirect3DVertexDeclaration9 *decl;
5201 IDirect3DVertexDeclaration9 *decl2;
5202 HRESULT hr;
5203 unsigned int i;
5204 DWORD color, r, g, b, r_e, g_e, b_e;
5205 BOOL drawok;
5207 memcpy(data2, data, sizeof(data2));
5208 data2[0].pos_x = 0; data2[0].pos_y = 0;
5209 data2[1].pos_x = 640; data2[1].pos_y = 0;
5210 data2[2].pos_x = 0; data2[2].pos_y = 480;
5211 data2[3].pos_x = 640; data2[3].pos_y = 480;
5213 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5214 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5215 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5216 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5217 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5218 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5220 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5222 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5223 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5224 tests[i].name, DXGetErrorString9(hr));
5227 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5230 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5232 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5233 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5235 hr = IDirect3DDevice9_BeginScene(device);
5236 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5237 drawok = FALSE;
5238 if(SUCCEEDED(hr))
5240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5241 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5242 drawok = SUCCEEDED(hr);
5243 hr = IDirect3DDevice9_EndScene(device);
5244 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5246 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5249 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5250 * the failure and do not check the color if it failed
5252 if(!drawok) {
5253 continue;
5256 color = getPixelColor(device, 360, 240);
5257 r = color & 0x00ff0000 >> 16;
5258 g = color & 0x0000ff00 >> 8;
5259 b = color & 0x000000ff;
5260 r_e = tests[i].color & 0x00ff0000 >> 16;
5261 g_e = tests[i].color & 0x0000ff00 >> 8;
5262 b_e = tests[i].color & 0x000000ff;
5264 if(tests[i].todo) {
5265 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5266 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5267 tests[i].name, color, tests[i].color);
5268 } else {
5269 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5270 "Test %s returned color 0x%08x, expected 0x%08x\n",
5271 tests[i].name, color, tests[i].color);
5275 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5276 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5277 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5280 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5282 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5283 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5285 hr = IDirect3DDevice9_BeginScene(device);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5287 if(SUCCEEDED(hr))
5289 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5290 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5291 hr = IDirect3DDevice9_EndScene(device);
5292 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5294 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5297 color = getPixelColor(device, 360, 240);
5298 r = color & 0x00ff0000 >> 16;
5299 g = color & 0x0000ff00 >> 8;
5300 b = color & 0x000000ff;
5301 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5302 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5303 b_e = tests[i].color_rhw & 0x000000ff;
5305 if(tests[i].todo_rhw) {
5306 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5307 * pipeline
5309 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5310 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5311 tests[i].name, color, tests[i].color_rhw);
5312 } else {
5313 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5314 "Test %s returned color 0x%08x, expected 0x%08x\n",
5315 tests[i].name, color, tests[i].color_rhw);
5319 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5321 IDirect3DPixelShader9_Release(tests[i].shader);
5324 IDirect3DVertexDeclaration9_Release(decl2);
5325 IDirect3DVertexDeclaration9_Release(decl);
5328 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5329 static const DWORD ps_code[] = {
5330 0xffff0300, /* ps_3_0 */
5331 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5332 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5333 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5334 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5335 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5336 0x0200001f, 0x80000003, 0x900f0006,
5337 0x0200001f, 0x80000006, 0x900f0007,
5338 0x0200001f, 0x80000001, 0x900f0008,
5339 0x0200001f, 0x8000000c, 0x900f0009,
5341 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5342 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5343 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5344 0x0000001d, /* endloop */
5345 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5346 0x0000ffff /* end */
5348 static const DWORD vs_1_code[] = {
5349 0xfffe0101, /* vs_1_1 */
5350 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5351 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5352 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5353 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5354 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5355 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5356 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5357 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5358 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5359 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5360 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5361 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5362 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5363 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5364 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5365 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5366 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5367 0x0000ffff
5369 DWORD vs_2_code[] = {
5370 0xfffe0200, /* vs_2_0 */
5371 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5372 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
5373 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
5374 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0 */
5375 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5376 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5377 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5378 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5379 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5380 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5381 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5382 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5383 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5384 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5385 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5386 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5387 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5388 0x0000ffff /* end */
5390 /* TODO: Define normal, tangent, blendweight and depth here */
5391 static const DWORD vs_3_code[] = {
5392 0xfffe0300, /* vs_3_0 */
5393 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5394 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5395 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5396 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5397 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5398 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5399 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5400 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5401 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5402 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5403 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5404 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5405 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5406 0x0000ffff /* end */
5408 float quad1[] = {
5409 -1.0, -1.0, 0.1,
5410 0.0, -1.0, 0.1,
5411 -1.0, 0.0, 0.1,
5412 0.0, 0.0, 0.1
5414 float quad2[] = {
5415 0.0, -1.0, 0.1,
5416 1.0, -1.0, 0.1,
5417 0.0, 0.0, 0.1,
5418 1.0, 0.0, 0.1
5420 float quad3[] = {
5421 -1.0, 0.0, 0.1,
5422 0.0, 0.0, 0.1,
5423 -1.0, 1.0, 0.1,
5424 0.0, 1.0, 0.1
5427 HRESULT hr;
5428 DWORD color;
5429 IDirect3DPixelShader9 *pixelshader = NULL;
5430 IDirect3DVertexShader9 *vs_1_shader = NULL;
5431 IDirect3DVertexShader9 *vs_2_shader = NULL;
5432 IDirect3DVertexShader9 *vs_3_shader = NULL;
5434 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5436 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5437 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5438 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5439 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5440 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5441 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5442 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5443 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5444 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5445 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5446 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5448 hr = IDirect3DDevice9_BeginScene(device);
5449 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5450 if(SUCCEEDED(hr))
5452 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5453 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5455 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5457 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5458 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5460 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5462 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5465 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5467 hr = IDirect3DDevice9_EndScene(device);
5468 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5470 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5471 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5473 color = getPixelColor(device, 160, 120);
5474 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5475 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5476 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5477 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5478 color = getPixelColor(device, 160, 360);
5479 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5480 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5481 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5482 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5483 color = getPixelColor(device, 480, 360);
5484 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5485 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5486 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5487 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5489 /* cleanup */
5490 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5491 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5492 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5493 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5494 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5495 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5496 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5497 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5500 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5501 static const DWORD vs_code[] = {
5502 0xfffe0300, /* vs_3_0 */
5503 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5504 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5505 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5506 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5507 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5508 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5509 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5510 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5511 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5512 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5513 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5514 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5515 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5517 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5518 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5519 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5520 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5521 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5522 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5523 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5524 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5525 0x0000ffff /* end */
5527 static const DWORD ps_1_code[] = {
5528 0xffff0104, /* ps_1_4 */
5529 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5530 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5531 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5532 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5533 0x0000ffff /* end */
5535 static const DWORD ps_2_code[] = {
5536 0xffff0200, /* ps_2_0 */
5537 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5538 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5539 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5541 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5542 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5543 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5544 0x0000ffff /* end */
5546 static const DWORD ps_3_code[] = {
5547 0xffff0300, /* ps_3_0 */
5548 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5549 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5550 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5552 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5553 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5554 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5555 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5556 0x0000ffff /* end */
5559 float quad1[] = {
5560 -1.0, -1.0, 0.1,
5561 0.0, -1.0, 0.1,
5562 -1.0, 0.0, 0.1,
5563 0.0, 0.0, 0.1
5565 float quad2[] = {
5566 0.0, -1.0, 0.1,
5567 1.0, -1.0, 0.1,
5568 0.0, 0.0, 0.1,
5569 1.0, 0.0, 0.1
5571 float quad3[] = {
5572 -1.0, 0.0, 0.1,
5573 0.0, 0.0, 0.1,
5574 -1.0, 1.0, 0.1,
5575 0.0, 1.0, 0.1
5577 float quad4[] = {
5578 0.0, 0.0, 0.1,
5579 1.0, 0.0, 0.1,
5580 0.0, 1.0, 0.1,
5581 1.0, 1.0, 0.1
5584 HRESULT hr;
5585 DWORD color;
5586 IDirect3DVertexShader9 *vertexshader = NULL;
5587 IDirect3DPixelShader9 *ps_1_shader = NULL;
5588 IDirect3DPixelShader9 *ps_2_shader = NULL;
5589 IDirect3DPixelShader9 *ps_3_shader = NULL;
5590 IDirect3DTexture9 *texture = NULL;
5591 D3DLOCKED_RECT lr;
5592 unsigned int x, y;
5594 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5596 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5597 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5598 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5599 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5600 for(y = 0; y < 512; y++) {
5601 for(x = 0; x < 512; x++) {
5602 double r_f = (double) x / (double) 512;
5603 double g_f = (double) y / (double) 512;
5604 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5605 unsigned short r = (unsigned short) (r_f * 65535.0);
5606 unsigned short g = (unsigned short) (g_f * 65535.0);
5607 dst[0] = r;
5608 dst[1] = g;
5609 dst[2] = 0;
5610 dst[3] = 65535;
5613 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5614 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5616 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5617 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5618 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5620 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5621 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5622 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5623 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5624 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5625 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5626 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5628 hr = IDirect3DDevice9_BeginScene(device);
5629 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5630 if(SUCCEEDED(hr))
5632 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5635 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5637 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5640 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5642 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5643 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5645 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5647 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5649 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5650 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5651 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5652 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5653 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5654 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5656 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5658 hr = IDirect3DDevice9_EndScene(device);
5659 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5662 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5664 color = getPixelColor(device, 160, 120);
5665 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5666 (color & 0x0000ff00) == 0x0000ff00 &&
5667 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5668 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5669 color = getPixelColor(device, 160, 360);
5670 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5671 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5672 (color & 0x000000ff) == 0x00000000,
5673 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5674 color = getPixelColor(device, 480, 360);
5675 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5676 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5677 (color & 0x000000ff) == 0x00000000,
5678 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5679 color = getPixelColor(device, 480, 160);
5680 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5681 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5682 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5683 (color & 0x000000ff) == 0x00000000),
5684 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5686 /* cleanup */
5687 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5688 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5689 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5690 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5691 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5692 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5693 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5694 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5695 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5696 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5697 if(texture) IDirect3DTexture9_Release(texture);
5700 void test_compare_instructions(IDirect3DDevice9 *device)
5702 DWORD shader_sge_vec_code[] = {
5703 0xfffe0101, /* vs_1_1 */
5704 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5705 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5706 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5707 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5708 0x0000ffff /* end */
5710 DWORD shader_slt_vec_code[] = {
5711 0xfffe0101, /* vs_1_1 */
5712 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5713 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5714 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5715 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5716 0x0000ffff /* end */
5718 DWORD shader_sge_scalar_code[] = {
5719 0xfffe0101, /* vs_1_1 */
5720 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5721 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5722 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5723 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5724 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5725 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5726 0x0000ffff /* end */
5728 DWORD shader_slt_scalar_code[] = {
5729 0xfffe0101, /* vs_1_1 */
5730 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5731 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5732 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5733 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5734 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5735 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5736 0x0000ffff /* end */
5738 IDirect3DVertexShader9 *shader_sge_vec;
5739 IDirect3DVertexShader9 *shader_slt_vec;
5740 IDirect3DVertexShader9 *shader_sge_scalar;
5741 IDirect3DVertexShader9 *shader_slt_scalar;
5742 HRESULT hr, color;
5743 float quad1[] = {
5744 -1.0, -1.0, 0.1,
5745 0.0, -1.0, 0.1,
5746 -1.0, 0.0, 0.1,
5747 0.0, 0.0, 0.1
5749 float quad2[] = {
5750 0.0, -1.0, 0.1,
5751 1.0, -1.0, 0.1,
5752 0.0, 0.0, 0.1,
5753 1.0, 0.0, 0.1
5755 float quad3[] = {
5756 -1.0, 0.0, 0.1,
5757 0.0, 0.0, 0.1,
5758 -1.0, 1.0, 0.1,
5759 0.0, 1.0, 0.1
5761 float quad4[] = {
5762 0.0, 0.0, 0.1,
5763 1.0, 0.0, 0.1,
5764 0.0, 1.0, 0.1,
5765 1.0, 1.0, 0.1
5767 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5768 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5772 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5774 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5776 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5778 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5780 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5781 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5782 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5783 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5785 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5787 hr = IDirect3DDevice9_BeginScene(device);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5789 if(SUCCEEDED(hr))
5791 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5792 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5794 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5796 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5797 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5799 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5801 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5802 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5804 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5806 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5807 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5809 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5810 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5812 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5814 hr = IDirect3DDevice9_EndScene(device);
5815 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5819 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5821 color = getPixelColor(device, 160, 360);
5822 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5823 color = getPixelColor(device, 480, 360);
5824 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5825 color = getPixelColor(device, 160, 120);
5826 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5827 color = getPixelColor(device, 480, 160);
5828 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5830 IDirect3DVertexShader9_Release(shader_sge_vec);
5831 IDirect3DVertexShader9_Release(shader_slt_vec);
5832 IDirect3DVertexShader9_Release(shader_sge_scalar);
5833 IDirect3DVertexShader9_Release(shader_slt_scalar);
5836 void test_vshader_input(IDirect3DDevice9 *device)
5838 DWORD swapped_shader_code_3[] = {
5839 0xfffe0300, /* vs_3_0 */
5840 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5841 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5842 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5843 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5844 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5845 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5846 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5847 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5848 0x0000ffff /* end */
5850 DWORD swapped_shader_code_1[] = {
5851 0xfffe0101, /* vs_1_1 */
5852 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5853 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5854 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5855 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5856 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5857 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5858 0x0000ffff /* end */
5860 DWORD swapped_shader_code_2[] = {
5861 0xfffe0200, /* vs_2_0 */
5862 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5863 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5864 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5865 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5866 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5867 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5868 0x0000ffff /* end */
5870 DWORD texcoord_color_shader_code_3[] = {
5871 0xfffe0300, /* vs_3_0 */
5872 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5873 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5874 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5875 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5876 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5877 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5878 0x0000ffff /* end */
5880 DWORD texcoord_color_shader_code_2[] = {
5881 0xfffe0200, /* vs_2_0 */
5882 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5883 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5884 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5885 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5886 0x0000ffff /* end */
5888 DWORD texcoord_color_shader_code_1[] = {
5889 0xfffe0101, /* vs_1_1 */
5890 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5891 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5892 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5893 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5894 0x0000ffff /* end */
5896 DWORD color_color_shader_code_3[] = {
5897 0xfffe0300, /* vs_3_0 */
5898 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5899 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5900 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5901 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5902 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5903 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5904 0x0000ffff /* end */
5906 DWORD color_color_shader_code_2[] = {
5907 0xfffe0200, /* vs_2_0 */
5908 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5909 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5910 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5911 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5912 0x0000ffff /* end */
5914 DWORD color_color_shader_code_1[] = {
5915 0xfffe0101, /* vs_1_1 */
5916 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5917 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5918 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5919 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5920 0x0000ffff /* end */
5922 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5923 HRESULT hr;
5924 DWORD color, r, g, b;
5925 float quad1[] = {
5926 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5927 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5928 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5929 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5931 float quad2[] = {
5932 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5933 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5934 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5935 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5937 float quad3[] = {
5938 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5939 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5940 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5941 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5943 float quad4[] = {
5944 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5945 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5946 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5947 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5949 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5950 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5951 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5952 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5953 D3DDECL_END()
5955 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5956 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5957 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5958 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5959 D3DDECL_END()
5961 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5962 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5963 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5964 D3DDECL_END()
5966 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5967 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5968 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5969 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5970 D3DDECL_END()
5972 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5973 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5974 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5975 D3DDECL_END()
5977 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5978 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5979 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5980 D3DDECL_END()
5982 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5983 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5984 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5985 D3DDECL_END()
5987 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5988 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5989 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5990 D3DDECL_END()
5992 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5993 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5994 unsigned int i;
5995 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5996 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5998 struct vertex quad1_color[] = {
5999 {-1.0, -1.0, 0.1, 0x00ff8040},
6000 { 0.0, -1.0, 0.1, 0x00ff8040},
6001 {-1.0, 0.0, 0.1, 0x00ff8040},
6002 { 0.0, 0.0, 0.1, 0x00ff8040}
6004 struct vertex quad2_color[] = {
6005 { 0.0, -1.0, 0.1, 0x00ff8040},
6006 { 1.0, -1.0, 0.1, 0x00ff8040},
6007 { 0.0, 0.0, 0.1, 0x00ff8040},
6008 { 1.0, 0.0, 0.1, 0x00ff8040}
6010 struct vertex quad3_color[] = {
6011 {-1.0, 0.0, 0.1, 0x00ff8040},
6012 { 0.0, 0.0, 0.1, 0x00ff8040},
6013 {-1.0, 1.0, 0.1, 0x00ff8040},
6014 { 0.0, 1.0, 0.1, 0x00ff8040}
6016 float quad4_color[] = {
6017 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6018 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6019 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6020 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6023 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6025 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6026 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6027 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6028 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6029 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6032 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6033 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6034 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6036 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6038 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6039 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6041 for(i = 1; i <= 3; i++) {
6042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6043 if(i == 3) {
6044 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6045 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6046 } else if(i == 2){
6047 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6048 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6049 } else if(i == 1) {
6050 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6051 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6054 hr = IDirect3DDevice9_BeginScene(device);
6055 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6056 if(SUCCEEDED(hr))
6058 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6059 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6061 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6062 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6064 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6066 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6067 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6069 if(i == 3 || i == 2) {
6070 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6071 } else if(i == 1) {
6072 /* Succeeds or fails, depending on SW or HW vertex processing */
6073 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6076 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6077 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6078 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6079 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6081 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6084 if(i == 3 || i == 2) {
6085 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6086 } else if(i == 1) {
6087 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6090 hr = IDirect3DDevice9_EndScene(device);
6091 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6094 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6095 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6097 if(i == 3 || i == 2) {
6098 color = getPixelColor(device, 160, 360);
6099 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6100 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6102 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6103 color = getPixelColor(device, 480, 360);
6104 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6105 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6106 color = getPixelColor(device, 160, 120);
6107 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6108 ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6109 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6111 color = getPixelColor(device, 480, 160);
6112 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6113 } else if(i == 1) {
6114 color = getPixelColor(device, 160, 360);
6115 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6116 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6117 color = getPixelColor(device, 480, 360);
6118 /* Accept the clear color as well in this case, since SW VP returns an error */
6119 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6120 color = getPixelColor(device, 160, 120);
6121 ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6122 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6123 color = getPixelColor(device, 480, 160);
6124 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6127 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6128 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6130 /* Now find out if the whole streams are re-read, or just the last active value for the
6131 * vertices is used.
6133 hr = IDirect3DDevice9_BeginScene(device);
6134 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6135 if(SUCCEEDED(hr))
6137 float quad1_modified[] = {
6138 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6139 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6140 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6141 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6143 float quad2_modified[] = {
6144 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6145 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6146 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6147 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6150 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6151 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6153 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6154 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6156 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6158 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6161 if(i == 3 || i == 2) {
6162 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6163 } else if(i == 1) {
6164 /* Succeeds or fails, depending on SW or HW vertex processing */
6165 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6168 hr = IDirect3DDevice9_EndScene(device);
6169 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6171 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6174 color = getPixelColor(device, 480, 350);
6175 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6176 * as well.
6178 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6179 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6180 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6181 * refrast's result.
6183 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6185 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6186 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6187 color = getPixelColor(device, 160, 120);
6189 IDirect3DDevice9_SetVertexShader(device, NULL);
6190 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6192 IDirect3DVertexShader9_Release(swapped_shader);
6195 for(i = 1; i <= 3; i++) {
6196 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6197 if(i == 3) {
6198 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6199 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6200 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6201 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6202 } else if(i == 2){
6203 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6205 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6207 } else if(i == 1) {
6208 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6209 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6210 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6214 hr = IDirect3DDevice9_BeginScene(device);
6215 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6216 if(SUCCEEDED(hr))
6218 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6219 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6220 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6223 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6225 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6228 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6230 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6233 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6235 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6236 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6237 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6238 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6240 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6242 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6243 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6245 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6247 hr = IDirect3DDevice9_EndScene(device);
6248 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6250 IDirect3DDevice9_SetVertexShader(device, NULL);
6251 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6253 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6254 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6256 color = getPixelColor(device, 160, 360);
6257 r = (color & 0x00ff0000) >> 16;
6258 g = (color & 0x0000ff00) >> 8;
6259 b = (color & 0x000000ff) >> 0;
6260 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6261 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6262 color = getPixelColor(device, 480, 360);
6263 r = (color & 0x00ff0000) >> 16;
6264 g = (color & 0x0000ff00) >> 8;
6265 b = (color & 0x000000ff) >> 0;
6266 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6267 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6268 color = getPixelColor(device, 160, 120);
6269 r = (color & 0x00ff0000) >> 16;
6270 g = (color & 0x0000ff00) >> 8;
6271 b = (color & 0x000000ff) >> 0;
6272 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6273 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6274 color = getPixelColor(device, 480, 160);
6275 r = (color & 0x00ff0000) >> 16;
6276 g = (color & 0x0000ff00) >> 8;
6277 b = (color & 0x000000ff) >> 0;
6278 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6279 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6281 IDirect3DVertexShader9_Release(texcoord_color_shader);
6282 IDirect3DVertexShader9_Release(color_color_shader);
6285 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6286 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6287 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6288 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6290 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6291 IDirect3DVertexDeclaration9_Release(decl_color_color);
6292 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6293 IDirect3DVertexDeclaration9_Release(decl_color_float);
6296 static void srgbtexture_test(IDirect3DDevice9 *device)
6298 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6299 * texture stage state to render a quad using that texture. The resulting
6300 * color components should be 0x36 (~ 0.21), per this formula:
6301 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6302 * This is true where srgb_color > 0.04045.
6304 IDirect3D9 *d3d = NULL;
6305 HRESULT hr;
6306 LPDIRECT3DTEXTURE9 texture = NULL;
6307 LPDIRECT3DSURFACE9 surface = NULL;
6308 D3DLOCKED_RECT lr;
6309 DWORD color;
6310 float quad[] = {
6311 -1.0, 1.0, 0.0, 0.0, 0.0,
6312 1.0, 1.0, 0.0, 1.0, 0.0,
6313 -1.0, -1.0, 0.0, 0.0, 1.0,
6314 1.0, -1.0, 0.0, 1.0, 1.0,
6318 memset(&lr, 0, sizeof(lr));
6319 IDirect3DDevice9_GetDirect3D(device, &d3d);
6320 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6321 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6322 D3DFMT_A8R8G8B8) != D3D_OK) {
6323 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6324 goto out;
6327 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6328 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6329 &texture, NULL);
6330 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6331 if(!texture) {
6332 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6333 goto out;
6335 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6336 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6338 fill_surface(surface, 0xff7f7f7f);
6339 IDirect3DSurface9_Release(surface);
6341 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6342 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6343 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6346 hr = IDirect3DDevice9_BeginScene(device);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6348 if(SUCCEEDED(hr))
6350 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6351 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6353 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6358 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6360 hr = IDirect3DDevice9_EndScene(device);
6361 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6364 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6365 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6366 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6367 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6369 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6370 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6372 color = getPixelColor(device, 320, 240);
6373 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6375 out:
6376 if(texture) IDirect3DTexture9_Release(texture);
6377 IDirect3D9_Release(d3d);
6380 /* Return true if color is near the expected value */
6381 static int color_near(DWORD color, DWORD expected)
6383 const BYTE slop = 2;
6385 BYTE r, g, b;
6386 BYTE rx, gx, bx;
6387 r = (color & 0x00ff0000) >> 16;
6388 g = (color & 0x0000ff00) >> 8;
6389 b = (color & 0x000000ff);
6390 rx = (expected & 0x00ff0000) >> 16;
6391 gx = (expected & 0x0000ff00) >> 8;
6392 bx = (expected & 0x000000ff);
6394 return
6395 ((r >= (rx - slop)) && (r <= (rx + slop))) &&
6396 ((g >= (gx - slop)) && (g <= (gx + slop))) &&
6397 ((b >= (bx - slop)) && (b <= (bx + slop)));
6400 static void shademode_test(IDirect3DDevice9 *device)
6402 /* Render a quad and try all of the different fixed function shading models. */
6403 HRESULT hr;
6404 DWORD color0, color1;
6405 DWORD color0_gouraud = 0, color1_gouraud = 0;
6406 DWORD shademode = D3DSHADE_FLAT;
6407 DWORD primtype = D3DPT_TRIANGLESTRIP;
6408 LPVOID data = NULL;
6409 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6410 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6411 UINT i, j;
6412 struct vertex quad_strip[] =
6414 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6415 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6416 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6417 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6419 struct vertex quad_list[] =
6421 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6422 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6423 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6425 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6426 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6427 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6430 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6431 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6432 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6433 if (FAILED(hr)) goto bail;
6435 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6436 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6437 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6438 if (FAILED(hr)) goto bail;
6440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6443 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6444 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6446 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6447 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6448 memcpy(data, quad_strip, sizeof(quad_strip));
6449 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6450 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6452 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6453 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6454 memcpy(data, quad_list, sizeof(quad_list));
6455 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6456 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6458 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6459 * the color fixups we have to do for FLAT shading will be dependent on that. */
6460 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6461 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6463 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6464 for (j=0; j<2; j++) {
6466 /* Inner loop just changes the D3DRS_SHADEMODE */
6467 for (i=0; i<3; i++) {
6468 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6469 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6471 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6472 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6474 hr = IDirect3DDevice9_BeginScene(device);
6475 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6476 if(SUCCEEDED(hr))
6478 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6479 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6481 hr = IDirect3DDevice9_EndScene(device);
6482 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6485 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6486 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6488 /* Sample two spots from the output */
6489 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6490 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6491 switch(shademode) {
6492 case D3DSHADE_FLAT:
6493 /* Should take the color of the first vertex of each triangle */
6494 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6495 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6496 shademode = D3DSHADE_GOURAUD;
6497 break;
6498 case D3DSHADE_GOURAUD:
6499 /* Should be an interpolated blend */
6501 ok(color_near(color0, 0x000dca28),
6502 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6503 ok(color_near(color1, 0x000d45c7),
6504 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6506 color0_gouraud = color0;
6507 color1_gouraud = color1;
6509 shademode = D3DSHADE_PHONG;
6510 break;
6511 case D3DSHADE_PHONG:
6512 /* Should be the same as GOURAUD, since no hardware implements this */
6513 ok(color_near(color0, 0x000dca28),
6514 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6515 ok(color_near(color1, 0x000d45c7),
6516 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6518 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6519 color0_gouraud, color0);
6520 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6521 color1_gouraud, color1);
6522 break;
6525 /* Now, do it all over again with a TRIANGLELIST */
6526 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6527 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6528 primtype = D3DPT_TRIANGLELIST;
6529 shademode = D3DSHADE_FLAT;
6532 bail:
6533 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6534 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6536 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6538 if (vb_strip)
6539 IDirect3DVertexBuffer9_Release(vb_strip);
6540 if (vb_list)
6541 IDirect3DVertexBuffer9_Release(vb_list);
6545 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6547 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6548 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6549 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6550 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6551 * 0.73
6553 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6554 * so use shaders for this task
6556 IDirect3DPixelShader9 *pshader;
6557 IDirect3DVertexShader9 *vshader;
6558 IDirect3D9 *d3d;
6559 DWORD vshader_code[] = {
6560 0xfffe0101, /* vs_1_1 */
6561 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6562 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6563 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6564 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6565 0x0000ffff /* end */
6567 DWORD pshader_code[] = {
6568 0xffff0101, /* ps_1_1 */
6569 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6570 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6571 0x0000ffff /* end */
6573 const float quad[] = {
6574 -1.0, -1.0, 0.1,
6575 1.0, -1.0, 0.1,
6576 -1.0, 1.0, 0.1,
6577 1.0, 1.0, 0.1
6579 HRESULT hr;
6580 DWORD color;
6582 IDirect3DDevice9_GetDirect3D(device, &d3d);
6583 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6584 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6585 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6586 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6587 * works
6589 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6590 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6591 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6592 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6593 IDirect3D9_Release(d3d);
6594 return;
6596 IDirect3D9_Release(d3d);
6598 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6599 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6601 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6602 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6604 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6606 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6608 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6609 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6610 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6612 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6613 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6614 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6615 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6616 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6617 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6618 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6619 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6620 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6621 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6623 hr = IDirect3DDevice9_BeginScene(device);
6624 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6625 if(SUCCEEDED(hr)) {
6626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6627 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6629 hr = IDirect3DDevice9_EndScene(device);
6630 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6633 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6634 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6635 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6636 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6637 IDirect3DPixelShader9_Release(pshader);
6638 IDirect3DVertexShader9_Release(vshader);
6640 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6641 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6643 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6645 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6646 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6647 color = getPixelColor(device, 160, 360);
6648 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6649 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6652 static void alpha_test(IDirect3DDevice9 *device)
6654 HRESULT hr;
6655 IDirect3DTexture9 *offscreenTexture;
6656 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6657 DWORD color;
6659 struct vertex quad1[] =
6661 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6662 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6663 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6664 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6666 struct vertex quad2[] =
6668 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6669 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6670 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6671 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6673 static const float composite_quad[][5] = {
6674 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6675 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6676 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6677 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6680 /* Clear the render target with alpha = 0.5 */
6681 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6682 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6684 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6685 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6687 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6688 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6689 if(!backbuffer) {
6690 goto out;
6693 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6694 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6695 if(!offscreen) {
6696 goto out;
6699 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6703 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6704 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6705 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6706 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6707 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6708 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6709 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6711 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6715 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6717 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6723 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6725 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6726 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6728 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6730 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6732 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6733 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6734 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6735 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6736 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6738 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6741 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6745 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6748 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6749 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6752 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6754 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6755 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6757 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6758 * Disable alpha blending for the final composition
6760 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6761 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6762 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6763 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6765 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6766 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6768 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6769 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6770 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6772 hr = IDirect3DDevice9_EndScene(device);
6773 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6776 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6778 color = getPixelColor(device, 160, 360);
6779 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6780 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6782 color = getPixelColor(device, 160, 120);
6783 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6784 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6786 color = getPixelColor(device, 480, 360);
6787 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6788 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6790 color = getPixelColor(device, 480, 120);
6791 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6792 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6794 out:
6795 /* restore things */
6796 if(backbuffer) {
6797 IDirect3DSurface9_Release(backbuffer);
6799 if(offscreenTexture) {
6800 IDirect3DTexture9_Release(offscreenTexture);
6802 if(offscreen) {
6803 IDirect3DSurface9_Release(offscreen);
6807 struct vertex_shortcolor {
6808 float x, y, z;
6809 unsigned short r, g, b, a;
6811 struct vertex_floatcolor {
6812 float x, y, z;
6813 float r, g, b, a;
6816 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6818 HRESULT hr;
6819 BOOL s_ok, ub_ok, f_ok;
6820 DWORD color, size, i;
6821 void *data;
6822 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6823 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6824 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6825 D3DDECL_END()
6827 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6828 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6829 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6830 D3DDECL_END()
6832 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6833 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6834 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6835 D3DDECL_END()
6837 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6838 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6839 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6840 D3DDECL_END()
6842 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6843 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6844 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6845 D3DDECL_END()
6847 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6848 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6849 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6850 D3DDECL_END()
6852 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6853 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6854 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6855 D3DDECL_END()
6857 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6858 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6859 IDirect3DVertexBuffer9 *vb, *vb2;
6860 struct vertex quad1[] = /* D3DCOLOR */
6862 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6863 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6864 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6865 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6867 struct vertex quad2[] = /* UBYTE4N */
6869 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6870 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6871 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6872 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6874 struct vertex_shortcolor quad3[] = /* short */
6876 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6877 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6878 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6879 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6881 struct vertex_floatcolor quad4[] =
6883 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6884 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6885 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6886 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6888 DWORD colors[] = {
6889 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6890 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6891 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
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,
6906 float quads[] = {
6907 -1.0, -1.0, 0.1,
6908 -1.0, 0.0, 0.1,
6909 0.0, -1.0, 0.1,
6910 0.0, 0.0, 0.1,
6912 0.0, -1.0, 0.1,
6913 0.0, 0.0, 0.1,
6914 1.0, -1.0, 0.1,
6915 1.0, 0.0, 0.1,
6917 0.0, 0.0, 0.1,
6918 0.0, 1.0, 0.1,
6919 1.0, 0.0, 0.1,
6920 1.0, 1.0, 0.1,
6922 -1.0, 0.0, 0.1,
6923 -1.0, 1.0, 0.1,
6924 0.0, 0.0, 0.1,
6925 0.0, 1.0, 0.1
6927 struct tvertex quad_transformed[] = {
6928 { 90, 110, 0.1, 2.0, 0x00ffff00},
6929 { 570, 110, 0.1, 2.0, 0x00ffff00},
6930 { 90, 300, 0.1, 2.0, 0x00ffff00},
6931 { 570, 300, 0.1, 2.0, 0x00ffff00}
6933 D3DCAPS9 caps;
6935 memset(&caps, 0, sizeof(caps));
6936 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6937 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6940 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6942 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6943 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6944 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6945 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6946 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6947 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6948 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6949 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6950 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6951 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6952 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6953 } else {
6954 trace("D3DDTCAPS_UBYTE4N not supported\n");
6955 dcl_ubyte_2 = NULL;
6956 dcl_ubyte = NULL;
6958 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6959 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6960 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6961 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6963 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6964 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6965 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6966 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6968 hr = IDirect3DDevice9_BeginScene(device);
6969 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6970 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6971 if(SUCCEEDED(hr)) {
6972 if(dcl_color) {
6973 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6974 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6976 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6979 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6980 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6981 * using software vertex processing. Doh!
6983 if(dcl_ubyte) {
6984 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6985 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6987 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6988 ub_ok = SUCCEEDED(hr);
6991 if(dcl_short) {
6992 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6993 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6995 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6996 s_ok = SUCCEEDED(hr);
6999 if(dcl_float) {
7000 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7001 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7003 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7004 f_ok = SUCCEEDED(hr);
7007 hr = IDirect3DDevice9_EndScene(device);
7008 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7011 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7012 if(dcl_short) {
7013 color = getPixelColor(device, 480, 360);
7014 ok(color == 0x000000ff || !s_ok,
7015 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7017 if(dcl_ubyte) {
7018 color = getPixelColor(device, 160, 120);
7019 ok(color == 0x0000ffff || !ub_ok,
7020 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7022 if(dcl_color) {
7023 color = getPixelColor(device, 160, 360);
7024 ok(color == 0x00ffff00,
7025 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7027 if(dcl_float) {
7028 color = getPixelColor(device, 480, 120);
7029 ok(color == 0x00ff0000 || !f_ok,
7030 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7033 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7034 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7035 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7036 * whether the immediate mode code works
7038 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7039 hr = IDirect3DDevice9_BeginScene(device);
7040 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7041 if(SUCCEEDED(hr)) {
7042 if(dcl_color) {
7043 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7044 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7045 memcpy(data, quad1, sizeof(quad1));
7046 hr = IDirect3DVertexBuffer9_Unlock(vb);
7047 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7048 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7051 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7052 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7053 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7056 if(dcl_ubyte) {
7057 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7058 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7059 memcpy(data, quad2, sizeof(quad2));
7060 hr = IDirect3DVertexBuffer9_Unlock(vb);
7061 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7062 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7063 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7064 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7065 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7066 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7067 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7068 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7069 ub_ok = SUCCEEDED(hr);
7072 if(dcl_short) {
7073 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7074 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7075 memcpy(data, quad3, sizeof(quad3));
7076 hr = IDirect3DVertexBuffer9_Unlock(vb);
7077 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7078 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7079 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7080 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7081 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7082 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7083 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7084 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7085 s_ok = SUCCEEDED(hr);
7088 if(dcl_float) {
7089 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7090 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7091 memcpy(data, quad4, sizeof(quad4));
7092 hr = IDirect3DVertexBuffer9_Unlock(vb);
7093 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7094 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7095 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7096 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7097 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7098 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7099 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7100 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7101 f_ok = SUCCEEDED(hr);
7104 hr = IDirect3DDevice9_EndScene(device);
7105 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7108 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7109 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7110 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7113 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7114 if(dcl_short) {
7115 color = getPixelColor(device, 480, 360);
7116 ok(color == 0x000000ff || !s_ok,
7117 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7119 if(dcl_ubyte) {
7120 color = getPixelColor(device, 160, 120);
7121 ok(color == 0x0000ffff || !ub_ok,
7122 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7124 if(dcl_color) {
7125 color = getPixelColor(device, 160, 360);
7126 ok(color == 0x00ffff00,
7127 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7129 if(dcl_float) {
7130 color = getPixelColor(device, 480, 120);
7131 ok(color == 0x00ff0000 || !f_ok,
7132 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7135 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7136 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7138 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7139 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7140 memcpy(data, quad_transformed, sizeof(quad_transformed));
7141 hr = IDirect3DVertexBuffer9_Unlock(vb);
7142 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7144 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7145 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7147 hr = IDirect3DDevice9_BeginScene(device);
7148 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7149 if(SUCCEEDED(hr)) {
7150 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7151 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7152 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7153 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7155 hr = IDirect3DDevice9_EndScene(device);
7156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7159 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7160 color = getPixelColor(device, 88, 108);
7161 ok(color == 0x000000ff,
7162 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7163 color = getPixelColor(device, 92, 108);
7164 ok(color == 0x000000ff,
7165 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7166 color = getPixelColor(device, 88, 112);
7167 ok(color == 0x000000ff,
7168 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7169 color = getPixelColor(device, 92, 112);
7170 ok(color == 0x00ffff00,
7171 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7173 color = getPixelColor(device, 568, 108);
7174 ok(color == 0x000000ff,
7175 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7176 color = getPixelColor(device, 572, 108);
7177 ok(color == 0x000000ff,
7178 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7179 color = getPixelColor(device, 568, 112);
7180 ok(color == 0x00ffff00,
7181 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7182 color = getPixelColor(device, 572, 112);
7183 ok(color == 0x000000ff,
7184 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7186 color = getPixelColor(device, 88, 298);
7187 ok(color == 0x000000ff,
7188 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7189 color = getPixelColor(device, 92, 298);
7190 ok(color == 0x00ffff00,
7191 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7192 color = getPixelColor(device, 88, 302);
7193 ok(color == 0x000000ff,
7194 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7195 color = getPixelColor(device, 92, 302);
7196 ok(color == 0x000000ff,
7197 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7199 color = getPixelColor(device, 568, 298);
7200 ok(color == 0x00ffff00,
7201 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7202 color = getPixelColor(device, 572, 298);
7203 ok(color == 0x000000ff,
7204 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7205 color = getPixelColor(device, 568, 302);
7206 ok(color == 0x000000ff,
7207 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7208 color = getPixelColor(device, 572, 302);
7209 ok(color == 0x000000ff,
7210 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7212 /* This test is pointless without those two declarations: */
7213 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7214 skip("color-ubyte switching test declarations aren't supported\n");
7215 goto out;
7218 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7219 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7220 memcpy(data, quads, sizeof(quads));
7221 hr = IDirect3DVertexBuffer9_Unlock(vb);
7222 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7223 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7224 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7225 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7226 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7227 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7228 memcpy(data, colors, sizeof(colors));
7229 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7230 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7232 for(i = 0; i < 2; i++) {
7233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7236 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7238 if(i == 0) {
7239 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7240 } else {
7241 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7243 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7245 hr = IDirect3DDevice9_BeginScene(device);
7246 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7247 ub_ok = FALSE;
7248 if(SUCCEEDED(hr)) {
7249 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7250 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7251 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7252 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7253 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7254 ub_ok = SUCCEEDED(hr);
7256 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7258 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7259 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7261 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7262 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7263 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7264 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7265 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7266 ub_ok = (SUCCEEDED(hr) && ub_ok);
7268 hr = IDirect3DDevice9_EndScene(device);
7269 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7272 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7273 if(i == 0) {
7274 color = getPixelColor(device, 480, 360);
7275 ok(color == 0x00ff0000,
7276 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7277 color = getPixelColor(device, 160, 120);
7278 ok(color == 0x00ffffff,
7279 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7280 color = getPixelColor(device, 160, 360);
7281 ok(color == 0x000000ff || !ub_ok,
7282 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7283 color = getPixelColor(device, 480, 120);
7284 ok(color == 0x000000ff || !ub_ok,
7285 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7286 } else {
7287 color = getPixelColor(device, 480, 360);
7288 ok(color == 0x000000ff,
7289 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7290 color = getPixelColor(device, 160, 120);
7291 ok(color == 0x00ffffff,
7292 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7293 color = getPixelColor(device, 160, 360);
7294 ok(color == 0x00ff0000 || !ub_ok,
7295 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7296 color = getPixelColor(device, 480, 120);
7297 ok(color == 0x00ff0000 || !ub_ok,
7298 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7302 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7303 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7304 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7305 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7306 IDirect3DVertexBuffer9_Release(vb2);
7308 out:
7309 IDirect3DVertexBuffer9_Release(vb);
7310 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7311 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7312 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7313 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7314 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7315 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7316 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7319 struct vertex_float16color {
7320 float x, y, z;
7321 DWORD c1, c2;
7324 static void test_vshader_float16(IDirect3DDevice9 *device)
7326 HRESULT hr;
7327 DWORD color;
7328 void *data;
7329 static const D3DVERTEXELEMENT9 decl_elements[] = {
7330 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7331 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7332 D3DDECL_END()
7334 IDirect3DVertexDeclaration9 *vdecl = NULL;
7335 IDirect3DVertexBuffer9 *buffer = NULL;
7336 IDirect3DVertexShader9 *shader;
7337 DWORD shader_code[] = {
7338 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7339 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7340 0x90e40001, 0x0000ffff
7342 struct vertex_float16color quad[] = {
7343 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7344 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7345 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7346 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7348 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7349 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7350 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7351 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7353 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7354 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7355 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7356 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7358 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7359 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7360 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7361 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7367 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7368 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7369 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7370 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7371 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7372 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7374 hr = IDirect3DDevice9_BeginScene(device);
7375 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7376 if(SUCCEEDED(hr)) {
7377 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7378 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7380 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7382 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7384 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7386 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7388 hr = IDirect3DDevice9_EndScene(device);
7389 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7391 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7392 color = getPixelColor(device, 480, 360);
7393 ok(color == 0x00ff0000,
7394 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7395 color = getPixelColor(device, 160, 120);
7396 ok(color == 0x00000000,
7397 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7398 color = getPixelColor(device, 160, 360);
7399 ok(color == 0x0000ff00,
7400 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7401 color = getPixelColor(device, 480, 120);
7402 ok(color == 0x000000ff,
7403 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7406 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7408 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7409 D3DPOOL_MANAGED, &buffer, NULL);
7410 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7411 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7412 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7413 memcpy(data, quad, sizeof(quad));
7414 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7415 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7416 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7417 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7419 hr = IDirect3DDevice9_BeginScene(device);
7420 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7421 if(SUCCEEDED(hr)) {
7422 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7423 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7424 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7425 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7426 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7427 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7428 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7429 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7431 hr = IDirect3DDevice9_EndScene(device);
7432 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7435 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7436 color = getPixelColor(device, 480, 360);
7437 ok(color == 0x00ff0000,
7438 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7439 color = getPixelColor(device, 160, 120);
7440 ok(color == 0x00000000,
7441 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7442 color = getPixelColor(device, 160, 360);
7443 ok(color == 0x0000ff00,
7444 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7445 color = getPixelColor(device, 480, 120);
7446 ok(color == 0x000000ff,
7447 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7449 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7450 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7451 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7452 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7453 IDirect3DDevice9_SetVertexShader(device, NULL);
7454 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7456 IDirect3DVertexDeclaration9_Release(vdecl);
7457 IDirect3DVertexShader9_Release(shader);
7458 IDirect3DVertexBuffer9_Release(buffer);
7461 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7463 D3DCAPS9 caps;
7464 IDirect3DTexture9 *texture;
7465 HRESULT hr;
7466 D3DLOCKED_RECT rect;
7467 unsigned int x, y;
7468 DWORD *dst, color;
7469 const float quad[] = {
7470 -1.0, -1.0, 0.1, -0.2, -0.2,
7471 1.0, -1.0, 0.1, 1.2, -0.2,
7472 -1.0, 1.0, 0.1, -0.2, 1.2,
7473 1.0, 1.0, 0.1, 1.2, 1.2
7475 memset(&caps, 0, sizeof(caps));
7477 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7478 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7479 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7480 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7481 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7482 "Card has conditional NP2 support without power of two restriction set\n");
7483 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7484 return;
7485 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7486 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7487 return;
7490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7493 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7494 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7496 memset(&rect, 0, sizeof(rect));
7497 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7498 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7499 for(y = 0; y < 10; y++) {
7500 for(x = 0; x < 10; x++) {
7501 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7502 if(x == 0 || x == 9 || y == 0 || y == 9) {
7503 *dst = 0x00ff0000;
7504 } else {
7505 *dst = 0x000000ff;
7509 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7510 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7512 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7513 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7514 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7515 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7516 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7517 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7518 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7521 hr = IDirect3DDevice9_BeginScene(device);
7522 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7523 if(SUCCEEDED(hr)) {
7524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7525 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7527 hr = IDirect3DDevice9_EndScene(device);
7528 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7531 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7533 color = getPixelColor(device, 1, 1);
7534 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7535 color = getPixelColor(device, 639, 479);
7536 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7538 color = getPixelColor(device, 135, 101);
7539 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7540 color = getPixelColor(device, 140, 101);
7541 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7542 color = getPixelColor(device, 135, 105);
7543 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7544 color = getPixelColor(device, 140, 105);
7545 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7547 color = getPixelColor(device, 135, 376);
7548 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7549 color = getPixelColor(device, 140, 376);
7550 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7551 color = getPixelColor(device, 135, 379);
7552 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7553 color = getPixelColor(device, 140, 379);
7554 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7556 color = getPixelColor(device, 500, 101);
7557 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7558 color = getPixelColor(device, 504, 101);
7559 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7560 color = getPixelColor(device, 500, 105);
7561 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7562 color = getPixelColor(device, 504, 105);
7563 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7565 color = getPixelColor(device, 500, 376);
7566 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7567 color = getPixelColor(device, 504, 376);
7568 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7569 color = getPixelColor(device, 500, 380);
7570 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7571 color = getPixelColor(device, 504, 380);
7572 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7574 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7576 IDirect3DTexture9_Release(texture);
7579 static void vFace_register_test(IDirect3DDevice9 *device)
7581 HRESULT hr;
7582 DWORD color;
7583 const DWORD shader_code[] = {
7584 0xffff0300, /* ps_3_0 */
7585 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7586 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7587 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7588 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7589 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7590 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7591 0x0000ffff /* END */
7593 IDirect3DPixelShader9 *shader;
7594 IDirect3DTexture9 *texture;
7595 IDirect3DSurface9 *surface, *backbuffer;
7596 const float quad[] = {
7597 -1.0, -1.0, 0.1,
7598 1.0, -1.0, 0.1,
7599 -1.0, 0.0, 0.1,
7601 1.0, -1.0, 0.1,
7602 1.0, 0.0, 0.1,
7603 -1.0, 0.0, 0.1,
7605 -1.0, 0.0, 0.1,
7606 -1.0, 1.0, 0.1,
7607 1.0, 0.0, 0.1,
7609 1.0, 0.0, 0.1,
7610 -1.0, 1.0, 0.1,
7611 1.0, 1.0, 0.1,
7613 const float blit[] = {
7614 0.0, -1.0, 0.1, 0.0, 0.0,
7615 1.0, -1.0, 0.1, 1.0, 0.0,
7616 0.0, 1.0, 0.1, 0.0, 1.0,
7617 1.0, 1.0, 0.1, 1.0, 1.0,
7620 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7621 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7622 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7623 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7624 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7625 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7626 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7627 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7628 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7629 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7630 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7631 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7633 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7636 hr = IDirect3DDevice9_BeginScene(device);
7637 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7638 if(SUCCEEDED(hr)) {
7639 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7640 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7641 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7643 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7645 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7646 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7649 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7651 /* Blit the texture onto the back buffer to make it visible */
7652 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7653 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7654 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7655 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7656 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7657 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7658 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7659 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7660 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7661 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7666 hr = IDirect3DDevice9_EndScene(device);
7667 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7670 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7671 color = getPixelColor(device, 160, 360);
7672 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7673 color = getPixelColor(device, 160, 120);
7674 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7675 color = getPixelColor(device, 480, 360);
7676 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7677 color = getPixelColor(device, 480, 120);
7678 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7680 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7681 IDirect3DDevice9_SetTexture(device, 0, NULL);
7682 IDirect3DPixelShader9_Release(shader);
7683 IDirect3DSurface9_Release(surface);
7684 IDirect3DSurface9_Release(backbuffer);
7685 IDirect3DTexture9_Release(texture);
7688 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7690 HRESULT hr;
7691 DWORD color;
7692 int i;
7693 D3DCAPS9 caps;
7695 static const float quad[][7] = {
7696 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7697 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7698 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7699 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7702 static const D3DVERTEXELEMENT9 decl_elements[] = {
7703 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7704 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7705 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7706 D3DDECL_END()
7709 /* use asymmetric matrix to test loading */
7710 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7712 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7713 IDirect3DTexture9 *texture = NULL;
7715 memset(&caps, 0, sizeof(caps));
7716 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7717 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7718 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7719 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7720 return;
7721 } else {
7722 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7723 * They report that it is not supported, but after that bump mapping works properly. So just test
7724 * if the format is generally supported, and check the BUMPENVMAP flag
7726 IDirect3D9 *d3d9;
7728 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7729 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7730 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7731 IDirect3D9_Release(d3d9);
7732 if(FAILED(hr)) {
7733 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7734 return;
7738 /* Generate the textures */
7739 generate_bumpmap_textures(device);
7741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7742 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7743 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7744 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7745 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7746 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7747 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7748 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7750 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7751 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7752 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7753 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7754 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7755 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7757 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7758 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7759 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7760 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7761 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7762 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7764 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7765 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7767 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7768 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7771 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7774 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7775 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7776 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7777 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7779 hr = IDirect3DDevice9_BeginScene(device);
7780 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7783 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7785 hr = IDirect3DDevice9_EndScene(device);
7786 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7789 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7791 color = getPixelColor(device, 320-32, 240);
7792 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7793 color = getPixelColor(device, 320+32, 240);
7794 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7795 color = getPixelColor(device, 320, 240-32);
7796 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7797 color = getPixelColor(device, 320, 240+32);
7798 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7799 color = getPixelColor(device, 320, 240);
7800 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7801 color = getPixelColor(device, 320+32, 240+32);
7802 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7803 color = getPixelColor(device, 320-32, 240+32);
7804 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7805 color = getPixelColor(device, 320+32, 240-32);
7806 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7807 color = getPixelColor(device, 320-32, 240-32);
7808 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7810 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7811 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7812 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7814 for(i = 0; i < 2; i++) {
7815 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7816 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7817 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7818 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7819 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7820 IDirect3DTexture9_Release(texture); /* To destroy it */
7823 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7824 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7825 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7826 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7830 static void stencil_cull_test(IDirect3DDevice9 *device) {
7831 HRESULT hr;
7832 IDirect3DSurface9 *depthstencil = NULL;
7833 D3DSURFACE_DESC desc;
7834 float quad1[] = {
7835 -1.0, -1.0, 0.1,
7836 0.0, -1.0, 0.1,
7837 -1.0, 0.0, 0.1,
7838 0.0, 0.0, 0.1,
7840 float quad2[] = {
7841 0.0, -1.0, 0.1,
7842 1.0, -1.0, 0.1,
7843 0.0, 0.0, 0.1,
7844 1.0, 0.0, 0.1,
7846 float quad3[] = {
7847 0.0, 0.0, 0.1,
7848 1.0, 0.0, 0.1,
7849 0.0, 1.0, 0.1,
7850 1.0, 1.0, 0.1,
7852 float quad4[] = {
7853 -1.0, 0.0, 0.1,
7854 0.0, 0.0, 0.1,
7855 -1.0, 1.0, 0.1,
7856 0.0, 1.0, 0.1,
7858 struct vertex painter[] = {
7859 {-1.0, -1.0, 0.0, 0x00000000},
7860 { 1.0, -1.0, 0.0, 0x00000000},
7861 {-1.0, 1.0, 0.0, 0x00000000},
7862 { 1.0, 1.0, 0.0, 0x00000000},
7864 WORD indices_cw[] = {0, 1, 3};
7865 WORD indices_ccw[] = {0, 2, 3};
7866 unsigned int i;
7867 DWORD color;
7869 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7870 if(depthstencil == NULL) {
7871 skip("No depth stencil buffer\n");
7872 return;
7874 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7875 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7876 IDirect3DSurface9_Release(depthstencil);
7877 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7878 skip("No 4 or 8 bit stencil surface\n");
7879 return;
7882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7883 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7884 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7896 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7897 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7898 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7899 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7905 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7907 /* First pass: Fill the stencil buffer with some values... */
7908 hr = IDirect3DDevice9_BeginScene(device);
7909 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7910 if(SUCCEEDED(hr))
7912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7913 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7914 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7915 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7916 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7917 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7920 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7921 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7922 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7923 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7924 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7925 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7926 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7929 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7930 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7931 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7932 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7933 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7937 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7938 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7939 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7940 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7942 hr = IDirect3DDevice9_EndScene(device);
7943 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7946 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7948 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7950 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7952 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7953 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7954 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7956 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7958 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7960 /* 2nd pass: Make the stencil values visible */
7961 hr = IDirect3DDevice9_BeginScene(device);
7962 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7963 if(SUCCEEDED(hr))
7965 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7966 for(i = 0; i < 16; i++) {
7967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7968 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7970 painter[0].diffuse = (i * 16); /* Creates shades of blue */
7971 painter[1].diffuse = (i * 16);
7972 painter[2].diffuse = (i * 16);
7973 painter[3].diffuse = (i * 16);
7974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7975 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7977 hr = IDirect3DDevice9_EndScene(device);
7978 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7981 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7982 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7985 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7987 color = getPixelColor(device, 160, 420);
7988 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7989 color = getPixelColor(device, 160, 300);
7990 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7992 color = getPixelColor(device, 480, 420);
7993 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7994 color = getPixelColor(device, 480, 300);
7995 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7997 color = getPixelColor(device, 160, 180);
7998 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7999 color = getPixelColor(device, 160, 60);
8000 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8002 color = getPixelColor(device, 480, 180);
8003 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8004 color = getPixelColor(device, 480, 60);
8005 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8008 static void vpos_register_test(IDirect3DDevice9 *device)
8010 HRESULT hr;
8011 DWORD color;
8012 const DWORD shader_code[] = {
8013 0xffff0300, /* ps_3_0 */
8014 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8015 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8016 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8017 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8018 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8019 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8020 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8021 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8022 0x0000ffff /* end */
8024 const DWORD shader_frac_code[] = {
8025 0xffff0300, /* ps_3_0 */
8026 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8027 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8028 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8029 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8030 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8031 0x0000ffff /* end */
8033 IDirect3DPixelShader9 *shader, *shader_frac;
8034 IDirect3DSurface9 *surface = NULL, *backbuffer;
8035 const float quad[] = {
8036 -1.0, -1.0, 0.1, 0.0, 0.0,
8037 1.0, -1.0, 0.1, 1.0, 0.0,
8038 -1.0, 1.0, 0.1, 0.0, 1.0,
8039 1.0, 1.0, 0.1, 1.0, 1.0,
8041 D3DLOCKED_RECT lr;
8042 float constant[4] = {1.0, 0.0, 320, 240};
8043 DWORD *pos;
8045 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8046 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8047 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8048 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8049 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8050 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8051 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8052 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8053 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8054 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8055 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8056 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8058 hr = IDirect3DDevice9_BeginScene(device);
8059 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8060 if(SUCCEEDED(hr)) {
8061 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8062 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8064 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8065 hr = IDirect3DDevice9_EndScene(device);
8066 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8069 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8070 /* This has to be pixel exact */
8071 color = getPixelColor(device, 319, 239);
8072 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8073 color = getPixelColor(device, 320, 239);
8074 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8075 color = getPixelColor(device, 319, 240);
8076 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8077 color = getPixelColor(device, 320, 240);
8078 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8080 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8081 &surface, NULL);
8082 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8083 hr = IDirect3DDevice9_BeginScene(device);
8084 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8085 if(SUCCEEDED(hr)) {
8086 constant[2] = 16; constant[3] = 16;
8087 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8088 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8089 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8090 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8092 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8093 hr = IDirect3DDevice9_EndScene(device);
8094 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8096 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8097 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8099 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8100 color = *pos & 0x00ffffff;
8101 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8102 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8103 color = *pos & 0x00ffffff;
8104 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8105 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8106 color = *pos & 0x00ffffff;
8107 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8108 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8109 color = *pos & 0x00ffffff;
8110 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8112 hr = IDirect3DSurface9_UnlockRect(surface);
8113 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8115 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8116 * have full control over the multisampling setting inside this test
8118 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8119 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8120 hr = IDirect3DDevice9_BeginScene(device);
8121 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8122 if(SUCCEEDED(hr)) {
8123 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8124 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8126 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8127 hr = IDirect3DDevice9_EndScene(device);
8128 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8130 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8133 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8134 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8136 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8137 color = *pos & 0x00ffffff;
8138 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8140 hr = IDirect3DSurface9_UnlockRect(surface);
8141 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8143 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8144 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8145 IDirect3DPixelShader9_Release(shader);
8146 IDirect3DPixelShader9_Release(shader_frac);
8147 if(surface) IDirect3DSurface9_Release(surface);
8148 IDirect3DSurface9_Release(backbuffer);
8151 static void pointsize_test(IDirect3DDevice9 *device)
8153 HRESULT hr;
8154 D3DCAPS9 caps;
8155 D3DMATRIX matrix;
8156 D3DMATRIX identity;
8157 float ptsize, ptsize_orig;
8158 DWORD color;
8160 const float vertices[] = {
8161 64, 64, 0.1,
8162 128, 64, 0.1,
8163 192, 64, 0.1,
8164 256, 64, 0.1,
8165 320, 64, 0.1,
8166 384, 64, 0.1
8169 /* 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 */
8170 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;
8171 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;
8172 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;
8173 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;
8175 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;
8176 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;
8177 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;
8178 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;
8180 memset(&caps, 0, sizeof(caps));
8181 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8182 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8183 if(caps.MaxPointSize < 32.0) {
8184 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8185 return;
8188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8189 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8190 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8191 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8192 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8193 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8194 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8195 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8197 hr = IDirect3DDevice9_BeginScene(device);
8198 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8199 if(SUCCEEDED(hr)) {
8200 ptsize = 16.0;
8201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8204 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8206 ptsize = 32.0;
8207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8210 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8212 ptsize = 31.5;
8213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8216 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8218 if(caps.MaxPointSize >= 64.0) {
8219 ptsize = 64.0;
8220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8221 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8223 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8225 ptsize = 63.75;
8226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8229 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8232 ptsize = 1.0;
8233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8236 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8238 hr = IDirect3DDevice9_EndScene(device);
8239 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8241 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8242 color = getPixelColor(device, 64-9, 64-9);
8243 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8244 color = getPixelColor(device, 64-8, 64-8);
8245 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8246 color = getPixelColor(device, 64-7, 64-7);
8247 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8248 color = getPixelColor(device, 64+7, 64+7);
8249 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8250 color = getPixelColor(device, 64+8, 64+8);
8251 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8252 color = getPixelColor(device, 64+9, 64+9);
8253 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8255 color = getPixelColor(device, 128-17, 64-17);
8256 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8257 color = getPixelColor(device, 128-16, 64-16);
8258 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8259 color = getPixelColor(device, 128-15, 64-15);
8260 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8261 color = getPixelColor(device, 128+15, 64+15);
8262 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8263 color = getPixelColor(device, 128+16, 64+16);
8264 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8265 color = getPixelColor(device, 128+17, 64+17);
8266 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8268 color = getPixelColor(device, 192-17, 64-17);
8269 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8270 color = getPixelColor(device, 192-16, 64-16);
8271 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8272 color = getPixelColor(device, 192-15, 64-15);
8273 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8274 color = getPixelColor(device, 192+15, 64+15);
8275 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8276 color = getPixelColor(device, 192+16, 64+16);
8277 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8278 color = getPixelColor(device, 192+17, 64+17);
8279 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8281 if(caps.MaxPointSize >= 64.0) {
8282 color = getPixelColor(device, 256-33, 64-33);
8283 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8284 color = getPixelColor(device, 256-32, 64-32);
8285 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8286 color = getPixelColor(device, 256-31, 64-31);
8287 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8288 color = getPixelColor(device, 256+31, 64+31);
8289 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8290 color = getPixelColor(device, 256+32, 64+32);
8291 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8292 color = getPixelColor(device, 256+33, 64+33);
8293 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8295 color = getPixelColor(device, 384-33, 64-33);
8296 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8297 color = getPixelColor(device, 384-32, 64-32);
8298 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8299 color = getPixelColor(device, 384-31, 64-31);
8300 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8301 color = getPixelColor(device, 384+31, 64+31);
8302 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8303 color = getPixelColor(device, 384+32, 64+32);
8304 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8305 color = getPixelColor(device, 384+33, 64+33);
8306 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8309 color = getPixelColor(device, 320-1, 64-1);
8310 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8311 color = getPixelColor(device, 320-0, 64-0);
8312 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8313 color = getPixelColor(device, 320+1, 64+1);
8314 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8318 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8319 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8322 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8324 HRESULT hr;
8325 IDirect3DPixelShader9 *ps;
8326 IDirect3DTexture9 *tex1, *tex2;
8327 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8328 D3DCAPS9 caps;
8329 DWORD color;
8330 DWORD shader_code[] = {
8331 0xffff0300, /* ps_3_0 */
8332 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8333 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8334 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8335 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8336 0x0000ffff /* END */
8338 float quad[] = {
8339 -1.0, -1.0, 0.1,
8340 1.0, -1.0, 0.1,
8341 -1.0, 1.0, 0.1,
8342 1.0, 1.0, 0.1,
8344 float texquad[] = {
8345 -1.0, -1.0, 0.1, 0.0, 0.0,
8346 0.0, -1.0, 0.1, 1.0, 0.0,
8347 -1.0, 1.0, 0.1, 0.0, 1.0,
8348 0.0, 1.0, 0.1, 1.0, 1.0,
8350 0.0, -1.0, 0.1, 0.0, 0.0,
8351 1.0, -1.0, 0.1, 1.0, 0.0,
8352 0.0, 1.0, 0.1, 0.0, 1.0,
8353 1.0, 1.0, 0.1, 1.0, 1.0,
8356 memset(&caps, 0, sizeof(caps));
8357 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8358 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8359 if(caps.NumSimultaneousRTs < 2) {
8360 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8361 return;
8364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8367 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8368 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8369 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8370 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8371 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8372 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8374 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8375 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8376 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8377 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8378 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8379 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8381 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8382 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8383 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8385 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8387 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8388 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8390 hr = IDirect3DDevice9_BeginScene(device);
8391 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8392 if(SUCCEEDED(hr)) {
8393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8394 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8396 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8397 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8398 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8400 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8401 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8402 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8403 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8405 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8406 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8408 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8410 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8413 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8415 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8416 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8418 hr = IDirect3DDevice9_EndScene(device);
8419 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8422 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8423 color = getPixelColor(device, 160, 240);
8424 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8425 color = getPixelColor(device, 480, 240);
8426 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8428 IDirect3DPixelShader9_Release(ps);
8429 IDirect3DTexture9_Release(tex1);
8430 IDirect3DTexture9_Release(tex2);
8431 IDirect3DSurface9_Release(surf1);
8432 IDirect3DSurface9_Release(surf2);
8433 IDirect3DSurface9_Release(backbuf);
8436 struct formats {
8437 const char *fmtName;
8438 D3DFORMAT textureFormat;
8439 DWORD resultColorBlending;
8440 DWORD resultColorNoBlending;
8443 const struct formats test_formats[] = {
8444 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8445 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8446 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8447 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8448 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8449 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8450 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8451 { NULL, 0 }
8454 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8456 HRESULT hr;
8457 IDirect3DTexture9 *offscreenTexture = NULL;
8458 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8459 IDirect3D9 *d3d = NULL;
8460 DWORD color;
8461 DWORD r0, g0, b0, r1, g1, b1;
8462 int fmt_index;
8464 static const float quad[][5] = {
8465 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8466 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8467 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8468 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8471 /* Quad with R=0x10, G=0x20 */
8472 static const struct vertex quad1[] = {
8473 {-1.0f, -1.0f, 0.1f, 0x80102000},
8474 {-1.0f, 1.0f, 0.1f, 0x80102000},
8475 { 1.0f, -1.0f, 0.1f, 0x80102000},
8476 { 1.0f, 1.0f, 0.1f, 0x80102000},
8479 /* Quad with R=0x20, G=0x10 */
8480 static const struct vertex quad2[] = {
8481 {-1.0f, -1.0f, 0.1f, 0x80201000},
8482 {-1.0f, 1.0f, 0.1f, 0x80201000},
8483 { 1.0f, -1.0f, 0.1f, 0x80201000},
8484 { 1.0f, 1.0f, 0.1f, 0x80201000},
8487 IDirect3DDevice9_GetDirect3D(device, &d3d);
8489 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8490 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8491 if(!backbuffer) {
8492 goto out;
8495 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8497 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8498 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8499 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8500 continue;
8503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8504 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8506 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8507 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8508 if(!offscreenTexture) {
8509 continue;
8512 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8513 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8514 if(!offscreen) {
8515 continue;
8518 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8519 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8521 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8522 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8523 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8524 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8525 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8526 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8527 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8528 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8530 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8532 /* Below we will draw two quads with different colors and try to blend them together.
8533 * The result color is compared with the expected outcome.
8535 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8536 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8537 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8539 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8542 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8544 /* Draw a quad using color 0x0010200 */
8545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8548 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8550 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8552 /* Draw a quad using color 0x0020100 */
8553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8554 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8556 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8558 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8560 /* We don't want to blend the result on the backbuffer */
8561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8562 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8564 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8565 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8566 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8567 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8568 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8570 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8571 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8573 /* This time with the texture */
8574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8575 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8577 IDirect3DDevice9_EndScene(device);
8579 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8582 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8583 /* Compare the color of the center quad with our expectation */
8584 color = getPixelColor(device, 320, 240);
8585 r0 = (color & 0x00ff0000) >> 16;
8586 g0 = (color & 0x0000ff00) >> 8;
8587 b0 = (color & 0x000000ff) >> 0;
8589 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8590 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8591 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8593 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8594 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8595 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8596 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8597 } else {
8598 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8599 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8600 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8601 color = getPixelColor(device, 320, 240);
8602 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);
8605 IDirect3DDevice9_SetTexture(device, 0, NULL);
8606 if(offscreenTexture) {
8607 IDirect3DTexture9_Release(offscreenTexture);
8609 if(offscreen) {
8610 IDirect3DSurface9_Release(offscreen);
8614 out:
8615 /* restore things */
8616 if(backbuffer) {
8617 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8618 IDirect3DSurface9_Release(backbuffer);
8622 static void tssargtemp_test(IDirect3DDevice9 *device)
8624 HRESULT hr;
8625 DWORD color;
8626 static const struct vertex quad[] = {
8627 {-1.0, -1.0, 0.1, 0x00ff0000},
8628 { 1.0, -1.0, 0.1, 0x00ff0000},
8629 {-1.0, 1.0, 0.1, 0x00ff0000},
8630 { 1.0, 1.0, 0.1, 0x00ff0000}
8632 D3DCAPS9 caps;
8634 memset(&caps, 0, sizeof(caps));
8635 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8636 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8637 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8638 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8639 return;
8642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8643 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8645 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8646 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8647 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8648 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8650 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8651 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8652 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8653 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8654 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8655 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8657 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8658 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8659 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8660 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8661 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8662 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8664 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8665 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8669 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8670 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8672 hr = IDirect3DDevice9_BeginScene(device);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8674 if(SUCCEEDED(hr)) {
8676 hr = IDirect3DDevice9_EndScene(device);
8677 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8679 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8681 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8682 color = getPixelColor(device, 320, 240);
8683 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8685 /* Set stage 1 back to default */
8686 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8687 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8688 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8689 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8690 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8691 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8692 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8693 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8694 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8695 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8698 struct testdata
8700 DWORD idxVertex; /* number of instances in the first stream */
8701 DWORD idxColor; /* number of instances in the second stream */
8702 DWORD idxInstance; /* should be 1 ?? */
8703 DWORD color1; /* color 1 instance */
8704 DWORD color2; /* color 2 instance */
8705 DWORD color3; /* color 3 instance */
8706 DWORD color4; /* color 4 instance */
8707 WORD strVertex; /* specify which stream to use 0-2*/
8708 WORD strColor;
8709 WORD strInstance;
8712 static const struct testdata testcases[]=
8714 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8715 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8716 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8717 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8718 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8719 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8720 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8721 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8722 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8723 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8724 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8725 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8726 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8727 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8728 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8730 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8731 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8735 /* Drawing Indexed Geometry with instances*/
8736 static void stream_test(IDirect3DDevice9 *device)
8738 IDirect3DVertexBuffer9 *vb = NULL;
8739 IDirect3DVertexBuffer9 *vb2 = NULL;
8740 IDirect3DVertexBuffer9 *vb3 = NULL;
8741 IDirect3DIndexBuffer9 *ib = NULL;
8742 IDirect3DVertexDeclaration9 *pDecl = NULL;
8743 IDirect3DVertexShader9 *shader = NULL;
8744 HRESULT hr;
8745 BYTE *data;
8746 DWORD color;
8747 DWORD ind;
8748 int i;
8750 const DWORD shader_code[] =
8752 0xfffe0101, /* vs_1_1 */
8753 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8754 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8755 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8756 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8757 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8758 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8759 0x0000ffff
8762 const float quad[][3] =
8764 {-0.5f, -0.5f, 1.1f}, /*0 */
8765 {-0.5f, 0.5f, 1.1f}, /*1 */
8766 { 0.5f, -0.5f, 1.1f}, /*2 */
8767 { 0.5f, 0.5f, 1.1f}, /*3 */
8770 const float vertcolor[][4] =
8772 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8773 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8774 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8775 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8778 /* 4 position for 4 instances */
8779 const float instancepos[][3] =
8781 {-0.6f,-0.6f, 0.0f},
8782 { 0.6f,-0.6f, 0.0f},
8783 { 0.6f, 0.6f, 0.0f},
8784 {-0.6f, 0.6f, 0.0f},
8787 short indices[] = {0, 1, 2, 1, 2, 3};
8789 D3DVERTEXELEMENT9 decl[] =
8791 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8792 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8793 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8794 D3DDECL_END()
8797 /* set the default value because it isn't done in wine? */
8798 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8799 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8801 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8802 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8803 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8805 /* check wrong cases */
8806 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8807 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8808 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8809 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8810 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8811 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8812 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8813 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8814 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8815 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8816 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8817 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8818 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8819 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8820 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8821 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8822 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8823 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8824 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8825 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8827 /* set the default value back */
8828 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8829 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8831 /* create all VertexBuffers*/
8832 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8833 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8834 if(!vb) {
8835 skip("Failed to create a vertex buffer\n");
8836 return;
8838 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8839 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8840 if(!vb2) {
8841 skip("Failed to create a vertex buffer\n");
8842 goto out;
8844 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8845 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8846 if(!vb3) {
8847 skip("Failed to create a vertex buffer\n");
8848 goto out;
8851 /* create IndexBuffer*/
8852 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8853 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8854 if(!ib) {
8855 skip("Failed to create a index buffer\n");
8856 goto out;
8859 /* copy all Buffers (Vertex + Index)*/
8860 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8861 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8862 memcpy(data, quad, sizeof(quad));
8863 hr = IDirect3DVertexBuffer9_Unlock(vb);
8864 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8865 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8866 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8867 memcpy(data, vertcolor, sizeof(vertcolor));
8868 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8869 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8870 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8871 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8872 memcpy(data, instancepos, sizeof(instancepos));
8873 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8874 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8875 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8876 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8877 memcpy(data, indices, sizeof(indices));
8878 hr = IDirect3DIndexBuffer9_Unlock(ib);
8879 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8881 /* create VertexShader */
8882 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8883 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8884 if(!shader) {
8885 skip("Failed to create a vetex shader\n");
8886 goto out;
8889 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8890 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8892 hr = IDirect3DDevice9_SetIndices(device, ib);
8893 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8895 /* run all tests */
8896 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8898 struct testdata act = testcases[i];
8899 decl[0].Stream = act.strVertex;
8900 decl[1].Stream = act.strColor;
8901 decl[2].Stream = act.strInstance;
8902 /* create VertexDeclarations */
8903 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8904 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8907 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8909 hr = IDirect3DDevice9_BeginScene(device);
8910 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8911 if(SUCCEEDED(hr))
8913 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8914 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8916 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8917 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8918 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8919 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8921 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8922 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8923 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8924 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8926 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8927 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8928 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8929 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8931 /* don't know if this is right (1*3 and 4*1)*/
8932 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8933 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8934 hr = IDirect3DDevice9_EndScene(device);
8935 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8937 /* set all StreamSource && StreamSourceFreq back to default */
8938 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8939 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8940 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8941 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8942 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8943 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8944 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8945 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8946 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8947 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8948 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8952 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8953 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8955 hr = IDirect3DVertexDeclaration9_Release(pDecl);
8956 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8958 color = getPixelColor(device, 160, 360);
8959 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8960 color = getPixelColor(device, 480, 360);
8961 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8962 color = getPixelColor(device, 480, 120);
8963 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8964 color = getPixelColor(device, 160, 120);
8965 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8968 hr = IDirect3DDevice9_SetIndices(device, NULL);
8969 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8971 out:
8972 if(vb) IDirect3DVertexBuffer9_Release(vb);
8973 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8974 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8975 if(ib)IDirect3DIndexBuffer9_Release(ib);
8976 if(shader)IDirect3DVertexShader9_Release(shader);
8979 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8980 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8981 IDirect3DTexture9 *dsttex = NULL;
8982 HRESULT hr;
8983 DWORD color;
8984 D3DRECT r1 = {0, 0, 50, 50 };
8985 D3DRECT r2 = {50, 0, 100, 50 };
8986 D3DRECT r3 = {50, 50, 100, 100};
8987 D3DRECT r4 = {0, 50, 50, 100};
8988 const float quad[] = {
8989 -1.0, -1.0, 0.1, 0.0, 0.0,
8990 1.0, -1.0, 0.1, 1.0, 0.0,
8991 -1.0, 1.0, 0.1, 0.0, 1.0,
8992 1.0, 1.0, 0.1, 1.0, 1.0,
8995 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8996 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
8998 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
8999 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
9000 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9001 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
9003 if(!src || !dsttex) {
9004 skip("One or more test resources could not be created\n");
9005 goto cleanup;
9008 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9009 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
9011 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9012 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9014 /* Clear the StretchRect destination for debugging */
9015 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9016 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9017 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9018 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9020 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9021 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9023 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9024 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9025 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9026 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9027 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9028 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9029 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9030 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9032 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9033 * the target -> texture GL blit path
9035 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9036 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9037 IDirect3DSurface9_Release(dst);
9039 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9042 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9043 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9045 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9046 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9047 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9048 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9049 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9051 hr = IDirect3DDevice9_BeginScene(device);
9052 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9053 if(SUCCEEDED(hr)) {
9054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9055 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9056 hr = IDirect3DDevice9_EndScene(device);
9057 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9060 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9061 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9062 color = getPixelColor(device, 160, 360);
9063 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9064 color = getPixelColor(device, 480, 360);
9065 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9066 color = getPixelColor(device, 480, 120);
9067 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9068 color = getPixelColor(device, 160, 120);
9069 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9071 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9072 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9073 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9074 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9076 cleanup:
9077 if(src) IDirect3DSurface9_Release(src);
9078 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9079 if(dsttex) IDirect3DTexture9_Release(dsttex);
9082 static void texop_test(IDirect3DDevice9 *device)
9084 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9085 IDirect3DTexture9 *texture = NULL;
9086 D3DLOCKED_RECT locked_rect;
9087 D3DCOLOR color;
9088 D3DCAPS9 caps;
9089 HRESULT hr;
9090 int i;
9092 static const struct {
9093 float x, y, z;
9094 float s, t;
9095 D3DCOLOR diffuse;
9096 } quad[] = {
9097 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9098 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9099 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9100 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9103 static const D3DVERTEXELEMENT9 decl_elements[] = {
9104 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9105 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9106 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9107 D3DDECL_END()
9110 static const struct {
9111 D3DTEXTUREOP op;
9112 const char *name;
9113 DWORD caps_flag;
9114 D3DCOLOR result;
9115 } test_data[] = {
9116 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9117 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9118 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9119 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9120 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9121 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9122 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9123 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9124 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9125 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9126 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9127 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9128 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9129 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9130 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9131 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9132 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9133 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9134 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9135 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9136 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9137 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9138 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9141 memset(&caps, 0, sizeof(caps));
9142 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9143 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9145 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9146 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9147 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9148 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9150 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9151 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9152 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9153 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9154 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9155 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9156 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9157 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9158 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9160 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9161 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9163 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9164 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9165 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9167 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9168 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9171 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9173 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9175 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9178 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9180 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9182 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9184 skip("tex operation %s not supported\n", test_data[i].name);
9185 continue;
9188 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9189 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x (%s)\n",
9190 test_data[i].name, hr, DXGetErrorString9(hr));
9192 hr = IDirect3DDevice9_BeginScene(device);
9193 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9195 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9196 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9198 hr = IDirect3DDevice9_EndScene(device);
9199 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9201 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9202 ok(SUCCEEDED(hr), "Present failed with 0x%08x (%s)\n", hr, DXGetErrorString9(hr));
9204 color = getPixelColor(device, 320, 240);
9205 ok(color_match(color, test_data[i].result, 1), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9206 test_data[i].name, color, test_data[i].result);
9209 if (texture) IDirect3DTexture9_Release(texture);
9210 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9213 START_TEST(visual)
9215 IDirect3DDevice9 *device_ptr;
9216 D3DCAPS9 caps;
9217 HRESULT hr;
9218 DWORD color;
9220 d3d9_handle = LoadLibraryA("d3d9.dll");
9221 if (!d3d9_handle)
9223 skip("Could not load d3d9.dll\n");
9224 return;
9227 device_ptr = init_d3d9();
9228 if (!device_ptr)
9230 skip("Creating the device failed\n");
9231 return;
9234 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9236 /* Check for the reliability of the returned data */
9237 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9238 if(FAILED(hr))
9240 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9241 goto cleanup;
9243 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9245 color = getPixelColor(device_ptr, 1, 1);
9246 if(color !=0x00ff0000)
9248 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9249 goto cleanup;
9252 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9253 if(FAILED(hr))
9255 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9256 goto cleanup;
9258 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9260 color = getPixelColor(device_ptr, 639, 479);
9261 if(color != 0x0000ddee)
9263 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9264 goto cleanup;
9267 /* Now execute the real tests */
9268 stretchrect_test(device_ptr);
9269 lighting_test(device_ptr);
9270 clear_test(device_ptr);
9271 fog_test(device_ptr);
9272 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9274 test_cube_wrap(device_ptr);
9275 } else {
9276 skip("No cube texture support\n");
9278 z_range_test(device_ptr);
9279 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9281 maxmip_test(device_ptr);
9283 else
9285 skip("No mipmap support\n");
9287 offscreen_test(device_ptr);
9288 alpha_test(device_ptr);
9289 shademode_test(device_ptr);
9290 srgbtexture_test(device_ptr);
9291 release_buffer_test(device_ptr);
9292 float_texture_test(device_ptr);
9293 g16r16_texture_test(device_ptr);
9294 pixelshader_blending_test(device_ptr);
9295 texture_transform_flags_test(device_ptr);
9296 autogen_mipmap_test(device_ptr);
9297 fixed_function_decl_test(device_ptr);
9298 conditional_np2_repeat_test(device_ptr);
9299 fixed_function_bumpmap_test(device_ptr);
9300 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9301 stencil_cull_test(device_ptr);
9302 } else {
9303 skip("No two sided stencil support\n");
9305 pointsize_test(device_ptr);
9306 tssargtemp_test(device_ptr);
9307 np2_stretch_rect_test(device_ptr);
9309 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9311 test_constant_clamp_vs(device_ptr);
9312 test_compare_instructions(device_ptr);
9314 else skip("No vs_1_1 support\n");
9316 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9318 test_mova(device_ptr);
9319 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9320 test_vshader_input(device_ptr);
9321 test_vshader_float16(device_ptr);
9322 stream_test(device_ptr);
9323 } else {
9324 skip("No vs_3_0 support\n");
9327 else skip("No vs_2_0 support\n");
9329 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9331 fog_with_shader_test(device_ptr);
9332 fog_srgbwrite_test(device_ptr);
9334 else skip("No vs_1_1 and ps_1_1 support\n");
9336 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9338 texbem_test(device_ptr);
9339 texdepth_test(device_ptr);
9340 texkill_test(device_ptr);
9341 x8l8v8u8_test(device_ptr);
9342 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9343 constant_clamp_ps_test(device_ptr);
9344 cnd_test(device_ptr);
9345 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9346 dp2add_ps_test(device_ptr);
9347 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9348 nested_loop_test(device_ptr);
9349 fixed_function_varying_test(device_ptr);
9350 vFace_register_test(device_ptr);
9351 vpos_register_test(device_ptr);
9352 multiple_rendertargets_test(device_ptr);
9353 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9354 vshader_version_varying_test(device_ptr);
9355 pshader_version_varying_test(device_ptr);
9356 } else {
9357 skip("No vs_3_0 support\n");
9359 } else {
9360 skip("No ps_3_0 support\n");
9362 } else {
9363 skip("No ps_2_0 support\n");
9367 else skip("No ps_1_1 support\n");
9368 texop_test(device_ptr);
9370 cleanup:
9371 if(device_ptr) {
9372 ULONG ref;
9374 D3DPRESENT_PARAMETERS present_parameters;
9375 IDirect3DSwapChain9 *swapchain;
9376 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9377 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9378 IDirect3DSwapChain9_Release(swapchain);
9379 ref = IDirect3DDevice9_Release(device_ptr);
9380 DestroyWindow(present_parameters.hDeviceWindow);
9381 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);