push 45342d27cd031b08b6cfabdf8789426cb53c1c53
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob0663a9178c34c5900020ab2bef038d9030dc0d2e
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 c1 >>= 8; c2 >>= 8;
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55 c1 >>= 8; c2 >>= 8;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 c1 >>= 8; c2 >>= 8;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59 return TRUE;
62 /* Locks a given surface and returns the color at (x,y). It's the caller's
63 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 DWORD color;
67 HRESULT hr;
68 D3DSURFACE_DESC desc;
69 RECT rectToLock = {x, y, x+1, y+1};
70 D3DLOCKED_RECT lockedRect;
72 hr = IDirect3DSurface9_GetDesc(surface, &desc);
73 if(FAILED(hr)) /* This is not a test */
75 trace("Can't get the surface description, hr=%08x\n", hr);
76 return 0xdeadbeef;
79 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80 if(FAILED(hr)) /* This is not a test */
82 trace("Can't lock the surface, hr=%08x\n", hr);
83 return 0xdeadbeef;
85 switch(desc.Format) {
86 case D3DFMT_A8R8G8B8:
88 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89 break;
91 default:
92 trace("Error: unknown surface format: %d\n", desc.Format);
93 color = 0xdeadbeef;
94 break;
96 hr = IDirect3DSurface9_UnlockRect(surface);
97 if(FAILED(hr))
99 trace("Can't unlock the surface, hr=%08x\n", hr);
101 return color;
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 DWORD ret;
107 IDirect3DSurface9 *surf;
108 HRESULT hr;
109 D3DLOCKED_RECT lockedRect;
110 RECT rectToLock = {x, y, x+1, y+1};
112 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113 if(FAILED(hr) || !surf ) /* This is not a test */
115 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116 return 0xdeadbeef;
119 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120 if(FAILED(hr))
122 trace("Can't read the front buffer data, hr=%08x\n", hr);
123 ret = 0xdeadbeed;
124 goto out;
127 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128 if(FAILED(hr))
130 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131 ret = 0xdeadbeec;
132 goto out;
135 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136 * really important for these tests
138 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139 hr = IDirect3DSurface9_UnlockRect(surf);
140 if(FAILED(hr))
142 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
145 out:
146 if(surf) IDirect3DSurface9_Release(surf);
147 return ret;
150 static IDirect3DDevice9 *init_d3d9(void)
152 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153 IDirect3D9 *d3d9_ptr = 0;
154 IDirect3DDevice9 *device_ptr = 0;
155 D3DPRESENT_PARAMETERS present_parameters;
156 HRESULT hr;
157 D3DADAPTER_IDENTIFIER9 identifier;
159 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161 if (!d3d9_create) return NULL;
163 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164 if (!d3d9_ptr)
166 skip("could not create D3D9\n");
167 return NULL;
170 ZeroMemory(&present_parameters, sizeof(present_parameters));
171 present_parameters.Windowed = FALSE;
172 present_parameters.hDeviceWindow = create_window();
173 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174 present_parameters.BackBufferWidth = 640;
175 present_parameters.BackBufferHeight = 480;
176 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177 present_parameters.EnableAutoDepthStencil = TRUE;
178 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
180 memset(&identifier, 0, sizeof(identifier));
181 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183 trace("Driver string: \"%s\"\n", identifier.Driver);
184 trace("Description string: \"%s\"\n", identifier.Description);
185 trace("Device name string: \"%s\"\n", identifier.DeviceName);
186 trace("Driver version %d.%d.%d.%d\n",
187 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
188 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
190 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191 if(FAILED(hr)) {
192 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
193 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
194 if(FAILED(hr)) {
195 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
198 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
200 return device_ptr;
203 struct vertex
205 float x, y, z;
206 DWORD diffuse;
209 struct tvertex
211 float x, y, z, rhw;
212 DWORD diffuse;
215 struct nvertex
217 float x, y, z;
218 float nx, ny, nz;
219 DWORD diffuse;
222 static void lighting_test(IDirect3DDevice9 *device)
224 HRESULT hr;
225 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
226 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
227 DWORD color;
228 D3DMATERIAL9 material, old_material;
229 DWORD cop, carg;
231 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
232 0.0f, 1.0f, 0.0f, 0.0f,
233 0.0f, 0.0f, 1.0f, 0.0f,
234 0.0f, 0.0f, 0.0f, 1.0f };
236 struct vertex unlitquad[] =
238 {-1.0f, -1.0f, 0.1f, 0xffff0000},
239 {-1.0f, 0.0f, 0.1f, 0xffff0000},
240 { 0.0f, 0.0f, 0.1f, 0xffff0000},
241 { 0.0f, -1.0f, 0.1f, 0xffff0000},
243 struct vertex litquad[] =
245 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
246 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
247 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
248 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
250 struct nvertex unlitnquad[] =
252 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
253 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
254 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
255 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
257 struct nvertex litnquad[] =
259 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
260 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
261 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
262 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
264 WORD Indices[] = {0, 1, 2, 2, 3, 0};
266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
267 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
269 /* Setup some states that may cause issues */
270 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
271 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
272 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
295 hr = IDirect3DDevice9_SetFVF(device, 0);
296 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetFVF(device, fvf);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
301 hr = IDirect3DDevice9_BeginScene(device);
302 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
303 if(hr == D3D_OK)
305 /* No lights are defined... That means, lit vertices should be entirely black */
306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
308 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
309 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
310 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
315 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
316 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
318 hr = IDirect3DDevice9_SetFVF(device, nfvf);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
322 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
323 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
324 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
325 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
328 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
329 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
330 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
331 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
333 IDirect3DDevice9_EndScene(device);
334 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
337 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
339 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
340 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
341 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
342 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
343 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
344 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
345 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
346 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
348 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
349 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
350 memset(&material, 0, sizeof(material));
351 material.Diffuse.r = 0.0;
352 material.Diffuse.g = 0.0;
353 material.Diffuse.b = 0.0;
354 material.Diffuse.a = 1.0;
355 material.Ambient.r = 0.0;
356 material.Ambient.g = 0.0;
357 material.Ambient.b = 0.0;
358 material.Ambient.a = 0.0;
359 material.Specular.r = 0.0;
360 material.Specular.g = 0.0;
361 material.Specular.b = 0.0;
362 material.Specular.a = 0.0;
363 material.Emissive.r = 0.0;
364 material.Emissive.g = 0.0;
365 material.Emissive.b = 0.0;
366 material.Emissive.a = 0.0;
367 material.Power = 0.0;
368 IDirect3DDevice9_SetMaterial(device, &material);
369 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
372 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
374 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
376 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
377 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
378 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
379 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
381 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
382 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
383 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
385 hr = IDirect3DDevice9_BeginScene(device);
386 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
387 if(SUCCEEDED(hr)) {
388 struct vertex lighting_test[] = {
389 {-1.0, -1.0, 0.1, 0x8000ff00},
390 { 1.0, -1.0, 0.1, 0x80000000},
391 {-1.0, 1.0, 0.1, 0x8000ff00},
392 { 1.0, 1.0, 0.1, 0x80000000}
394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
399 hr = IDirect3DDevice9_EndScene(device);
400 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
403 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
404 color = getPixelColor(device, 320, 240);
405 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
407 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
408 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
414 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
417 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
418 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
421 static void clear_test(IDirect3DDevice9 *device)
423 /* Tests the correctness of clearing parameters */
424 HRESULT hr;
425 D3DRECT rect[2];
426 D3DRECT rect_negneg;
427 DWORD color;
428 D3DVIEWPORT9 old_vp, vp;
429 RECT scissor;
430 DWORD oldColorWrite;
431 BOOL invalid_clear_failed = FALSE;
433 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
434 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
436 /* Positive x, negative y */
437 rect[0].x1 = 0;
438 rect[0].y1 = 480;
439 rect[0].x2 = 320;
440 rect[0].y2 = 240;
442 /* Positive x, positive y */
443 rect[1].x1 = 0;
444 rect[1].y1 = 0;
445 rect[1].x2 = 320;
446 rect[1].y2 = 240;
447 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
448 * returns D3D_OK, but ignores the rectangle silently
450 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
451 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
452 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
454 /* negative x, negative y */
455 rect_negneg.x1 = 640;
456 rect_negneg.y1 = 240;
457 rect_negneg.x2 = 320;
458 rect_negneg.y2 = 0;
459 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
460 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
461 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
463 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
465 color = getPixelColor(device, 160, 360); /* lower left quad */
466 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
467 color = getPixelColor(device, 160, 120); /* upper left quad */
468 if(invalid_clear_failed) {
469 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
470 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
471 } else {
472 /* If the negative rectangle was dropped silently, the correct ones are cleared */
473 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
475 color = getPixelColor(device, 480, 360); /* lower right quad */
476 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
477 color = getPixelColor(device, 480, 120); /* upper right quad */
478 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
480 /* Test how the viewport affects clears */
481 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
482 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
483 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
484 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
486 vp.X = 160;
487 vp.Y = 120;
488 vp.Width = 160;
489 vp.Height = 120;
490 vp.MinZ = 0.0;
491 vp.MaxZ = 1.0;
492 hr = IDirect3DDevice9_SetViewport(device, &vp);
493 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
495 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
497 vp.X = 320;
498 vp.Y = 240;
499 vp.Width = 320;
500 vp.Height = 240;
501 vp.MinZ = 0.0;
502 vp.MaxZ = 1.0;
503 hr = IDirect3DDevice9_SetViewport(device, &vp);
504 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
505 rect[0].x1 = 160;
506 rect[0].y1 = 120;
507 rect[0].x2 = 480;
508 rect[0].y2 = 360;
509 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
510 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
512 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
513 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
515 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
516 color = getPixelColor(device, 158, 118);
517 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
518 color = getPixelColor(device, 162, 118);
519 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
520 color = getPixelColor(device, 158, 122);
521 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
522 color = getPixelColor(device, 162, 122);
523 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
525 color = getPixelColor(device, 318, 238);
526 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
527 color = getPixelColor(device, 322, 238);
528 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
529 color = getPixelColor(device, 318, 242);
530 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
531 color = getPixelColor(device, 322, 242);
532 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
534 color = getPixelColor(device, 478, 358);
535 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
536 color = getPixelColor(device, 482, 358);
537 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
538 color = getPixelColor(device, 478, 362);
539 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
540 color = getPixelColor(device, 482, 362);
541 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
544 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
546 scissor.left = 160;
547 scissor.right = 480;
548 scissor.top = 120;
549 scissor.bottom = 360;
550 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
551 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
553 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
556 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
557 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
558 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
561 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
563 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
564 color = getPixelColor(device, 158, 118);
565 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
566 color = getPixelColor(device, 162, 118);
567 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
568 color = getPixelColor(device, 158, 122);
569 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
570 color = getPixelColor(device, 162, 122);
571 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
573 color = getPixelColor(device, 158, 358);
574 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
575 color = getPixelColor(device, 162, 358);
576 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
577 color = getPixelColor(device, 158, 358);
578 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
579 color = getPixelColor(device, 162, 362);
580 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
582 color = getPixelColor(device, 478, 118);
583 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
584 color = getPixelColor(device, 478, 122);
585 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
586 color = getPixelColor(device, 482, 122);
587 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
588 color = getPixelColor(device, 482, 358);
589 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
591 color = getPixelColor(device, 478, 358);
592 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
593 color = getPixelColor(device, 478, 362);
594 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
595 color = getPixelColor(device, 482, 358);
596 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
597 color = getPixelColor(device, 482, 362);
598 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
600 color = getPixelColor(device, 318, 238);
601 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
602 color = getPixelColor(device, 318, 242);
603 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
604 color = getPixelColor(device, 322, 238);
605 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
606 color = getPixelColor(device, 322, 242);
607 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
609 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
610 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
612 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
614 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
615 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
618 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
620 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622 /* Colorwriteenable does not affect the clear */
623 color = getPixelColor(device, 320, 240);
624 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
627 typedef struct {
628 float in[4];
629 DWORD out;
630 } test_data_t;
633 * c7 mova ARGB mov ARGB
634 * -2.4 -2 0x00ffff00 -3 0x00ff0000
635 * -1.6 -2 0x00ffff00 -2 0x00ffff00
636 * -0.4 0 0x0000ffff -1 0x0000ff00
637 * 0.4 0 0x0000ffff 0 0x0000ffff
638 * 1.6 2 0x00ff00ff 1 0x000000ff
639 * 2.4 2 0x00ff00ff 2 0x00ff00ff
641 static void test_mova(IDirect3DDevice9 *device)
643 static const DWORD mova_test[] = {
644 0xfffe0200, /* vs_2_0 */
645 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
646 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
647 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
648 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
649 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
650 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
651 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
652 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
653 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
654 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
655 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
656 0x0000ffff /* END */
658 static const DWORD mov_test[] = {
659 0xfffe0101, /* vs_1_1 */
660 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
661 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
662 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
663 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
664 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
665 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
666 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
667 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
668 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
669 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
670 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
671 0x0000ffff /* END */
674 static const test_data_t test_data[2][6] = {
676 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
677 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
678 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
679 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
680 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
681 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
684 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
685 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
686 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
687 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
688 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
689 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
693 static const float quad[][3] = {
694 {-1.0f, -1.0f, 0.0f},
695 {-1.0f, 1.0f, 0.0f},
696 { 1.0f, -1.0f, 0.0f},
697 { 1.0f, 1.0f, 0.0f},
700 static const D3DVERTEXELEMENT9 decl_elements[] = {
701 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
702 D3DDECL_END()
705 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
706 IDirect3DVertexShader9 *mova_shader = NULL;
707 IDirect3DVertexShader9 *mov_shader = NULL;
708 HRESULT hr;
709 UINT i, j;
711 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
712 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
713 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
714 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
716 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
717 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
718 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
720 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
721 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
722 for(j = 0; j < 2; ++j)
724 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
726 DWORD color;
728 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
729 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
731 hr = IDirect3DDevice9_BeginScene(device);
732 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
735 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
737 hr = IDirect3DDevice9_EndScene(device);
738 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
740 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
741 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
743 color = getPixelColor(device, 320, 240);
744 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
745 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
748 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
750 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
751 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
754 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
755 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
757 IDirect3DVertexDeclaration9_Release(vertex_declaration);
758 IDirect3DVertexShader9_Release(mova_shader);
759 IDirect3DVertexShader9_Release(mov_shader);
762 struct sVertex {
763 float x, y, z;
764 DWORD diffuse;
765 DWORD specular;
768 struct sVertexT {
769 float x, y, z, rhw;
770 DWORD diffuse;
771 DWORD specular;
774 static void fog_test(IDirect3DDevice9 *device)
776 HRESULT hr;
777 DWORD color;
778 BYTE r, g, b;
779 float start = 0.0f, end = 1.0f;
780 D3DCAPS9 caps;
781 int i;
783 /* Gets full z based fog with linear fog, no fog with specular color */
784 struct sVertex unstransformed_1[] = {
785 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
786 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
787 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
788 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
790 /* Ok, I am too lazy to deal with transform matrices */
791 struct sVertex unstransformed_2[] = {
792 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
793 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
794 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
795 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
797 /* Untransformed ones. Give them a different diffuse color to make the test look
798 * nicer. It also makes making sure that they are drawn correctly easier.
800 struct sVertexT transformed_1[] = {
801 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
802 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
803 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
804 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
806 struct sVertexT transformed_2[] = {
807 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
808 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
809 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
810 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
812 struct vertex rev_fog_quads[] = {
813 {-1.0, -1.0, 0.1, 0x000000ff},
814 {-1.0, 0.0, 0.1, 0x000000ff},
815 { 0.0, 0.0, 0.1, 0x000000ff},
816 { 0.0, -1.0, 0.1, 0x000000ff},
818 { 0.0, -1.0, 0.9, 0x000000ff},
819 { 0.0, 0.0, 0.9, 0x000000ff},
820 { 1.0, 0.0, 0.9, 0x000000ff},
821 { 1.0, -1.0, 0.9, 0x000000ff},
823 { 0.0, 0.0, 0.4, 0x000000ff},
824 { 0.0, 1.0, 0.4, 0x000000ff},
825 { 1.0, 1.0, 0.4, 0x000000ff},
826 { 1.0, 0.0, 0.4, 0x000000ff},
828 {-1.0, 0.0, 0.7, 0x000000ff},
829 {-1.0, 1.0, 0.7, 0x000000ff},
830 { 0.0, 1.0, 0.7, 0x000000ff},
831 { 0.0, 0.0, 0.7, 0x000000ff},
833 WORD Indices[] = {0, 1, 2, 2, 3, 0};
835 memset(&caps, 0, sizeof(caps));
836 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
837 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
839 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
841 /* Setup initial states: No lighting, fog on, fog color */
842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
843 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
845 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
847 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
849 /* First test: Both table fog and vertex fog off */
850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
851 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
853 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
855 /* Start = 0, end = 1. Should be default, but set them */
856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
857 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
859 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
861 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
863 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
864 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
865 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
866 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
867 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
868 sizeof(unstransformed_1[0]));
869 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
871 /* That makes it use the Z value */
872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
873 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
874 /* Untransformed, vertex fog != none (or table fog != none):
875 * Use the Z value as input into the equation
877 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
878 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
879 sizeof(unstransformed_1[0]));
880 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
882 /* transformed verts */
883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
884 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
885 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
886 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
887 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
888 sizeof(transformed_1[0]));
889 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
892 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
893 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
894 * equation
896 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
897 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
898 sizeof(transformed_2[0]));
900 hr = IDirect3DDevice9_EndScene(device);
901 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
903 else
905 ok(FALSE, "BeginScene failed\n");
908 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
909 color = getPixelColor(device, 160, 360);
910 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
911 color = getPixelColor(device, 160, 120);
912 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
913 color = getPixelColor(device, 480, 120);
914 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
915 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
917 color = getPixelColor(device, 480, 360);
918 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
920 else
922 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
923 * The settings above result in no fogging with vertex fog
925 color = getPixelColor(device, 480, 120);
926 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
927 trace("Info: Table fog not supported by this device\n");
930 /* Now test the special case fogstart == fogend */
931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
932 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
934 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
936 start = 512;
937 end = 512;
938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
939 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
941 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
944 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
946 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
948 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
950 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
951 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
952 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
953 * The third transformed quad remains unfogged because the fogcoords are read from the specular
954 * color and has fixed fogstart and fogend.
956 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
957 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
958 sizeof(unstransformed_1[0]));
959 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
961 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
962 sizeof(unstransformed_1[0]));
963 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
965 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
966 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
967 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
968 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
969 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
970 sizeof(transformed_1[0]));
971 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
973 hr = IDirect3DDevice9_EndScene(device);
974 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
976 else
978 ok(FALSE, "BeginScene failed\n");
980 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
981 color = getPixelColor(device, 160, 360);
982 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
983 color = getPixelColor(device, 160, 120);
984 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
985 color = getPixelColor(device, 480, 120);
986 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
988 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
989 * but without shaders it seems to work everywhere
991 end = 0.2;
992 start = 0.8;
993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
994 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
996 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
997 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
998 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1000 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1001 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1002 * so skip this for now
1004 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1005 const char *mode = (i ? "table" : "vertex");
1006 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1007 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1009 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1011 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1012 hr = IDirect3DDevice9_BeginScene(device);
1013 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1014 if(SUCCEEDED(hr)) {
1015 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1016 4, 5, 6, 6, 7, 4,
1017 8, 9, 10, 10, 11, 8,
1018 12, 13, 14, 14, 15, 12};
1020 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1021 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1022 sizeof(rev_fog_quads[0]));
1024 hr = IDirect3DDevice9_EndScene(device);
1025 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1027 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1028 color = getPixelColor(device, 160, 360);
1029 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1031 color = getPixelColor(device, 160, 120);
1032 r = (color & 0x00ff0000) >> 16;
1033 g = (color & 0x0000ff00) >> 8;
1034 b = (color & 0x000000ff);
1035 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
1036 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1038 color = getPixelColor(device, 480, 120);
1039 r = (color & 0x00ff0000) >> 16;
1040 g = (color & 0x0000ff00) >> 8;
1041 b = (color & 0x000000ff);
1042 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
1043 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1045 color = getPixelColor(device, 480, 360);
1046 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1048 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1049 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1050 break;
1053 /* Turn off the fog master switch to avoid confusing other tests */
1054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1055 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1056 start = 0.0;
1057 end = 1.0;
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1059 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1061 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1063 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1065 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1068 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1069 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1070 * regardless of the actual addressing mode set. */
1071 static void test_cube_wrap(IDirect3DDevice9 *device)
1073 static const float quad[][6] = {
1074 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1075 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1076 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1077 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1080 static const D3DVERTEXELEMENT9 decl_elements[] = {
1081 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1082 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1083 D3DDECL_END()
1086 static const struct {
1087 D3DTEXTUREADDRESS mode;
1088 const char *name;
1089 } address_modes[] = {
1090 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1091 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1092 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1093 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1094 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1097 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1098 IDirect3DCubeTexture9 *texture = NULL;
1099 IDirect3DSurface9 *surface = NULL;
1100 D3DLOCKED_RECT locked_rect;
1101 HRESULT hr;
1102 UINT x;
1103 INT y, face;
1105 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1106 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1107 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1108 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1110 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1111 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1112 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1114 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1115 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1117 for (y = 0; y < 128; ++y)
1119 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1120 for (x = 0; x < 64; ++x)
1122 *ptr++ = 0xffff0000;
1124 for (x = 64; x < 128; ++x)
1126 *ptr++ = 0xff0000ff;
1130 hr = IDirect3DSurface9_UnlockRect(surface);
1131 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1133 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1134 D3DPOOL_DEFAULT, &texture, NULL);
1135 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1137 /* Create cube faces */
1138 for (face = 0; face < 6; ++face)
1140 IDirect3DSurface9 *face_surface = NULL;
1142 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1143 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1145 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1146 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1148 IDirect3DSurface9_Release(face_surface);
1151 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1152 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1154 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1155 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1156 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1157 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1158 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1159 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1162 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1164 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1166 DWORD color;
1168 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1169 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1171 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1173 hr = IDirect3DDevice9_BeginScene(device);
1174 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1177 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1179 hr = IDirect3DDevice9_EndScene(device);
1180 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1182 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1183 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1185 /* Due to the nature of this test, we sample essentially at the edge
1186 * between two faces. Because of this it's undefined from which face
1187 * the driver will sample. Fortunately that's not important for this
1188 * test, since all we care about is that it doesn't sample from the
1189 * other side of the surface or from the border. */
1190 color = getPixelColor(device, 320, 240);
1191 ok(color == 0x00ff0000 || color == 0x000000ff,
1192 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1193 color, address_modes[x].name);
1195 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1196 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1199 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1200 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1202 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1203 IDirect3DCubeTexture9_Release(texture);
1204 IDirect3DSurface9_Release(surface);
1207 static void offscreen_test(IDirect3DDevice9 *device)
1209 HRESULT hr;
1210 IDirect3DTexture9 *offscreenTexture = NULL;
1211 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1212 DWORD color;
1214 static const float quad[][5] = {
1215 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1216 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1217 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1218 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1222 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1224 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1225 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1226 if(!offscreenTexture) {
1227 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1228 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1229 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1230 if(!offscreenTexture) {
1231 skip("Cannot create an offscreen render target\n");
1232 goto out;
1236 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1237 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1238 if(!backbuffer) {
1239 goto out;
1242 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1243 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1244 if(!offscreen) {
1245 goto out;
1248 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1249 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1251 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1252 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1253 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1254 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1255 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1256 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1257 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1258 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1260 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1262 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1263 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1264 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1266 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1268 /* Draw without textures - Should result in a white quad */
1269 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1270 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1272 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1273 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1275 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1277 /* This time with the texture */
1278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1279 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1281 IDirect3DDevice9_EndScene(device);
1284 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1286 /* Center quad - should be white */
1287 color = getPixelColor(device, 320, 240);
1288 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1289 /* Some quad in the cleared part of the texture */
1290 color = getPixelColor(device, 170, 240);
1291 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1292 /* Part of the originally cleared back buffer */
1293 color = getPixelColor(device, 10, 10);
1294 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1295 if(0) {
1296 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1297 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1298 * the offscreen rendering mode this test would succeed or fail
1300 color = getPixelColor(device, 10, 470);
1301 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1304 out:
1305 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1307 /* restore things */
1308 if(backbuffer) {
1309 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1310 IDirect3DSurface9_Release(backbuffer);
1312 if(offscreenTexture) {
1313 IDirect3DTexture9_Release(offscreenTexture);
1315 if(offscreen) {
1316 IDirect3DSurface9_Release(offscreen);
1320 /* This test tests fog in combination with shaders.
1321 * What's tested: linear fog (vertex and table) with pixel shader
1322 * linear table fog with non foggy vertex shader
1323 * vertex fog with foggy vertex shader, non-linear
1324 * fog with shader, non-linear fog with foggy shader,
1325 * linear table fog with foggy shader
1327 static void fog_with_shader_test(IDirect3DDevice9 *device)
1329 HRESULT hr;
1330 DWORD color;
1331 union {
1332 float f;
1333 DWORD i;
1334 } start, end;
1335 unsigned int i, j;
1337 /* basic vertex shader without fog computation ("non foggy") */
1338 static const DWORD vertex_shader_code1[] = {
1339 0xfffe0101, /* vs_1_1 */
1340 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1341 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1342 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1343 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1344 0x0000ffff
1346 /* basic vertex shader with reversed fog computation ("foggy") */
1347 static const DWORD vertex_shader_code2[] = {
1348 0xfffe0101, /* vs_1_1 */
1349 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1350 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1351 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1352 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1353 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1354 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1355 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1356 0x0000ffff
1358 /* basic pixel shader */
1359 static const DWORD pixel_shader_code[] = {
1360 0xffff0101, /* ps_1_1 */
1361 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1362 0x0000ffff
1365 static struct vertex quad[] = {
1366 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1367 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1368 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1369 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1372 static const D3DVERTEXELEMENT9 decl_elements[] = {
1373 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1374 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1375 D3DDECL_END()
1378 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1379 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1380 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1382 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1383 static const struct test_data_t {
1384 int vshader;
1385 int pshader;
1386 D3DFOGMODE vfog;
1387 D3DFOGMODE tfog;
1388 unsigned int color[11];
1389 } test_data[] = {
1390 /* only pixel shader: */
1391 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1392 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1395 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1398 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1401 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1404 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1405 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407 /* vertex shader */
1408 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1409 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1410 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1411 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1412 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1415 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1419 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1422 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1423 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1425 /* vertex shader and pixel shader */
1426 /* The next 4 tests would read the fog coord output, but it isn't available.
1427 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1428 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1429 * These tests should be disabled if some other hardware behaves differently
1431 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1432 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1433 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1434 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1435 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1436 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1437 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1438 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1439 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1440 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1441 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1442 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1444 /* These use the Z coordinate with linear table fog */
1445 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1446 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1447 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1448 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1449 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1450 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1451 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1452 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1453 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1454 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1455 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1456 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1458 /* Non-linear table fog without fog coord */
1459 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1460 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1461 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1462 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1463 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1464 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1466 #if 0 /* FIXME: these fail on GeForce 8500 */
1467 /* foggy vertex shader */
1468 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1469 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1470 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1471 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1472 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1473 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1474 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1475 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1476 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1477 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1478 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1479 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1480 #endif
1482 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1483 * all using the fixed fog-coord linear fog
1485 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1486 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1487 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1488 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1489 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1490 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1491 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1492 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1493 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1494 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1495 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1496 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1498 /* These use table fog. Here the shader-provided fog coordinate is
1499 * ignored and the z coordinate used instead
1501 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1502 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1503 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1504 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1505 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1506 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1507 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1508 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1509 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1513 start.f=0.1f;
1514 end.f=0.9f;
1516 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1517 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1518 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1519 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1520 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1521 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1522 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1523 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1525 /* Setup initial states: No lighting, fog on, fog color */
1526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1527 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1529 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1531 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1532 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1533 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1536 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1538 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1540 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1542 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1544 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1546 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1548 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1549 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1550 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1551 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1553 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1555 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1557 for(j=0; j < 11; j++)
1559 /* Don't use the whole zrange to prevent rounding errors */
1560 quad[0].z = 0.001f + (float)j / 10.02f;
1561 quad[1].z = 0.001f + (float)j / 10.02f;
1562 quad[2].z = 0.001f + (float)j / 10.02f;
1563 quad[3].z = 0.001f + (float)j / 10.02f;
1565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1566 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1568 hr = IDirect3DDevice9_BeginScene(device);
1569 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1572 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1574 hr = IDirect3DDevice9_EndScene(device);
1575 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1577 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1579 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1580 color = getPixelColor(device, 128, 240);
1581 ok(color_match(color, test_data[i].color[j], 13),
1582 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1583 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1587 /* reset states */
1588 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1589 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1590 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1591 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1592 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1593 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1595 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1597 IDirect3DVertexShader9_Release(vertex_shader[1]);
1598 IDirect3DVertexShader9_Release(vertex_shader[2]);
1599 IDirect3DPixelShader9_Release(pixel_shader[1]);
1600 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1603 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1604 unsigned int i, x, y;
1605 HRESULT hr;
1606 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1607 D3DLOCKED_RECT locked_rect;
1609 /* Generate the textures */
1610 for(i=0; i<2; i++)
1612 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1613 D3DPOOL_MANAGED, &texture[i], NULL);
1614 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1616 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1617 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1618 for (y = 0; y < 128; ++y)
1620 if(i)
1621 { /* Set up black texture with 2x2 texel white spot in the middle */
1622 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1623 for (x = 0; x < 128; ++x)
1625 if(y>62 && y<66 && x>62 && x<66)
1626 *ptr++ = 0xffffffff;
1627 else
1628 *ptr++ = 0xff000000;
1631 else
1632 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1633 * (if multiplied with bumpenvmat)
1635 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1636 for (x = 0; x < 128; ++x)
1638 if(abs(x-64)>abs(y-64))
1640 if(x < 64)
1641 *ptr++ = 0xc000;
1642 else
1643 *ptr++ = 0x4000;
1645 else
1647 if(y < 64)
1648 *ptr++ = 0x0040;
1649 else
1650 *ptr++ = 0x00c0;
1655 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1656 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1658 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1659 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1661 /* Disable texture filtering */
1662 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1663 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1664 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1665 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1667 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1668 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1669 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1670 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1674 /* test the behavior of the texbem instruction
1675 * with normal 2D and projective 2D textures
1677 static void texbem_test(IDirect3DDevice9 *device)
1679 HRESULT hr;
1680 DWORD color;
1681 int i;
1683 static const DWORD pixel_shader_code[] = {
1684 0xffff0101, /* ps_1_1*/
1685 0x00000042, 0xb00f0000, /* tex t0*/
1686 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1687 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1688 0x0000ffff
1690 static const DWORD double_texbem_code[] = {
1691 0xffff0103, /* ps_1_3 */
1692 0x00000042, 0xb00f0000, /* tex t0 */
1693 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1694 0x00000042, 0xb00f0002, /* tex t2 */
1695 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1696 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1697 0x0000ffff /* end */
1701 static const float quad[][7] = {
1702 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1703 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1704 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1705 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1707 static const float quad_proj[][9] = {
1708 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1709 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1710 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1711 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1714 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1715 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1716 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1717 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1718 D3DDECL_END()
1720 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1721 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1722 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1723 D3DDECL_END()
1724 } };
1726 /* use asymmetric matrix to test loading */
1727 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1729 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1730 IDirect3DPixelShader9 *pixel_shader = NULL;
1731 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1732 D3DLOCKED_RECT locked_rect;
1734 generate_bumpmap_textures(device);
1736 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1737 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1738 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1739 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1740 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1742 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1743 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1748 for(i=0; i<2; i++)
1750 if(i)
1752 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1753 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1756 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1757 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1758 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1759 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1761 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1762 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1763 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1764 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1766 hr = IDirect3DDevice9_BeginScene(device);
1767 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1769 if(!i)
1770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1771 else
1772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1773 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1775 hr = IDirect3DDevice9_EndScene(device);
1776 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1779 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1781 color = getPixelColor(device, 320-32, 240);
1782 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783 color = getPixelColor(device, 320+32, 240);
1784 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1785 color = getPixelColor(device, 320, 240-32);
1786 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1787 color = getPixelColor(device, 320, 240+32);
1788 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1790 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1791 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1792 IDirect3DPixelShader9_Release(pixel_shader);
1794 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1795 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1796 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1799 /* clean up */
1800 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1801 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1803 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1804 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1806 for(i=0; i<2; i++)
1808 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1809 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1810 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1811 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1812 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1813 IDirect3DTexture9_Release(texture);
1816 /* Test double texbem */
1817 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1818 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1819 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1820 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1821 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1822 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1823 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1824 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1826 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1827 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1828 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1829 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1831 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1832 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1834 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1835 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1837 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1838 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1839 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1842 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1843 #define tex 0x00ff0000
1844 #define tex1 0x0000ff00
1845 #define origin 0x000000ff
1846 static const DWORD pixel_data[] = {
1847 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1848 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1851 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1852 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1853 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1854 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1856 #undef tex1
1857 #undef tex2
1858 #undef origin
1860 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1861 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1862 for(i = 0; i < 8; i++) {
1863 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1865 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1866 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1870 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1872 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1873 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1874 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1875 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1876 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1877 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1878 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1879 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1880 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1882 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1883 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1884 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1885 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1886 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1887 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1889 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1890 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1891 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1892 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1893 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1894 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1896 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1897 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1898 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1899 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1900 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1901 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1902 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1903 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1905 hr = IDirect3DDevice9_BeginScene(device);
1906 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1907 if(SUCCEEDED(hr)) {
1908 static const float double_quad[] = {
1909 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1910 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1911 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1912 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1915 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1916 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1917 hr = IDirect3DDevice9_EndScene(device);
1918 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1920 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1921 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1922 color = getPixelColor(device, 320, 240);
1923 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1925 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1929 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1930 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1931 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1932 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1933 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1934 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1936 IDirect3DPixelShader9_Release(pixel_shader);
1937 IDirect3DTexture9_Release(texture);
1938 IDirect3DTexture9_Release(texture1);
1939 IDirect3DTexture9_Release(texture2);
1942 static void z_range_test(IDirect3DDevice9 *device)
1944 const struct vertex quad[] =
1946 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1947 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1948 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1949 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1951 const struct vertex quad2[] =
1953 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1954 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1955 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1956 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1959 const struct tvertex quad3[] =
1961 { 0, 240, 1.1f, 1.0, 0xffffff00},
1962 { 0, 480, 1.1f, 1.0, 0xffffff00},
1963 { 640, 240, -1.1f, 1.0, 0xffffff00},
1964 { 640, 480, -1.1f, 1.0, 0xffffff00},
1966 const struct tvertex quad4[] =
1968 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1969 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1970 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1971 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1973 HRESULT hr;
1974 DWORD color;
1975 IDirect3DVertexShader9 *shader;
1976 IDirect3DVertexDeclaration9 *decl;
1977 D3DCAPS9 caps;
1978 const DWORD shader_code[] = {
1979 0xfffe0101, /* vs_1_1 */
1980 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1981 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1982 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1983 0x0000ffff /* end */
1985 static const D3DVERTEXELEMENT9 decl_elements[] = {
1986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1987 D3DDECL_END()
1989 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1990 * then call Present. Then clear the color buffer to make sure it has some defined content
1991 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1992 * by the depth value.
1994 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1995 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2000 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2002 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2004 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2006 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2007 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2008 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2010 hr = IDirect3DDevice9_BeginScene(device);
2011 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2012 if(hr == D3D_OK)
2014 /* Test the untransformed vertex path */
2015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2016 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2018 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2019 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2020 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2022 /* Test the transformed vertex path */
2023 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2024 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2027 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2028 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2029 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2031 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2033 hr = IDirect3DDevice9_EndScene(device);
2034 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2037 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2038 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2040 /* Do not test the exact corner pixels, but go pretty close to them */
2042 /* Clipped because z > 1.0 */
2043 color = getPixelColor(device, 28, 238);
2044 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2045 color = getPixelColor(device, 28, 241);
2046 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2048 /* Not clipped, > z buffer clear value(0.75) */
2049 color = getPixelColor(device, 31, 238);
2050 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2051 color = getPixelColor(device, 31, 241);
2052 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2053 color = getPixelColor(device, 100, 238);
2054 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2055 color = getPixelColor(device, 100, 241);
2056 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2058 /* Not clipped, < z buffer clear value */
2059 color = getPixelColor(device, 104, 238);
2060 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2061 color = getPixelColor(device, 104, 241);
2062 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2063 color = getPixelColor(device, 318, 238);
2064 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2065 color = getPixelColor(device, 318, 241);
2066 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2068 /* Clipped because z < 0.0 */
2069 color = getPixelColor(device, 321, 238);
2070 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2071 color = getPixelColor(device, 321, 241);
2072 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2074 /* Test the shader path */
2075 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2076 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2077 skip("Vertex shaders not supported\n");
2078 goto out;
2080 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2081 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2082 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2083 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2087 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2088 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2089 IDirect3DDevice9_SetVertexShader(device, shader);
2090 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2092 hr = IDirect3DDevice9_BeginScene(device);
2093 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2094 if(hr == D3D_OK)
2096 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2097 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2098 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2100 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2102 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2103 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2104 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2105 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2107 hr = IDirect3DDevice9_EndScene(device);
2108 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2111 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2112 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2113 IDirect3DDevice9_SetVertexShader(device, NULL);
2114 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2116 IDirect3DVertexDeclaration9_Release(decl);
2117 IDirect3DVertexShader9_Release(shader);
2119 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2121 /* Z < 1.0 */
2122 color = getPixelColor(device, 28, 238);
2123 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2125 /* 1.0 < z < 0.75 */
2126 color = getPixelColor(device, 31, 238);
2127 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2128 color = getPixelColor(device, 100, 238);
2129 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2131 /* 0.75 < z < 0.0 */
2132 color = getPixelColor(device, 104, 238);
2133 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2134 color = getPixelColor(device, 318, 238);
2135 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2137 /* 0.0 < z */
2138 color = getPixelColor(device, 321, 238);
2139 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2141 out:
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2147 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2150 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2152 D3DSURFACE_DESC desc;
2153 D3DLOCKED_RECT l;
2154 HRESULT hr;
2155 unsigned int x, y;
2156 DWORD *mem;
2158 memset(&desc, 0, sizeof(desc));
2159 memset(&l, 0, sizeof(l));
2160 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2161 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2162 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2163 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2164 if(FAILED(hr)) return;
2166 for(y = 0; y < desc.Height; y++)
2168 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2169 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2171 mem[x] = color;
2174 hr = IDirect3DSurface9_UnlockRect(surface);
2175 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2178 /* This tests a variety of possible StretchRect() situations */
2179 static void stretchrect_test(IDirect3DDevice9 *device)
2181 HRESULT hr;
2182 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2183 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2184 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2185 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2186 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2187 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2188 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2189 IDirect3DSurface9 *orig_rt = NULL;
2190 DWORD color;
2192 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2193 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2194 if(!orig_rt) {
2195 goto out;
2198 /* Create our temporary surfaces in system memory */
2199 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2200 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2201 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2204 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2205 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2207 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2209 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2210 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2212 /* Create render target surfaces */
2213 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2214 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2215 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2216 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2217 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2218 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2220 /* Create render target textures */
2221 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2222 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2223 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2224 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2225 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2226 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2227 if (tex_rt32) {
2228 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2229 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2231 if (tex_rt64) {
2232 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2233 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2235 if (tex_rt_dest64) {
2236 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2237 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2240 /* Create regular textures in D3DPOOL_DEFAULT */
2241 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2242 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2243 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2244 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2245 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2246 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2247 if (tex32) {
2248 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2249 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2251 if (tex64) {
2252 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2253 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2255 if (tex_dest64) {
2256 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2257 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2260 /*********************************************************************
2261 * Tests for when the source parameter is an offscreen plain surface *
2262 *********************************************************************/
2264 /* Fill the offscreen 64x64 surface with green */
2265 if (surf_offscreen64)
2266 fill_surface(surf_offscreen64, 0xff00ff00);
2268 /* offscreenplain ==> offscreenplain, same size */
2269 if(surf_offscreen64 && surf_offscreen_dest64) {
2270 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2271 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2273 if (hr == D3D_OK) {
2274 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2275 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2279 /* offscreenplain ==> rendertarget texture, same size */
2280 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2281 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2282 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2284 /* We can't lock rendertarget textures, so copy to our temp surface first */
2285 if (hr == D3D_OK) {
2286 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2287 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2290 if (hr == D3D_OK) {
2291 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2292 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2296 /* offscreenplain ==> rendertarget surface, same size */
2297 if(surf_offscreen64 && surf_rt_dest64) {
2298 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2299 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2301 if (hr == D3D_OK) {
2302 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2303 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2307 /* offscreenplain ==> texture, same size (should fail) */
2308 if(surf_offscreen64 && surf_tex_dest64) {
2309 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2310 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2313 /* Fill the smaller offscreen surface with red */
2314 fill_surface(surf_offscreen32, 0xffff0000);
2316 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2317 if(surf_offscreen32 && surf_offscreen64) {
2318 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2319 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2322 /* offscreenplain ==> rendertarget texture, scaling */
2323 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2324 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2325 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2327 /* We can't lock rendertarget textures, so copy to our temp surface first */
2328 if (hr == D3D_OK) {
2329 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2330 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2333 if (hr == D3D_OK) {
2334 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2335 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2339 /* offscreenplain ==> rendertarget surface, scaling */
2340 if(surf_offscreen32 && surf_rt_dest64) {
2341 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2342 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2344 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2345 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2348 /* offscreenplain ==> texture, scaling (should fail) */
2349 if(surf_offscreen32 && surf_tex_dest64) {
2350 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2351 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2354 /************************************************************
2355 * Tests for when the source parameter is a regular texture *
2356 ************************************************************/
2358 /* Fill the surface of the regular texture with blue */
2359 if (surf_tex64 && surf_temp64) {
2360 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2361 fill_surface(surf_temp64, 0xff0000ff);
2362 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2363 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2366 /* texture ==> offscreenplain, same size */
2367 if(surf_tex64 && surf_offscreen64) {
2368 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2369 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2372 /* texture ==> rendertarget texture, same size */
2373 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2374 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2375 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2377 /* We can't lock rendertarget textures, so copy to our temp surface first */
2378 if (hr == D3D_OK) {
2379 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2380 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2383 if (hr == D3D_OK) {
2384 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2385 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2389 /* texture ==> rendertarget surface, same size */
2390 if(surf_tex64 && surf_rt_dest64) {
2391 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2392 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2394 if (hr == D3D_OK) {
2395 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2396 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2400 /* texture ==> texture, same size (should fail) */
2401 if(surf_tex64 && surf_tex_dest64) {
2402 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2403 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2406 /* Fill the surface of the smaller regular texture with red */
2407 if (surf_tex32 && surf_temp32) {
2408 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2409 fill_surface(surf_temp32, 0xffff0000);
2410 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2411 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2414 /* texture ==> offscreenplain, scaling (should fail) */
2415 if(surf_tex32 && surf_offscreen64) {
2416 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2417 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2420 /* texture ==> rendertarget texture, scaling */
2421 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2422 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2423 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425 /* We can't lock rendertarget textures, so copy to our temp surface first */
2426 if (hr == D3D_OK) {
2427 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2428 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2431 if (hr == D3D_OK) {
2432 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2433 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2437 /* texture ==> rendertarget surface, scaling */
2438 if(surf_tex32 && surf_rt_dest64) {
2439 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2440 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2442 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2443 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2446 /* texture ==> texture, scaling (should fail) */
2447 if(surf_tex32 && surf_tex_dest64) {
2448 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2449 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2452 /*****************************************************************
2453 * Tests for when the source parameter is a rendertarget texture *
2454 *****************************************************************/
2456 /* Fill the surface of the rendertarget texture with white */
2457 if (surf_tex_rt64 && surf_temp64) {
2458 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2459 fill_surface(surf_temp64, 0xffffffff);
2460 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2461 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2464 /* rendertarget texture ==> offscreenplain, same size */
2465 if(surf_tex_rt64 && surf_offscreen64) {
2466 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2467 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2470 /* rendertarget texture ==> rendertarget texture, same size */
2471 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2472 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2473 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2475 /* We can't lock rendertarget textures, so copy to our temp surface first */
2476 if (hr == D3D_OK) {
2477 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2478 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2481 if (hr == D3D_OK) {
2482 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2483 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2487 /* rendertarget texture ==> rendertarget surface, same size */
2488 if(surf_tex_rt64 && surf_rt_dest64) {
2489 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2490 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2492 if (hr == D3D_OK) {
2493 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2494 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2498 /* rendertarget texture ==> texture, same size (should fail) */
2499 if(surf_tex_rt64 && surf_tex_dest64) {
2500 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2501 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2504 /* Fill the surface of the smaller rendertarget texture with red */
2505 if (surf_tex_rt32 && surf_temp32) {
2506 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2507 fill_surface(surf_temp32, 0xffff0000);
2508 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2509 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2512 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2513 if(surf_tex_rt32 && surf_offscreen64) {
2514 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2515 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2518 /* rendertarget texture ==> rendertarget texture, scaling */
2519 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2520 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2521 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2523 /* We can't lock rendertarget textures, so copy to our temp surface first */
2524 if (hr == D3D_OK) {
2525 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2526 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2529 if (hr == D3D_OK) {
2530 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2531 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2535 /* rendertarget texture ==> rendertarget surface, scaling */
2536 if(surf_tex_rt32 && surf_rt_dest64) {
2537 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2538 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2540 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2541 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2544 /* rendertarget texture ==> texture, scaling (should fail) */
2545 if(surf_tex_rt32 && surf_tex_dest64) {
2546 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2547 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2550 /*****************************************************************
2551 * Tests for when the source parameter is a rendertarget surface *
2552 *****************************************************************/
2554 /* Fill the surface of the rendertarget surface with black */
2555 if (surf_rt64)
2556 fill_surface(surf_rt64, 0xff000000);
2558 /* rendertarget texture ==> offscreenplain, same size */
2559 if(surf_rt64 && surf_offscreen64) {
2560 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2561 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2564 /* rendertarget surface ==> rendertarget texture, same size */
2565 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2566 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2567 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2569 /* We can't lock rendertarget textures, so copy to our temp surface first */
2570 if (hr == D3D_OK) {
2571 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2572 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2575 if (hr == D3D_OK) {
2576 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2577 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2581 /* rendertarget surface ==> rendertarget surface, same size */
2582 if(surf_rt64 && surf_rt_dest64) {
2583 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2584 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2586 if (hr == D3D_OK) {
2587 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2588 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2592 /* rendertarget surface ==> texture, same size (should fail) */
2593 if(surf_rt64 && surf_tex_dest64) {
2594 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2595 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2598 /* Fill the surface of the smaller rendertarget texture with red */
2599 if (surf_rt32)
2600 fill_surface(surf_rt32, 0xffff0000);
2602 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2603 if(surf_rt32 && surf_offscreen64) {
2604 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2605 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2608 /* rendertarget surface ==> rendertarget texture, scaling */
2609 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2610 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2611 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2613 /* We can't lock rendertarget textures, so copy to our temp surface first */
2614 if (hr == D3D_OK) {
2615 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2616 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2619 if (hr == D3D_OK) {
2620 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2621 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2625 /* rendertarget surface ==> rendertarget surface, scaling */
2626 if(surf_rt32 && surf_rt_dest64) {
2627 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2628 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2630 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2631 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634 /* rendertarget surface ==> texture, scaling (should fail) */
2635 if(surf_rt32 && surf_tex_dest64) {
2636 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2637 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2640 /* TODO: Test when source and destination RECT parameters are given... */
2641 /* TODO: Test format conversions */
2644 out:
2645 /* Clean up */
2646 if (surf_rt32)
2647 IDirect3DSurface9_Release(surf_rt32);
2648 if (surf_rt64)
2649 IDirect3DSurface9_Release(surf_rt64);
2650 if (surf_rt_dest64)
2651 IDirect3DSurface9_Release(surf_rt_dest64);
2652 if (surf_temp32)
2653 IDirect3DSurface9_Release(surf_temp32);
2654 if (surf_temp64)
2655 IDirect3DSurface9_Release(surf_temp64);
2656 if (surf_offscreen32)
2657 IDirect3DSurface9_Release(surf_offscreen32);
2658 if (surf_offscreen64)
2659 IDirect3DSurface9_Release(surf_offscreen64);
2660 if (surf_offscreen_dest64)
2661 IDirect3DSurface9_Release(surf_offscreen_dest64);
2663 if (tex_rt32) {
2664 if (surf_tex_rt32)
2665 IDirect3DSurface9_Release(surf_tex_rt32);
2666 IDirect3DTexture9_Release(tex_rt32);
2668 if (tex_rt64) {
2669 if (surf_tex_rt64)
2670 IDirect3DSurface9_Release(surf_tex_rt64);
2671 IDirect3DTexture9_Release(tex_rt64);
2673 if (tex_rt_dest64) {
2674 if (surf_tex_rt_dest64)
2675 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2676 IDirect3DTexture9_Release(tex_rt_dest64);
2678 if (tex32) {
2679 if (surf_tex32)
2680 IDirect3DSurface9_Release(surf_tex32);
2681 IDirect3DTexture9_Release(tex32);
2683 if (tex64) {
2684 if (surf_tex64)
2685 IDirect3DSurface9_Release(surf_tex64);
2686 IDirect3DTexture9_Release(tex64);
2688 if (tex_dest64) {
2689 if (surf_tex_dest64)
2690 IDirect3DSurface9_Release(surf_tex_dest64);
2691 IDirect3DTexture9_Release(tex_dest64);
2694 if (orig_rt) {
2695 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2696 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2697 IDirect3DSurface9_Release(orig_rt);
2701 static void maxmip_test(IDirect3DDevice9 *device)
2703 IDirect3DTexture9 *texture = NULL;
2704 IDirect3DSurface9 *surface = NULL;
2705 HRESULT hr;
2706 DWORD color;
2707 const float quads[] = {
2708 -1.0, -1.0, 0.0, 0.0, 0.0,
2709 -1.0, 0.0, 0.0, 0.0, 1.0,
2710 0.0, -1.0, 0.0, 1.0, 0.0,
2711 0.0, 0.0, 0.0, 1.0, 1.0,
2713 0.0, -1.0, 0.0, 0.0, 0.0,
2714 0.0, 0.0, 0.0, 0.0, 1.0,
2715 1.0, -1.0, 0.0, 1.0, 0.0,
2716 1.0, 0.0, 0.0, 1.0, 1.0,
2718 0.0, 0.0, 0.0, 0.0, 0.0,
2719 0.0, 1.0, 0.0, 0.0, 1.0,
2720 1.0, 0.0, 0.0, 1.0, 0.0,
2721 1.0, 1.0, 0.0, 1.0, 1.0,
2723 -1.0, 0.0, 0.0, 0.0, 0.0,
2724 -1.0, 1.0, 0.0, 0.0, 1.0,
2725 0.0, 0.0, 0.0, 1.0, 0.0,
2726 0.0, 1.0, 0.0, 1.0, 1.0,
2729 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2730 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2732 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2733 &texture, NULL);
2734 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2735 if(!texture)
2737 skip("Failed to create test texture\n");
2738 return;
2741 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2742 fill_surface(surface, 0xffff0000);
2743 IDirect3DSurface9_Release(surface);
2744 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2745 fill_surface(surface, 0xff00ff00);
2746 IDirect3DSurface9_Release(surface);
2747 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2748 fill_surface(surface, 0xff0000ff);
2749 IDirect3DSurface9_Release(surface);
2751 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2752 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2753 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2754 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2757 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2759 hr = IDirect3DDevice9_BeginScene(device);
2760 if(SUCCEEDED(hr))
2762 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2763 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2764 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2765 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2767 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2768 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2770 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2772 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2773 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2775 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2777 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2778 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2781 hr = IDirect3DDevice9_EndScene(device);
2784 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2785 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2786 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2787 color = getPixelColor(device, 160, 360);
2788 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2789 color = getPixelColor(device, 160, 120);
2790 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2791 color = getPixelColor(device, 480, 120);
2792 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2793 color = getPixelColor(device, 480, 360);
2794 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2797 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2799 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2800 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2802 hr = IDirect3DDevice9_BeginScene(device);
2803 if(SUCCEEDED(hr))
2805 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2806 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2808 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2810 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2811 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2813 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2815 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2816 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2818 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2820 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2821 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2823 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2824 hr = IDirect3DDevice9_EndScene(device);
2827 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2828 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2829 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2830 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2832 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2833 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2834 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2835 * samples from the highest level in the texture(level 2)
2837 color = getPixelColor(device, 160, 360);
2838 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2839 color = getPixelColor(device, 160, 120);
2840 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2841 color = getPixelColor(device, 480, 120);
2842 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2843 color = getPixelColor(device, 480, 360);
2844 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2846 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2847 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2848 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2849 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2850 IDirect3DTexture9_Release(texture);
2853 static void release_buffer_test(IDirect3DDevice9 *device)
2855 IDirect3DVertexBuffer9 *vb = NULL;
2856 IDirect3DIndexBuffer9 *ib = NULL;
2857 HRESULT hr;
2858 BYTE *data;
2859 LONG ref;
2861 static const struct vertex quad[] = {
2862 {-1.0, -1.0, 0.1, 0xffff0000},
2863 {-1.0, 1.0, 0.1, 0xffff0000},
2864 { 1.0, 1.0, 0.1, 0xffff0000},
2866 {-1.0, -1.0, 0.1, 0xff00ff00},
2867 {-1.0, 1.0, 0.1, 0xff00ff00},
2868 { 1.0, 1.0, 0.1, 0xff00ff00}
2870 short indices[] = {3, 4, 5};
2872 /* Index and vertex buffers should always be creatable */
2873 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2874 D3DPOOL_MANAGED, &vb, NULL);
2875 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2876 if(!vb) {
2877 skip("Failed to create a vertex buffer\n");
2878 return;
2880 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2881 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2882 if(!ib) {
2883 skip("Failed to create an index buffer\n");
2884 return;
2887 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2888 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2889 memcpy(data, quad, sizeof(quad));
2890 hr = IDirect3DVertexBuffer9_Unlock(vb);
2891 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2893 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2894 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2895 memcpy(data, indices, sizeof(indices));
2896 hr = IDirect3DIndexBuffer9_Unlock(ib);
2897 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2899 hr = IDirect3DDevice9_SetIndices(device, ib);
2900 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2901 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2902 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2903 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2904 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2906 /* Now destroy the bound index buffer and draw again */
2907 ref = IDirect3DIndexBuffer9_Release(ib);
2908 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2911 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2913 hr = IDirect3DDevice9_BeginScene(device);
2914 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2915 if(SUCCEEDED(hr))
2917 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2918 * making assumptions about the indices or vertices
2920 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2921 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2922 hr = IDirect3DDevice9_EndScene(device);
2923 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2927 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2929 hr = IDirect3DDevice9_SetIndices(device, NULL);
2930 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2931 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2932 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2934 /* Index buffer was already destroyed as part of the test */
2935 IDirect3DVertexBuffer9_Release(vb);
2938 static void float_texture_test(IDirect3DDevice9 *device)
2940 IDirect3D9 *d3d = NULL;
2941 HRESULT hr;
2942 IDirect3DTexture9 *texture = NULL;
2943 D3DLOCKED_RECT lr;
2944 float *data;
2945 DWORD color;
2946 float quad[] = {
2947 -1.0, -1.0, 0.1, 0.0, 0.0,
2948 -1.0, 1.0, 0.1, 0.0, 1.0,
2949 1.0, -1.0, 0.1, 1.0, 0.0,
2950 1.0, 1.0, 0.1, 1.0, 1.0,
2953 memset(&lr, 0, sizeof(lr));
2954 IDirect3DDevice9_GetDirect3D(device, &d3d);
2955 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2956 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2957 skip("D3DFMT_R32F textures not supported\n");
2958 goto out;
2961 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2962 D3DPOOL_MANAGED, &texture, NULL);
2963 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2964 if(!texture) {
2965 skip("Failed to create R32F texture\n");
2966 goto out;
2969 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2970 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2971 data = lr.pBits;
2972 *data = 0.0;
2973 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2974 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2976 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2979 hr = IDirect3DDevice9_BeginScene(device);
2980 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2981 if(SUCCEEDED(hr))
2983 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2984 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2987 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2989 hr = IDirect3DDevice9_EndScene(device);
2990 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2992 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2993 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2995 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2996 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2998 color = getPixelColor(device, 240, 320);
2999 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3001 out:
3002 if(texture) IDirect3DTexture9_Release(texture);
3003 IDirect3D9_Release(d3d);
3006 static void g16r16_texture_test(IDirect3DDevice9 *device)
3008 IDirect3D9 *d3d = NULL;
3009 HRESULT hr;
3010 IDirect3DTexture9 *texture = NULL;
3011 D3DLOCKED_RECT lr;
3012 DWORD *data;
3013 DWORD color, red, green, blue;
3014 float quad[] = {
3015 -1.0, -1.0, 0.1, 0.0, 0.0,
3016 -1.0, 1.0, 0.1, 0.0, 1.0,
3017 1.0, -1.0, 0.1, 1.0, 0.0,
3018 1.0, 1.0, 0.1, 1.0, 1.0,
3021 memset(&lr, 0, sizeof(lr));
3022 IDirect3DDevice9_GetDirect3D(device, &d3d);
3023 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3024 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3025 skip("D3DFMT_G16R16 textures not supported\n");
3026 goto out;
3029 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3030 D3DPOOL_MANAGED, &texture, NULL);
3031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3032 if(!texture) {
3033 skip("Failed to create D3DFMT_G16R16 texture\n");
3034 goto out;
3037 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3038 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3039 data = lr.pBits;
3040 *data = 0x0f00f000;
3041 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3042 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3044 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3045 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3047 hr = IDirect3DDevice9_BeginScene(device);
3048 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3049 if(SUCCEEDED(hr))
3051 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3052 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3055 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3057 hr = IDirect3DDevice9_EndScene(device);
3058 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3060 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3061 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3063 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3064 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3066 color = getPixelColor(device, 240, 320);
3067 red = (color & 0x00ff0000) >> 16;
3068 green = (color & 0x0000ff00) >> 8;
3069 blue = (color & 0x000000ff) >> 0;
3070 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3071 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3073 out:
3074 if(texture) IDirect3DTexture9_Release(texture);
3075 IDirect3D9_Release(d3d);
3078 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3080 HRESULT hr;
3081 IDirect3D9 *d3d;
3082 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3083 D3DCAPS9 caps;
3084 IDirect3DTexture9 *texture = NULL;
3085 IDirect3DVolumeTexture9 *volume = NULL;
3086 unsigned int x, y, z;
3087 D3DLOCKED_RECT lr;
3088 D3DLOCKED_BOX lb;
3089 DWORD color;
3090 UINT w, h;
3091 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3092 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3093 0.0, 1.0, 0.0, 0.0,
3094 0.0, 0.0, 1.0, 0.0,
3095 0.0, 0.0, 0.0, 1.0};
3096 static const D3DVERTEXELEMENT9 decl_elements[] = {
3097 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3098 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3099 D3DDECL_END()
3101 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3102 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3103 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3104 D3DDECL_END()
3106 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3107 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3108 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3109 D3DDECL_END()
3111 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3112 0x00, 0xff, 0x00, 0x00,
3113 0x00, 0x00, 0x00, 0x00,
3114 0x00, 0x00, 0x00, 0x00};
3116 memset(&lr, 0, sizeof(lr));
3117 memset(&lb, 0, sizeof(lb));
3118 IDirect3DDevice9_GetDirect3D(device, &d3d);
3119 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3120 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3121 fmt = D3DFMT_A16B16G16R16;
3123 IDirect3D9_Release(d3d);
3125 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3126 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3127 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3128 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3129 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3130 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3131 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3133 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3134 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3135 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3136 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3137 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3138 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3139 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3140 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3141 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3143 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3148 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3150 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3151 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3152 w = min(1024, caps.MaxTextureWidth);
3153 h = min(1024, caps.MaxTextureHeight);
3154 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3155 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3156 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3157 if(!texture) {
3158 skip("Failed to create the test texture\n");
3159 return;
3162 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3163 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3164 * 1.0 in red and green for the x and y coords
3166 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3167 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3168 for(y = 0; y < h; y++) {
3169 for(x = 0; x < w; x++) {
3170 double r_f = (double) y / (double) h;
3171 double g_f = (double) x / (double) w;
3172 if(fmt == D3DFMT_A16B16G16R16) {
3173 unsigned short r, g;
3174 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3175 r = (unsigned short) (r_f * 65536.0);
3176 g = (unsigned short) (g_f * 65536.0);
3177 dst[0] = r;
3178 dst[1] = g;
3179 dst[2] = 0;
3180 dst[3] = 65535;
3181 } else {
3182 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3183 unsigned char r = (unsigned char) (r_f * 255.0);
3184 unsigned char g = (unsigned char) (g_f * 255.0);
3185 dst[0] = 0;
3186 dst[1] = g;
3187 dst[2] = r;
3188 dst[3] = 255;
3192 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3193 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3194 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3197 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3198 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3199 hr = IDirect3DDevice9_BeginScene(device);
3200 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3201 if(SUCCEEDED(hr))
3203 float quad1[] = {
3204 -1.0, -1.0, 0.1, 1.0, 1.0,
3205 -1.0, 0.0, 0.1, 1.0, 1.0,
3206 0.0, -1.0, 0.1, 1.0, 1.0,
3207 0.0, 0.0, 0.1, 1.0, 1.0,
3209 float quad2[] = {
3210 -1.0, 0.0, 0.1, 1.0, 1.0,
3211 -1.0, 1.0, 0.1, 1.0, 1.0,
3212 0.0, 0.0, 0.1, 1.0, 1.0,
3213 0.0, 1.0, 0.1, 1.0, 1.0,
3215 float quad3[] = {
3216 0.0, 0.0, 0.1, 0.5, 0.5,
3217 0.0, 1.0, 0.1, 0.5, 0.5,
3218 1.0, 0.0, 0.1, 0.5, 0.5,
3219 1.0, 1.0, 0.1, 0.5, 0.5,
3221 float quad4[] = {
3222 320, 480, 0.1, 1.0, 0.0, 1.0,
3223 320, 240, 0.1, 1.0, 0.0, 1.0,
3224 640, 480, 0.1, 1.0, 0.0, 1.0,
3225 640, 240, 0.1, 1.0, 0.0, 1.0,
3227 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3228 0.0, 0.0, 0.0, 0.0,
3229 0.0, 0.0, 0.0, 0.0,
3230 0.0, 0.0, 0.0, 0.0};
3232 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3233 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3234 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3236 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3238 /* What happens with transforms enabled? */
3239 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3240 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3241 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3242 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3244 /* What happens if 4 coords are used, but only 2 given ?*/
3245 mat[8] = 1.0;
3246 mat[13] = 1.0;
3247 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3248 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3249 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3251 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3252 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3254 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3255 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3256 * due to the coords in the vertices. (turns out red, indeed)
3258 memset(mat, 0, sizeof(mat));
3259 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3260 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3261 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3262 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3264 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3266 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3268 hr = IDirect3DDevice9_EndScene(device);
3269 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3271 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3272 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3273 color = getPixelColor(device, 160, 360);
3274 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3275 color = getPixelColor(device, 160, 120);
3276 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3277 color = getPixelColor(device, 480, 120);
3278 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3279 color = getPixelColor(device, 480, 360);
3280 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3283 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3285 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3286 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3287 hr = IDirect3DDevice9_BeginScene(device);
3288 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3289 if(SUCCEEDED(hr))
3291 float quad1[] = {
3292 -1.0, -1.0, 0.1, 0.8, 0.2,
3293 -1.0, 0.0, 0.1, 0.8, 0.2,
3294 0.0, -1.0, 0.1, 0.8, 0.2,
3295 0.0, 0.0, 0.1, 0.8, 0.2,
3297 float quad2[] = {
3298 -1.0, 0.0, 0.1, 0.5, 1.0,
3299 -1.0, 1.0, 0.1, 0.5, 1.0,
3300 0.0, 0.0, 0.1, 0.5, 1.0,
3301 0.0, 1.0, 0.1, 0.5, 1.0,
3303 float quad3[] = {
3304 0.0, 0.0, 0.1, 0.5, 1.0,
3305 0.0, 1.0, 0.1, 0.5, 1.0,
3306 1.0, 0.0, 0.1, 0.5, 1.0,
3307 1.0, 1.0, 0.1, 0.5, 1.0,
3309 float quad4[] = {
3310 0.0, -1.0, 0.1, 0.8, 0.2,
3311 0.0, 0.0, 0.1, 0.8, 0.2,
3312 1.0, -1.0, 0.1, 0.8, 0.2,
3313 1.0, 0.0, 0.1, 0.8, 0.2,
3315 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3316 0.0, 0.0, 0.0, 0.0,
3317 0.0, 1.0, 0.0, 0.0,
3318 0.0, 0.0, 0.0, 0.0};
3320 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3322 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3323 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3324 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3325 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3328 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3330 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3331 * it behaves like COUNT2 because normal textures require 2 coords
3333 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3334 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3336 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3338 /* Just to be sure, the same as quad2 above */
3339 memset(mat, 0, sizeof(mat));
3340 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3341 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3342 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3343 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3345 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3347 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3348 * used? And what happens to the first?
3350 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3351 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3353 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3355 hr = IDirect3DDevice9_EndScene(device);
3356 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3359 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3360 color = getPixelColor(device, 160, 360);
3361 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3362 color = getPixelColor(device, 160, 120);
3363 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3364 color = getPixelColor(device, 480, 120);
3365 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3366 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3367 color = getPixelColor(device, 480, 360);
3368 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3369 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3371 IDirect3DTexture9_Release(texture);
3373 /* Test projected textures, without any fancy matrices */
3374 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3375 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3376 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3377 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3378 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3379 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3380 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3381 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3383 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3384 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3385 for(x = 0; x < 4; x++) {
3386 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3388 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3389 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3390 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3391 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3393 hr = IDirect3DDevice9_BeginScene(device);
3394 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3395 if(SUCCEEDED(hr))
3397 const float proj_quads[] = {
3398 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3399 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3400 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3401 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3402 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3403 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3404 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3405 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3408 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3409 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3411 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3413 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3414 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3416 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3418 hr = IDirect3DDevice9_EndScene(device);
3419 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3422 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3424 IDirect3DTexture9_Release(texture);
3426 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3427 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3428 color = getPixelColor(device, 158, 118);
3429 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3430 color = getPixelColor(device, 162, 118);
3431 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3432 color = getPixelColor(device, 158, 122);
3433 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3434 color = getPixelColor(device, 162, 122);
3435 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3437 color = getPixelColor(device, 158, 178);
3438 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3439 color = getPixelColor(device, 162, 178);
3440 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3441 color = getPixelColor(device, 158, 182);
3442 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3443 color = getPixelColor(device, 162, 182);
3444 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3446 color = getPixelColor(device, 318, 118);
3447 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3448 color = getPixelColor(device, 322, 118);
3449 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3450 color = getPixelColor(device, 318, 122);
3451 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3452 color = getPixelColor(device, 322, 122);
3453 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3455 color = getPixelColor(device, 318, 178);
3456 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3457 color = getPixelColor(device, 322, 178);
3458 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3459 color = getPixelColor(device, 318, 182);
3460 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3461 color = getPixelColor(device, 322, 182);
3462 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3464 color = getPixelColor(device, 238, 298);
3465 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3466 color = getPixelColor(device, 242, 298);
3467 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3468 color = getPixelColor(device, 238, 302);
3469 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3470 color = getPixelColor(device, 242, 302);
3471 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3473 color = getPixelColor(device, 238, 388);
3474 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3475 color = getPixelColor(device, 242, 388);
3476 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3477 color = getPixelColor(device, 238, 392);
3478 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3479 color = getPixelColor(device, 242, 392);
3480 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3482 color = getPixelColor(device, 478, 298);
3483 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3484 color = getPixelColor(device, 482, 298);
3485 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3486 color = getPixelColor(device, 478, 302);
3487 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3488 color = getPixelColor(device, 482, 302);
3489 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3491 color = getPixelColor(device, 478, 388);
3492 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3493 color = getPixelColor(device, 482, 388);
3494 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3495 color = getPixelColor(device, 478, 392);
3496 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3497 color = getPixelColor(device, 482, 392);
3498 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3500 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3502 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3503 * Thus watch out if sampling from texels between 0 and 1.
3505 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3506 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3507 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3508 if(!volume) {
3509 skip("Failed to create a volume texture\n");
3510 goto out;
3513 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3514 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3515 for(z = 0; z < 32; z++) {
3516 for(y = 0; y < 32; y++) {
3517 for(x = 0; x < 32; x++) {
3518 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3519 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3520 float r_f = (float) x / 31.0;
3521 float g_f = (float) y / 31.0;
3522 float b_f = (float) z / 31.0;
3524 if(fmt == D3DFMT_A16B16G16R16) {
3525 unsigned short *mem_s = mem;
3526 mem_s[0] = r_f * 65535.0;
3527 mem_s[1] = g_f * 65535.0;
3528 mem_s[2] = b_f * 65535.0;
3529 mem_s[3] = 65535;
3530 } else {
3531 unsigned char *mem_c = mem;
3532 mem_c[0] = b_f * 255.0;
3533 mem_c[1] = g_f * 255.0;
3534 mem_c[2] = r_f * 255.0;
3535 mem_c[3] = 255;
3540 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3541 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3543 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3544 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3546 hr = IDirect3DDevice9_BeginScene(device);
3547 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3548 if(SUCCEEDED(hr))
3550 float quad1[] = {
3551 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3552 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3553 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3554 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3556 float quad2[] = {
3557 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3558 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3559 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3560 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3562 float quad3[] = {
3563 0.0, 0.0, 0.1, 0.0, 0.0,
3564 0.0, 1.0, 0.1, 0.0, 0.0,
3565 1.0, 0.0, 0.1, 0.0, 0.0,
3566 1.0, 1.0, 0.1, 0.0, 0.0
3568 float quad4[] = {
3569 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3570 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3571 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3572 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3574 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3575 0.0, 0.0, 1.0, 0.0,
3576 0.0, 1.0, 0.0, 0.0,
3577 0.0, 0.0, 0.0, 1.0};
3578 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3581 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3582 * values
3584 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3585 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3587 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3589 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3591 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3592 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3593 * otherwise the w will be missing(blue).
3594 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3595 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3597 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3598 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3600 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3602 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3603 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3604 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3605 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3606 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3607 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3608 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3610 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3612 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3613 * disable. ATI extends it up to the amount of values needed for the volume texture
3615 memset(mat, 0, sizeof(mat));
3616 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3617 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3618 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3619 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3620 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3621 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3623 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3625 hr = IDirect3DDevice9_EndScene(device);
3626 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3628 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3629 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3631 color = getPixelColor(device, 160, 360);
3632 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3633 color = getPixelColor(device, 160, 120);
3634 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3635 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3636 color = getPixelColor(device, 480, 120);
3637 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3638 color = getPixelColor(device, 480, 360);
3639 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3642 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3643 hr = IDirect3DDevice9_BeginScene(device);
3644 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3645 if(SUCCEEDED(hr))
3647 float quad1[] = {
3648 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3649 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3650 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3651 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3653 float quad2[] = {
3654 -1.0, 0.0, 0.1,
3655 -1.0, 1.0, 0.1,
3656 0.0, 0.0, 0.1,
3657 0.0, 1.0, 0.1,
3659 float quad3[] = {
3660 0.0, 0.0, 0.1, 1.0,
3661 0.0, 1.0, 0.1, 1.0,
3662 1.0, 0.0, 0.1, 1.0,
3663 1.0, 1.0, 0.1, 1.0
3665 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3666 0.0, 0.0, 0.0, 0.0,
3667 0.0, 0.0, 0.0, 0.0,
3668 0.0, 1.0, 0.0, 0.0};
3669 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3670 1.0, 0.0, 0.0, 0.0,
3671 0.0, 1.0, 0.0, 0.0,
3672 0.0, 0.0, 1.0, 0.0};
3673 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3676 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3678 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3679 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3680 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3681 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3683 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3685 /* None passed */
3686 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3687 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3688 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3689 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3690 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3691 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3693 /* 4 used, 1 passed */
3694 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3695 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3696 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3697 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3698 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3699 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3701 hr = IDirect3DDevice9_EndScene(device);
3702 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3704 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3705 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3706 color = getPixelColor(device, 160, 360);
3707 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3708 color = getPixelColor(device, 160, 120);
3709 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3710 color = getPixelColor(device, 480, 120);
3711 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3712 /* Quad4: unused */
3714 IDirect3DVolumeTexture9_Release(volume);
3716 out:
3717 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3719 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3720 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3721 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3722 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3723 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3724 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3725 IDirect3DVertexDeclaration9_Release(decl);
3726 IDirect3DVertexDeclaration9_Release(decl2);
3727 IDirect3DVertexDeclaration9_Release(decl3);
3730 static void texdepth_test(IDirect3DDevice9 *device)
3732 IDirect3DPixelShader9 *shader;
3733 HRESULT hr;
3734 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3735 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3736 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3737 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3738 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3739 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3740 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3741 DWORD shader_code[] = {
3742 0xffff0104, /* ps_1_4 */
3743 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3744 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3745 0x0000fffd, /* phase */
3746 0x00000057, 0x800f0005, /* texdepth r5 */
3747 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3748 0x0000ffff /* end */
3750 DWORD color;
3751 float vertex[] = {
3752 -1.0, -1.0, 0.0,
3753 1.0, -1.0, 1.0,
3754 -1.0, 1.0, 0.0,
3755 1.0, 1.0, 1.0
3758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3759 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3762 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3764 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3767 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3768 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3769 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3771 /* Fill the depth buffer with a gradient */
3772 hr = IDirect3DDevice9_BeginScene(device);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3774 if(SUCCEEDED(hr))
3776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3777 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3778 hr = IDirect3DDevice9_EndScene(device);
3779 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3782 /* Now perform the actual tests. Same geometry, but with the shader */
3783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3784 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3786 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3787 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3790 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3791 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3792 hr = IDirect3DDevice9_BeginScene(device);
3793 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3794 if(SUCCEEDED(hr))
3796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3797 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3799 hr = IDirect3DDevice9_EndScene(device);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3803 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3804 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3805 color = getPixelColor(device, 158, 240);
3806 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3807 color = getPixelColor(device, 162, 240);
3808 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3812 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3813 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3814 hr = IDirect3DDevice9_BeginScene(device);
3815 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3816 if(SUCCEEDED(hr))
3818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3819 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3821 hr = IDirect3DDevice9_EndScene(device);
3822 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3825 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3826 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3827 color = getPixelColor(device, 318, 240);
3828 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3829 color = getPixelColor(device, 322, 240);
3830 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3832 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3834 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3835 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3836 hr = IDirect3DDevice9_BeginScene(device);
3837 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3838 if(SUCCEEDED(hr))
3840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3841 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3843 hr = IDirect3DDevice9_EndScene(device);
3844 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3846 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3847 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3849 color = getPixelColor(device, 1, 240);
3850 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3854 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3855 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3856 hr = IDirect3DDevice9_BeginScene(device);
3857 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3858 if(SUCCEEDED(hr))
3860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3861 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3863 hr = IDirect3DDevice9_EndScene(device);
3864 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3866 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3867 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3868 color = getPixelColor(device, 318, 240);
3869 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3870 color = getPixelColor(device, 322, 240);
3871 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3873 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3875 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3876 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3877 hr = IDirect3DDevice9_BeginScene(device);
3878 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3879 if(SUCCEEDED(hr))
3881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3882 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3884 hr = IDirect3DDevice9_EndScene(device);
3885 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3888 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3890 color = getPixelColor(device, 1, 240);
3891 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3895 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3896 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3897 hr = IDirect3DDevice9_BeginScene(device);
3898 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3899 if(SUCCEEDED(hr))
3901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3902 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3904 hr = IDirect3DDevice9_EndScene(device);
3905 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3907 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3908 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3910 color = getPixelColor(device, 638, 240);
3911 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3915 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3916 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3917 hr = IDirect3DDevice9_BeginScene(device);
3918 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3919 if(SUCCEEDED(hr))
3921 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3922 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3924 hr = IDirect3DDevice9_EndScene(device);
3925 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3927 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3928 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3930 color = getPixelColor(device, 638, 240);
3931 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3933 /* Cleanup */
3934 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3935 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3936 IDirect3DPixelShader9_Release(shader);
3938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3939 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3941 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3944 static void texkill_test(IDirect3DDevice9 *device)
3946 IDirect3DPixelShader9 *shader;
3947 HRESULT hr;
3948 DWORD color;
3950 const float vertex[] = {
3951 /* bottom top right left */
3952 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3953 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3954 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3955 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3958 DWORD shader_code_11[] = {
3959 0xffff0101, /* ps_1_1 */
3960 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3961 0x00000041, 0xb00f0000, /* texkill t0 */
3962 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3963 0x0000ffff /* end */
3965 DWORD shader_code_20[] = {
3966 0xffff0200, /* ps_2_0 */
3967 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3968 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3969 0x01000041, 0xb00f0000, /* texkill t0 */
3970 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3971 0x0000ffff /* end */
3974 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3975 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3976 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3977 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3979 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3980 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3981 hr = IDirect3DDevice9_BeginScene(device);
3982 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3983 if(SUCCEEDED(hr))
3985 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3986 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3987 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3988 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3989 hr = IDirect3DDevice9_EndScene(device);
3990 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3993 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3994 color = getPixelColor(device, 63, 46);
3995 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3996 color = getPixelColor(device, 66, 46);
3997 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3998 color = getPixelColor(device, 63, 49);
3999 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4000 color = getPixelColor(device, 66, 49);
4001 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4003 color = getPixelColor(device, 578, 46);
4004 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4005 color = getPixelColor(device, 575, 46);
4006 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4007 color = getPixelColor(device, 578, 49);
4008 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4009 color = getPixelColor(device, 575, 49);
4010 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4012 color = getPixelColor(device, 63, 430);
4013 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4014 color = getPixelColor(device, 63, 433);
4015 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4016 color = getPixelColor(device, 66, 433);
4017 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4018 color = getPixelColor(device, 66, 430);
4019 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4021 color = getPixelColor(device, 578, 430);
4022 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4023 color = getPixelColor(device, 578, 433);
4024 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4025 color = getPixelColor(device, 575, 433);
4026 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4027 color = getPixelColor(device, 575, 430);
4028 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4030 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4031 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4032 IDirect3DPixelShader9_Release(shader);
4034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4035 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4036 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4037 if(FAILED(hr)) {
4038 skip("Failed to create 2.0 test shader, most likely not supported\n");
4039 return;
4042 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4043 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4044 hr = IDirect3DDevice9_BeginScene(device);
4045 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4046 if(SUCCEEDED(hr))
4048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4049 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4050 hr = IDirect3DDevice9_EndScene(device);
4051 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4053 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4055 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4056 color = getPixelColor(device, 63, 46);
4057 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4058 color = getPixelColor(device, 66, 46);
4059 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4060 color = getPixelColor(device, 63, 49);
4061 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4062 color = getPixelColor(device, 66, 49);
4063 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4065 color = getPixelColor(device, 578, 46);
4066 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4067 color = getPixelColor(device, 575, 46);
4068 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4069 color = getPixelColor(device, 578, 49);
4070 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4071 color = getPixelColor(device, 575, 49);
4072 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4074 color = getPixelColor(device, 63, 430);
4075 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4076 color = getPixelColor(device, 63, 433);
4077 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4078 color = getPixelColor(device, 66, 433);
4079 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4080 color = getPixelColor(device, 66, 430);
4081 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4083 color = getPixelColor(device, 578, 430);
4084 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4085 color = getPixelColor(device, 578, 433);
4086 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4087 color = getPixelColor(device, 575, 433);
4088 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4089 color = getPixelColor(device, 575, 430);
4090 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4092 /* Cleanup */
4093 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4094 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4095 IDirect3DPixelShader9_Release(shader);
4098 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4100 IDirect3D9 *d3d9;
4101 HRESULT hr;
4102 IDirect3DTexture9 *texture;
4103 IDirect3DPixelShader9 *shader;
4104 IDirect3DPixelShader9 *shader2;
4105 D3DLOCKED_RECT lr;
4106 DWORD color;
4107 DWORD shader_code[] = {
4108 0xffff0101, /* ps_1_1 */
4109 0x00000042, 0xb00f0000, /* tex t0 */
4110 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4111 0x0000ffff /* end */
4113 DWORD shader_code2[] = {
4114 0xffff0101, /* ps_1_1 */
4115 0x00000042, 0xb00f0000, /* tex t0 */
4116 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4117 0x0000ffff /* end */
4120 float quad[] = {
4121 -1.0, -1.0, 0.1, 0.5, 0.5,
4122 1.0, -1.0, 0.1, 0.5, 0.5,
4123 -1.0, 1.0, 0.1, 0.5, 0.5,
4124 1.0, 1.0, 0.1, 0.5, 0.5,
4127 memset(&lr, 0, sizeof(lr));
4128 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4129 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4130 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4131 IDirect3D9_Release(d3d9);
4132 if(FAILED(hr)) {
4133 skip("No D3DFMT_X8L8V8U8 support\n");
4136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4139 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4140 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4141 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4142 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4143 *((DWORD *) lr.pBits) = 0x11ca3141;
4144 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4145 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4147 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4148 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4149 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4152 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4153 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4154 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4155 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4156 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4157 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4159 hr = IDirect3DDevice9_BeginScene(device);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4161 if(SUCCEEDED(hr))
4163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4164 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4166 hr = IDirect3DDevice9_EndScene(device);
4167 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4169 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4170 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4171 color = getPixelColor(device, 578, 430);
4172 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4173 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4175 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4176 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4177 hr = IDirect3DDevice9_BeginScene(device);
4178 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4179 if(SUCCEEDED(hr))
4181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4182 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4184 hr = IDirect3DDevice9_EndScene(device);
4185 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4187 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4188 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4189 color = getPixelColor(device, 578, 430);
4190 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4192 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4193 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4194 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4196 IDirect3DPixelShader9_Release(shader);
4197 IDirect3DPixelShader9_Release(shader2);
4198 IDirect3DTexture9_Release(texture);
4201 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4203 HRESULT hr;
4204 IDirect3D9 *d3d;
4205 IDirect3DTexture9 *texture = NULL;
4206 IDirect3DSurface9 *surface;
4207 DWORD color;
4208 const RECT r1 = {256, 256, 512, 512};
4209 const RECT r2 = {512, 256, 768, 512};
4210 const RECT r3 = {256, 512, 512, 768};
4211 const RECT r4 = {512, 512, 768, 768};
4212 unsigned int x, y;
4213 D3DLOCKED_RECT lr;
4214 memset(&lr, 0, sizeof(lr));
4216 IDirect3DDevice9_GetDirect3D(device, &d3d);
4217 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4218 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4219 skip("No autogenmipmap support\n");
4220 IDirect3D9_Release(d3d);
4221 return;
4223 IDirect3D9_Release(d3d);
4225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4226 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4228 /* Make the mipmap big, so that a smaller mipmap is used
4230 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4231 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4232 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4234 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4235 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4236 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4237 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4238 for(y = 0; y < 1024; y++) {
4239 for(x = 0; x < 1024; x++) {
4240 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4241 POINT pt;
4243 pt.x = x;
4244 pt.y = y;
4245 if(PtInRect(&r1, pt)) {
4246 *dst = 0xffff0000;
4247 } else if(PtInRect(&r2, pt)) {
4248 *dst = 0xff00ff00;
4249 } else if(PtInRect(&r3, pt)) {
4250 *dst = 0xff0000ff;
4251 } else if(PtInRect(&r4, pt)) {
4252 *dst = 0xff000000;
4253 } else {
4254 *dst = 0xffffffff;
4258 hr = IDirect3DSurface9_UnlockRect(surface);
4259 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4260 IDirect3DSurface9_Release(surface);
4262 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4264 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4265 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4267 hr = IDirect3DDevice9_BeginScene(device);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4269 if(SUCCEEDED(hr)) {
4270 const float quad[] = {
4271 -0.5, -0.5, 0.1, 0.0, 0.0,
4272 -0.5, 0.5, 0.1, 0.0, 1.0,
4273 0.5, -0.5, 0.1, 1.0, 0.0,
4274 0.5, 0.5, 0.1, 1.0, 1.0
4277 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4278 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4279 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4280 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4281 hr = IDirect3DDevice9_EndScene(device);
4282 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4284 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4285 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4286 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4287 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4288 IDirect3DTexture9_Release(texture);
4290 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4291 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4292 color = getPixelColor(device, 200, 200);
4293 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4294 color = getPixelColor(device, 280, 200);
4295 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4296 color = getPixelColor(device, 360, 200);
4297 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4298 color = getPixelColor(device, 440, 200);
4299 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4300 color = getPixelColor(device, 200, 270);
4301 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4302 color = getPixelColor(device, 280, 270);
4303 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4304 color = getPixelColor(device, 360, 270);
4305 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4306 color = getPixelColor(device, 440, 270);
4307 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4310 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4312 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4313 IDirect3DVertexDeclaration9 *decl;
4314 HRESULT hr;
4315 DWORD color;
4316 DWORD shader_code_11[] = {
4317 0xfffe0101, /* vs_1_1 */
4318 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4319 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4320 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4321 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4322 0x0000ffff /* end */
4324 DWORD shader_code_11_2[] = {
4325 0xfffe0101, /* vs_1_1 */
4326 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4327 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4328 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4329 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4330 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4331 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4332 0x0000ffff /* end */
4334 DWORD shader_code_20[] = {
4335 0xfffe0200, /* vs_2_0 */
4336 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4337 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4338 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4339 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4340 0x0000ffff /* end */
4342 DWORD shader_code_20_2[] = {
4343 0xfffe0200, /* vs_2_0 */
4344 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4345 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4346 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4347 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4348 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4349 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4350 0x0000ffff /* end */
4352 static const D3DVERTEXELEMENT9 decl_elements[] = {
4353 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4354 D3DDECL_END()
4356 float quad1[] = {
4357 -1.0, -1.0, 0.1,
4358 0.0, -1.0, 0.1,
4359 -1.0, 0.0, 0.1,
4360 0.0, 0.0, 0.1
4362 float quad2[] = {
4363 0.0, -1.0, 0.1,
4364 1.0, -1.0, 0.1,
4365 0.0, 0.0, 0.1,
4366 1.0, 0.0, 0.1
4368 float quad3[] = {
4369 0.0, 0.0, 0.1,
4370 1.0, 0.0, 0.1,
4371 0.0, 1.0, 0.1,
4372 1.0, 1.0, 0.1
4374 float quad4[] = {
4375 -1.0, 0.0, 0.1,
4376 0.0, 0.0, 0.1,
4377 -1.0, 1.0, 0.1,
4378 0.0, 1.0, 0.1
4380 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4381 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4384 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4386 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4387 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4388 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4390 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4391 if(FAILED(hr)) shader_20 = NULL;
4392 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4393 if(FAILED(hr)) shader_20_2 = NULL;
4394 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4395 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4397 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4398 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4399 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4400 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4401 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4402 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4404 hr = IDirect3DDevice9_BeginScene(device);
4405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4406 if(SUCCEEDED(hr))
4408 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4409 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4411 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4413 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4414 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4416 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4418 if(shader_20) {
4419 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4420 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4422 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4425 if(shader_20_2) {
4426 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4427 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4429 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4432 hr = IDirect3DDevice9_EndScene(device);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4435 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4438 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4439 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4440 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4441 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4443 color = getPixelColor(device, 160, 360);
4444 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4445 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4446 color = getPixelColor(device, 480, 360);
4447 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4448 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4449 if(shader_20) {
4450 color = getPixelColor(device, 160, 120);
4451 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4452 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4454 if(shader_20_2) {
4455 color = getPixelColor(device, 480, 120);
4456 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4457 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4460 IDirect3DVertexDeclaration9_Release(decl);
4461 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4462 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4463 IDirect3DVertexShader9_Release(shader_11_2);
4464 IDirect3DVertexShader9_Release(shader_11);
4467 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4469 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4470 HRESULT hr;
4471 DWORD color;
4472 DWORD shader_code_11[] = {
4473 0xffff0101, /* ps_1_1 */
4474 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4475 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4476 0x0000ffff /* end */
4478 DWORD shader_code_12[] = {
4479 0xffff0102, /* ps_1_2 */
4480 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4481 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4482 0x0000ffff /* end */
4484 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4485 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4486 * During development of this test, 1.3 shaders were verified too
4488 DWORD shader_code_14[] = {
4489 0xffff0104, /* ps_1_4 */
4490 /* Try to make one constant local. It gets clamped too, although the binary contains
4491 * the bigger numbers
4493 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4494 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4495 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4496 0x0000ffff /* end */
4498 DWORD shader_code_20[] = {
4499 0xffff0200, /* ps_2_0 */
4500 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4501 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4502 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4503 0x0000ffff /* end */
4505 float quad1[] = {
4506 -1.0, -1.0, 0.1,
4507 0.0, -1.0, 0.1,
4508 -1.0, 0.0, 0.1,
4509 0.0, 0.0, 0.1
4511 float quad2[] = {
4512 0.0, -1.0, 0.1,
4513 1.0, -1.0, 0.1,
4514 0.0, 0.0, 0.1,
4515 1.0, 0.0, 0.1
4517 float quad3[] = {
4518 0.0, 0.0, 0.1,
4519 1.0, 0.0, 0.1,
4520 0.0, 1.0, 0.1,
4521 1.0, 1.0, 0.1
4523 float quad4[] = {
4524 -1.0, 0.0, 0.1,
4525 0.0, 0.0, 0.1,
4526 -1.0, 1.0, 0.1,
4527 0.0, 1.0, 0.1
4529 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4530 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4532 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4535 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4536 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4537 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4538 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4539 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4540 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4541 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4542 if(FAILED(hr)) shader_20 = NULL;
4544 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4545 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4546 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4548 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4549 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4551 hr = IDirect3DDevice9_BeginScene(device);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4553 if(SUCCEEDED(hr))
4555 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4556 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4558 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4560 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4561 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4563 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4565 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4566 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4568 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4570 if(shader_20) {
4571 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4574 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4577 hr = IDirect3DDevice9_EndScene(device);
4578 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4580 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4581 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4583 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4586 color = getPixelColor(device, 160, 360);
4587 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4588 "quad 1 has color %08x, expected 0x00808000\n", color);
4589 color = getPixelColor(device, 480, 360);
4590 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4591 "quad 2 has color %08x, expected 0x00808000\n", color);
4592 color = getPixelColor(device, 480, 120);
4593 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4594 "quad 3 has color %08x, expected 0x00808000\n", color);
4595 if(shader_20) {
4596 color = getPixelColor(device, 160, 120);
4597 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4598 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4601 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4602 IDirect3DPixelShader9_Release(shader_14);
4603 IDirect3DPixelShader9_Release(shader_12);
4604 IDirect3DPixelShader9_Release(shader_11);
4607 static void dp2add_ps_test(IDirect3DDevice9 *device)
4609 IDirect3DPixelShader9 *shader_dp2add = NULL;
4610 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4611 HRESULT hr;
4612 DWORD color;
4614 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4615 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4616 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4617 * r0 first.
4618 * The result here for the r,g,b components should be roughly 0.5:
4619 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4620 static const DWORD shader_code_dp2add[] = {
4621 0xffff0200, /* ps_2_0 */
4622 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4624 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4625 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4627 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4628 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4629 0x0000ffff /* end */
4632 /* Test the _sat modifier, too. Result here should be:
4633 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4634 * _SAT: ==> 1.0
4635 * ADD: (1.0 + -0.5) = 0.5
4637 static const DWORD shader_code_dp2add_sat[] = {
4638 0xffff0200, /* ps_2_0 */
4639 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4641 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4642 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4643 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4645 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4646 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4647 0x0000ffff /* end */
4650 const float quad[] = {
4651 -1.0, -1.0, 0.1,
4652 1.0, -1.0, 0.1,
4653 -1.0, 1.0, 0.1,
4654 1.0, 1.0, 0.1
4658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4659 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4661 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4662 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4664 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4665 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4667 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4668 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4670 if (shader_dp2add) {
4672 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4673 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4675 hr = IDirect3DDevice9_BeginScene(device);
4676 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4677 if(SUCCEEDED(hr))
4679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4680 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4682 hr = IDirect3DDevice9_EndScene(device);
4683 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4685 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4686 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4688 color = getPixelColor(device, 360, 240);
4689 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4691 IDirect3DPixelShader9_Release(shader_dp2add);
4692 } else {
4693 skip("dp2add shader creation failed\n");
4696 if (shader_dp2add_sat) {
4698 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4699 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4701 hr = IDirect3DDevice9_BeginScene(device);
4702 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4703 if(SUCCEEDED(hr))
4705 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4706 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4708 hr = IDirect3DDevice9_EndScene(device);
4709 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4712 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4714 color = getPixelColor(device, 360, 240);
4715 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4717 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4718 } else {
4719 skip("dp2add shader creation failed\n");
4722 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4723 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4726 static void cnd_test(IDirect3DDevice9 *device)
4728 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4729 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4730 HRESULT hr;
4731 DWORD color;
4732 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4733 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4734 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4736 DWORD shader_code_11[] = {
4737 0xffff0101, /* ps_1_1 */
4738 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4739 0x00000040, 0xb00f0000, /* texcoord t0 */
4740 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4741 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4742 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4743 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4744 0x0000ffff /* end */
4746 DWORD shader_code_12[] = {
4747 0xffff0102, /* ps_1_2 */
4748 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4749 0x00000040, 0xb00f0000, /* texcoord t0 */
4750 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4751 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4752 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4753 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4754 0x0000ffff /* end */
4756 DWORD shader_code_13[] = {
4757 0xffff0103, /* ps_1_3 */
4758 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4759 0x00000040, 0xb00f0000, /* texcoord t0 */
4760 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4761 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4762 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4763 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4764 0x0000ffff /* end */
4766 DWORD shader_code_14[] = {
4767 0xffff0104, /* ps_1_3 */
4768 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4769 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4770 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4771 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4772 0x0000ffff /* end */
4775 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4776 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4777 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4778 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4779 * native CreatePixelShader returns an error.
4781 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4782 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4783 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4784 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4786 DWORD shader_code_11_coissue[] = {
4787 0xffff0101, /* ps_1_1 */
4788 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4789 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4790 0x00000040, 0xb00f0000, /* texcoord t0 */
4791 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4792 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4793 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4794 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4795 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4796 /* 0x40000000 = D3DSI_COISSUE */
4797 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4798 0x0000ffff /* end */
4800 DWORD shader_code_12_coissue[] = {
4801 0xffff0102, /* ps_1_2 */
4802 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4803 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4804 0x00000040, 0xb00f0000, /* texcoord t0 */
4805 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4806 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4807 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4808 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4809 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4810 /* 0x40000000 = D3DSI_COISSUE */
4811 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4812 0x0000ffff /* end */
4814 DWORD shader_code_13_coissue[] = {
4815 0xffff0103, /* ps_1_3 */
4816 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4817 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4818 0x00000040, 0xb00f0000, /* texcoord t0 */
4819 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4820 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4821 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4822 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4823 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4824 /* 0x40000000 = D3DSI_COISSUE */
4825 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4826 0x0000ffff /* end */
4828 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4829 * compare against 0.5
4831 DWORD shader_code_14_coissue[] = {
4832 0xffff0104, /* ps_1_4 */
4833 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4834 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4835 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4836 /* 0x40000000 = D3DSI_COISSUE */
4837 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4838 0x0000ffff /* end */
4840 float quad1[] = {
4841 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4842 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4843 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4844 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4846 float quad2[] = {
4847 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4848 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4849 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4850 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4852 float quad3[] = {
4853 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4854 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4855 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4856 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4858 float quad4[] = {
4859 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4860 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4861 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4862 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4864 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4865 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4866 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4867 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4869 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4872 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4873 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4874 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4875 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4876 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4877 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4878 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4879 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4880 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4882 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4883 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4884 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4885 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4886 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4887 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4889 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4890 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4891 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4892 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4893 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4896 hr = IDirect3DDevice9_BeginScene(device);
4897 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4898 if(SUCCEEDED(hr))
4900 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4901 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4903 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4905 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4906 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4907 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4908 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4910 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4911 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4913 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4915 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4916 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4918 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4920 hr = IDirect3DDevice9_EndScene(device);
4921 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4923 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4924 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4926 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4927 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4929 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4930 color = getPixelColor(device, 158, 118);
4931 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4932 color = getPixelColor(device, 162, 118);
4933 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4934 color = getPixelColor(device, 158, 122);
4935 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4936 color = getPixelColor(device, 162, 122);
4937 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4939 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4940 color = getPixelColor(device, 158, 358);
4941 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4942 color = getPixelColor(device, 162, 358);
4943 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4944 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4945 color = getPixelColor(device, 158, 362);
4946 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4947 color = getPixelColor(device, 162, 362);
4948 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4949 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4951 /* 1.2 shader */
4952 color = getPixelColor(device, 478, 358);
4953 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4954 color = getPixelColor(device, 482, 358);
4955 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4956 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4957 color = getPixelColor(device, 478, 362);
4958 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4959 color = getPixelColor(device, 482, 362);
4960 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4961 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4963 /* 1.3 shader */
4964 color = getPixelColor(device, 478, 118);
4965 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4966 color = getPixelColor(device, 482, 118);
4967 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4968 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4969 color = getPixelColor(device, 478, 122);
4970 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4971 color = getPixelColor(device, 482, 122);
4972 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4973 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4977 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4979 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4980 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4982 hr = IDirect3DDevice9_BeginScene(device);
4983 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4984 if(SUCCEEDED(hr))
4986 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4987 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4989 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4991 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4994 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4996 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4999 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5001 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5002 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5004 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5006 hr = IDirect3DDevice9_EndScene(device);
5007 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5009 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5010 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5012 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5013 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5015 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5016 * that we swapped the values in c1 and c2 to make the other tests return some color
5018 color = getPixelColor(device, 158, 118);
5019 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5020 color = getPixelColor(device, 162, 118);
5021 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5022 color = getPixelColor(device, 158, 122);
5023 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5024 color = getPixelColor(device, 162, 122);
5025 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5027 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5028 color = getPixelColor(device, 158, 358);
5029 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5030 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5031 color = getPixelColor(device, 162, 358);
5032 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5033 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5034 color = getPixelColor(device, 158, 362);
5035 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5036 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5037 color = getPixelColor(device, 162, 362);
5038 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5039 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5041 /* 1.2 shader */
5042 color = getPixelColor(device, 478, 358);
5043 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5044 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5045 color = getPixelColor(device, 482, 358);
5046 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5047 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5048 color = getPixelColor(device, 478, 362);
5049 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5050 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5051 color = getPixelColor(device, 482, 362);
5052 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5053 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5055 /* 1.3 shader */
5056 color = getPixelColor(device, 478, 118);
5057 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5058 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5059 color = getPixelColor(device, 482, 118);
5060 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5061 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5062 color = getPixelColor(device, 478, 122);
5063 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5064 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5065 color = getPixelColor(device, 482, 122);
5066 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5067 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5069 IDirect3DPixelShader9_Release(shader_14_coissue);
5070 IDirect3DPixelShader9_Release(shader_13_coissue);
5071 IDirect3DPixelShader9_Release(shader_12_coissue);
5072 IDirect3DPixelShader9_Release(shader_11_coissue);
5073 IDirect3DPixelShader9_Release(shader_14);
5074 IDirect3DPixelShader9_Release(shader_13);
5075 IDirect3DPixelShader9_Release(shader_12);
5076 IDirect3DPixelShader9_Release(shader_11);
5079 static void nested_loop_test(IDirect3DDevice9 *device) {
5080 const DWORD shader_code[] = {
5081 0xffff0300, /* ps_3_0 */
5082 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5083 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5084 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5085 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5086 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5087 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5088 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5089 0x0000001d, /* endloop */
5090 0x0000001d, /* endloop */
5091 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5092 0x0000ffff /* end */
5094 IDirect3DPixelShader9 *shader;
5095 HRESULT hr;
5096 DWORD color;
5097 const float quad[] = {
5098 -1.0, -1.0, 0.1,
5099 1.0, -1.0, 0.1,
5100 -1.0, 1.0, 0.1,
5101 1.0, 1.0, 0.1
5104 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5105 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5106 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5107 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5108 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5109 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5111 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5113 hr = IDirect3DDevice9_BeginScene(device);
5114 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5115 if(SUCCEEDED(hr))
5117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5118 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5119 hr = IDirect3DDevice9_EndScene(device);
5120 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5122 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5123 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5125 color = getPixelColor(device, 360, 240);
5126 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5127 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5130 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5131 IDirect3DPixelShader9_Release(shader);
5134 struct varying_test_struct
5136 const DWORD *shader_code;
5137 IDirect3DPixelShader9 *shader;
5138 DWORD color, color_rhw;
5139 const char *name;
5140 BOOL todo, todo_rhw;
5143 struct hugeVertex
5145 float pos_x, pos_y, pos_z, rhw;
5146 float weight_1, weight_2, weight_3, weight_4;
5147 float index_1, index_2, index_3, index_4;
5148 float normal_1, normal_2, normal_3, normal_4;
5149 float fog_1, fog_2, fog_3, fog_4;
5150 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5151 float tangent_1, tangent_2, tangent_3, tangent_4;
5152 float binormal_1, binormal_2, binormal_3, binormal_4;
5153 float depth_1, depth_2, depth_3, depth_4;
5154 DWORD diffuse, specular;
5157 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5158 /* dcl_position: fails to compile */
5159 const DWORD blendweight_code[] = {
5160 0xffff0300, /* ps_3_0 */
5161 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5162 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5163 0x0000ffff /* end */
5165 const DWORD blendindices_code[] = {
5166 0xffff0300, /* ps_3_0 */
5167 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5168 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5169 0x0000ffff /* end */
5171 const DWORD normal_code[] = {
5172 0xffff0300, /* ps_3_0 */
5173 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5174 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5175 0x0000ffff /* end */
5177 /* psize: fails? */
5178 const DWORD texcoord0_code[] = {
5179 0xffff0300, /* ps_3_0 */
5180 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5181 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5182 0x0000ffff /* end */
5184 const DWORD tangent_code[] = {
5185 0xffff0300, /* ps_3_0 */
5186 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5187 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5188 0x0000ffff /* end */
5190 const DWORD binormal_code[] = {
5191 0xffff0300, /* ps_3_0 */
5192 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5193 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5194 0x0000ffff /* end */
5196 /* tessfactor: fails */
5197 /* positiont: fails */
5198 const DWORD color_code[] = {
5199 0xffff0300, /* ps_3_0 */
5200 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5201 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5202 0x0000ffff /* end */
5204 const DWORD fog_code[] = {
5205 0xffff0300, /* ps_3_0 */
5206 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5207 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5208 0x0000ffff /* end */
5210 const DWORD depth_code[] = {
5211 0xffff0300, /* ps_3_0 */
5212 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5213 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5214 0x0000ffff /* end */
5216 const DWORD specular_code[] = {
5217 0xffff0300, /* ps_3_0 */
5218 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5219 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5220 0x0000ffff /* end */
5222 /* sample: fails */
5224 struct varying_test_struct tests[] = {
5225 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5226 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5227 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5228 /* Why does dx not forward the texcoord? */
5229 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5230 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5231 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5232 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5233 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5234 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5235 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5237 /* Declare a monster vertex type :-) */
5238 static const D3DVERTEXELEMENT9 decl_elements[] = {
5239 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5240 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5241 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5242 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5243 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5244 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5245 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5246 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5247 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5248 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5249 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5250 D3DDECL_END()
5252 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5253 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5254 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5255 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5256 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5257 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5258 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5259 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5260 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5261 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5262 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5263 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5264 D3DDECL_END()
5266 struct hugeVertex data[4] = {
5268 -1.0, -1.0, 0.1, 1.0,
5269 0.1, 0.1, 0.1, 0.1,
5270 0.2, 0.2, 0.2, 0.2,
5271 0.3, 0.3, 0.3, 0.3,
5272 0.4, 0.4, 0.4, 0.4,
5273 0.50, 0.55, 0.55, 0.55,
5274 0.6, 0.6, 0.6, 0.7,
5275 0.7, 0.7, 0.7, 0.6,
5276 0.8, 0.8, 0.8, 0.8,
5277 0xe6e6e6e6, /* 0.9 * 256 */
5278 0x224488ff /* Nothing special */
5281 1.0, -1.0, 0.1, 1.0,
5282 0.1, 0.1, 0.1, 0.1,
5283 0.2, 0.2, 0.2, 0.2,
5284 0.3, 0.3, 0.3, 0.3,
5285 0.4, 0.4, 0.4, 0.4,
5286 0.50, 0.55, 0.55, 0.55,
5287 0.6, 0.6, 0.6, 0.7,
5288 0.7, 0.7, 0.7, 0.6,
5289 0.8, 0.8, 0.8, 0.8,
5290 0xe6e6e6e6, /* 0.9 * 256 */
5291 0x224488ff /* Nothing special */
5294 -1.0, 1.0, 0.1, 1.0,
5295 0.1, 0.1, 0.1, 0.1,
5296 0.2, 0.2, 0.2, 0.2,
5297 0.3, 0.3, 0.3, 0.3,
5298 0.4, 0.4, 0.4, 0.4,
5299 0.50, 0.55, 0.55, 0.55,
5300 0.6, 0.6, 0.6, 0.7,
5301 0.7, 0.7, 0.7, 0.6,
5302 0.8, 0.8, 0.8, 0.8,
5303 0xe6e6e6e6, /* 0.9 * 256 */
5304 0x224488ff /* Nothing special */
5307 1.0, 1.0, 0.1, 1.0,
5308 0.1, 0.1, 0.1, 0.1,
5309 0.2, 0.2, 0.2, 0.2,
5310 0.3, 0.3, 0.3, 0.3,
5311 0.4, 0.4, 0.4, 0.4,
5312 0.50, 0.55, 0.55, 0.55,
5313 0.6, 0.6, 0.6, 0.7,
5314 0.7, 0.7, 0.7, 0.6,
5315 0.8, 0.8, 0.8, 0.8,
5316 0xe6e6e6e6, /* 0.9 * 256 */
5317 0x224488ff /* Nothing special */
5320 struct hugeVertex data2[4];
5321 IDirect3DVertexDeclaration9 *decl;
5322 IDirect3DVertexDeclaration9 *decl2;
5323 HRESULT hr;
5324 unsigned int i;
5325 DWORD color, r, g, b, r_e, g_e, b_e;
5326 BOOL drawok;
5328 memcpy(data2, data, sizeof(data2));
5329 data2[0].pos_x = 0; data2[0].pos_y = 0;
5330 data2[1].pos_x = 640; data2[1].pos_y = 0;
5331 data2[2].pos_x = 0; data2[2].pos_y = 480;
5332 data2[3].pos_x = 640; data2[3].pos_y = 480;
5334 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5335 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5336 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5337 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5338 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5341 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5343 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5344 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5345 tests[i].name, hr);
5348 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5353 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5354 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5356 hr = IDirect3DDevice9_BeginScene(device);
5357 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5358 drawok = FALSE;
5359 if(SUCCEEDED(hr))
5361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5362 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5363 drawok = SUCCEEDED(hr);
5364 hr = IDirect3DDevice9_EndScene(device);
5365 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5367 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5368 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5370 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5371 * the failure and do not check the color if it failed
5373 if(!drawok) {
5374 continue;
5377 color = getPixelColor(device, 360, 240);
5378 r = color & 0x00ff0000 >> 16;
5379 g = color & 0x0000ff00 >> 8;
5380 b = color & 0x000000ff;
5381 r_e = tests[i].color & 0x00ff0000 >> 16;
5382 g_e = tests[i].color & 0x0000ff00 >> 8;
5383 b_e = tests[i].color & 0x000000ff;
5385 if(tests[i].todo) {
5386 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5387 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5388 tests[i].name, color, tests[i].color);
5389 } else {
5390 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5391 "Test %s returned color 0x%08x, expected 0x%08x\n",
5392 tests[i].name, color, tests[i].color);
5396 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5397 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5398 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5400 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5401 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5403 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5404 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5406 hr = IDirect3DDevice9_BeginScene(device);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5408 if(SUCCEEDED(hr))
5410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5411 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5412 hr = IDirect3DDevice9_EndScene(device);
5413 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5416 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5418 color = getPixelColor(device, 360, 240);
5419 r = color & 0x00ff0000 >> 16;
5420 g = color & 0x0000ff00 >> 8;
5421 b = color & 0x000000ff;
5422 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5423 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5424 b_e = tests[i].color_rhw & 0x000000ff;
5426 if(tests[i].todo_rhw) {
5427 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5428 * pipeline
5430 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5431 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5432 tests[i].name, color, tests[i].color_rhw);
5433 } else {
5434 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5435 "Test %s returned color 0x%08x, expected 0x%08x\n",
5436 tests[i].name, color, tests[i].color_rhw);
5440 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5442 IDirect3DPixelShader9_Release(tests[i].shader);
5445 IDirect3DVertexDeclaration9_Release(decl2);
5446 IDirect3DVertexDeclaration9_Release(decl);
5449 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5450 static const DWORD ps_code[] = {
5451 0xffff0300, /* ps_3_0 */
5452 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5453 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5454 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5455 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5456 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5457 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5458 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5459 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5460 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5462 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5463 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5464 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5465 0x0000001d, /* endloop */
5466 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5467 0x0000ffff /* end */
5469 static const DWORD vs_1_code[] = {
5470 0xfffe0101, /* vs_1_1 */
5471 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5472 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5473 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5474 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5475 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5476 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5477 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5478 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5479 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5480 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5481 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5482 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5483 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5484 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5485 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5486 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5487 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5488 0x0000ffff
5490 DWORD vs_2_code[] = {
5491 0xfffe0200, /* vs_2_0 */
5492 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5493 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5494 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5495 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5496 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5497 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5498 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5499 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5500 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5501 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5502 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5503 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5504 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5505 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5506 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5507 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5508 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5509 0x0000ffff /* end */
5511 /* TODO: Define normal, tangent, blendweight and depth here */
5512 static const DWORD vs_3_code[] = {
5513 0xfffe0300, /* vs_3_0 */
5514 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5515 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5516 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5517 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5518 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5519 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5520 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5521 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5522 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5523 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5524 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5525 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5526 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5527 0x0000ffff /* end */
5529 float quad1[] = {
5530 -1.0, -1.0, 0.1,
5531 0.0, -1.0, 0.1,
5532 -1.0, 0.0, 0.1,
5533 0.0, 0.0, 0.1
5535 float quad2[] = {
5536 0.0, -1.0, 0.1,
5537 1.0, -1.0, 0.1,
5538 0.0, 0.0, 0.1,
5539 1.0, 0.0, 0.1
5541 float quad3[] = {
5542 -1.0, 0.0, 0.1,
5543 0.0, 0.0, 0.1,
5544 -1.0, 1.0, 0.1,
5545 0.0, 1.0, 0.1
5548 HRESULT hr;
5549 DWORD color;
5550 IDirect3DPixelShader9 *pixelshader = NULL;
5551 IDirect3DVertexShader9 *vs_1_shader = NULL;
5552 IDirect3DVertexShader9 *vs_2_shader = NULL;
5553 IDirect3DVertexShader9 *vs_3_shader = NULL;
5555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5557 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5558 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5559 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5560 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5561 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5562 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5563 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5564 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5565 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5567 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5569 hr = IDirect3DDevice9_BeginScene(device);
5570 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5571 if(SUCCEEDED(hr))
5573 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5574 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5576 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5578 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5579 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5581 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5583 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5584 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5586 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5588 hr = IDirect3DDevice9_EndScene(device);
5589 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5591 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5592 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5594 color = getPixelColor(device, 160, 120);
5595 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5596 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5597 color = getPixelColor(device, 160, 360);
5598 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5599 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5600 color = getPixelColor(device, 480, 360);
5601 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5602 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5604 /* cleanup */
5605 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5606 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5607 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5608 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5609 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5610 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5611 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5612 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5615 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5616 static const DWORD vs_code[] = {
5617 0xfffe0300, /* vs_3_0 */
5618 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5619 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5620 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5621 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5622 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5623 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5624 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5625 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5626 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5627 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5628 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5629 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5630 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5632 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5633 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5634 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5635 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5636 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5637 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5638 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5639 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5640 0x0000ffff /* end */
5642 static const DWORD ps_1_code[] = {
5643 0xffff0104, /* ps_1_4 */
5644 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5645 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5646 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5647 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5648 0x0000ffff /* end */
5650 static const DWORD ps_2_code[] = {
5651 0xffff0200, /* ps_2_0 */
5652 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5653 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5654 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5656 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5657 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5658 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5659 0x0000ffff /* end */
5661 static const DWORD ps_3_code[] = {
5662 0xffff0300, /* ps_3_0 */
5663 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5664 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5665 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5667 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5668 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5669 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5670 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5671 0x0000ffff /* end */
5674 float quad1[] = {
5675 -1.0, -1.0, 0.1,
5676 0.0, -1.0, 0.1,
5677 -1.0, 0.0, 0.1,
5678 0.0, 0.0, 0.1
5680 float quad2[] = {
5681 0.0, -1.0, 0.1,
5682 1.0, -1.0, 0.1,
5683 0.0, 0.0, 0.1,
5684 1.0, 0.0, 0.1
5686 float quad3[] = {
5687 -1.0, 0.0, 0.1,
5688 0.0, 0.0, 0.1,
5689 -1.0, 1.0, 0.1,
5690 0.0, 1.0, 0.1
5692 float quad4[] = {
5693 0.0, 0.0, 0.1,
5694 1.0, 0.0, 0.1,
5695 0.0, 1.0, 0.1,
5696 1.0, 1.0, 0.1
5699 HRESULT hr;
5700 DWORD color;
5701 IDirect3DVertexShader9 *vertexshader = NULL;
5702 IDirect3DPixelShader9 *ps_1_shader = NULL;
5703 IDirect3DPixelShader9 *ps_2_shader = NULL;
5704 IDirect3DPixelShader9 *ps_3_shader = NULL;
5705 IDirect3DTexture9 *texture = NULL;
5706 D3DLOCKED_RECT lr;
5707 unsigned int x, y;
5709 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5711 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5712 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5713 if(FAILED(hr)) {
5714 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5715 return;
5717 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5718 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5719 for(y = 0; y < 512; y++) {
5720 for(x = 0; x < 512; x++) {
5721 double r_f = (double) x / (double) 512;
5722 double g_f = (double) y / (double) 512;
5723 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5724 unsigned short r = (unsigned short) (r_f * 65535.0);
5725 unsigned short g = (unsigned short) (g_f * 65535.0);
5726 dst[0] = r;
5727 dst[1] = g;
5728 dst[2] = 0;
5729 dst[3] = 65535;
5732 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5733 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5735 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5736 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5737 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5738 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5739 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5740 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5741 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5742 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5743 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5744 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5745 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5747 hr = IDirect3DDevice9_BeginScene(device);
5748 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5749 if(SUCCEEDED(hr))
5751 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5752 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5754 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5756 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5757 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5759 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5761 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5762 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5764 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5766 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5767 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5768 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5770 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5771 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5772 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5773 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5775 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5777 hr = IDirect3DDevice9_EndScene(device);
5778 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5780 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5783 color = getPixelColor(device, 160, 120);
5784 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5785 (color & 0x0000ff00) == 0x0000ff00 &&
5786 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5787 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5788 color = getPixelColor(device, 160, 360);
5789 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5790 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5791 (color & 0x000000ff) == 0x00000000,
5792 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5793 color = getPixelColor(device, 480, 360);
5794 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5795 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5796 (color & 0x000000ff) == 0x00000000,
5797 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5798 color = getPixelColor(device, 480, 160);
5799 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5800 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5801 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5802 (color & 0x000000ff) == 0x00000000),
5803 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5805 /* cleanup */
5806 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5807 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5808 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5809 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5810 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5811 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5812 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5813 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5814 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5815 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5816 if(texture) IDirect3DTexture9_Release(texture);
5819 static void test_compare_instructions(IDirect3DDevice9 *device)
5821 DWORD shader_sge_vec_code[] = {
5822 0xfffe0101, /* vs_1_1 */
5823 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5824 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5825 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5826 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5827 0x0000ffff /* end */
5829 DWORD shader_slt_vec_code[] = {
5830 0xfffe0101, /* vs_1_1 */
5831 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5832 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5833 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5834 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5835 0x0000ffff /* end */
5837 DWORD shader_sge_scalar_code[] = {
5838 0xfffe0101, /* vs_1_1 */
5839 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5840 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5841 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5842 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5843 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5844 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5845 0x0000ffff /* end */
5847 DWORD shader_slt_scalar_code[] = {
5848 0xfffe0101, /* vs_1_1 */
5849 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5850 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5851 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5852 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5853 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5854 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5855 0x0000ffff /* end */
5857 IDirect3DVertexShader9 *shader_sge_vec;
5858 IDirect3DVertexShader9 *shader_slt_vec;
5859 IDirect3DVertexShader9 *shader_sge_scalar;
5860 IDirect3DVertexShader9 *shader_slt_scalar;
5861 HRESULT hr, color;
5862 float quad1[] = {
5863 -1.0, -1.0, 0.1,
5864 0.0, -1.0, 0.1,
5865 -1.0, 0.0, 0.1,
5866 0.0, 0.0, 0.1
5868 float quad2[] = {
5869 0.0, -1.0, 0.1,
5870 1.0, -1.0, 0.1,
5871 0.0, 0.0, 0.1,
5872 1.0, 0.0, 0.1
5874 float quad3[] = {
5875 -1.0, 0.0, 0.1,
5876 0.0, 0.0, 0.1,
5877 -1.0, 1.0, 0.1,
5878 0.0, 1.0, 0.1
5880 float quad4[] = {
5881 0.0, 0.0, 0.1,
5882 1.0, 0.0, 0.1,
5883 0.0, 1.0, 0.1,
5884 1.0, 1.0, 0.1
5886 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5887 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5889 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5891 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5893 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5894 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5895 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5896 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5897 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5898 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5899 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5900 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5901 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5902 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5903 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5904 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5906 hr = IDirect3DDevice9_BeginScene(device);
5907 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5908 if(SUCCEEDED(hr))
5910 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5911 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5913 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5915 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5916 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5918 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5920 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5921 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5923 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5925 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5926 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5928 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5929 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5931 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5933 hr = IDirect3DDevice9_EndScene(device);
5934 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5937 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5938 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5939 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5940 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5942 color = getPixelColor(device, 160, 360);
5943 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5944 color = getPixelColor(device, 480, 360);
5945 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5946 color = getPixelColor(device, 160, 120);
5947 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5948 color = getPixelColor(device, 480, 160);
5949 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5951 IDirect3DVertexShader9_Release(shader_sge_vec);
5952 IDirect3DVertexShader9_Release(shader_slt_vec);
5953 IDirect3DVertexShader9_Release(shader_sge_scalar);
5954 IDirect3DVertexShader9_Release(shader_slt_scalar);
5957 static void test_vshader_input(IDirect3DDevice9 *device)
5959 DWORD swapped_shader_code_3[] = {
5960 0xfffe0300, /* vs_3_0 */
5961 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5962 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5963 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5964 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5965 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5966 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5967 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5968 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5969 0x0000ffff /* end */
5971 DWORD swapped_shader_code_1[] = {
5972 0xfffe0101, /* vs_1_1 */
5973 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5974 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5975 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5976 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5977 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5978 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5979 0x0000ffff /* end */
5981 DWORD swapped_shader_code_2[] = {
5982 0xfffe0200, /* vs_2_0 */
5983 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5984 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5985 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5986 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5987 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5988 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5989 0x0000ffff /* end */
5991 DWORD texcoord_color_shader_code_3[] = {
5992 0xfffe0300, /* vs_3_0 */
5993 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5994 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5995 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5996 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5997 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5998 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5999 0x0000ffff /* end */
6001 DWORD texcoord_color_shader_code_2[] = {
6002 0xfffe0200, /* vs_2_0 */
6003 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6004 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6005 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6006 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6007 0x0000ffff /* end */
6009 DWORD texcoord_color_shader_code_1[] = {
6010 0xfffe0101, /* vs_1_1 */
6011 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6012 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6013 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6014 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6015 0x0000ffff /* end */
6017 DWORD color_color_shader_code_3[] = {
6018 0xfffe0300, /* vs_3_0 */
6019 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6020 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6021 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6022 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6023 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6024 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6025 0x0000ffff /* end */
6027 DWORD color_color_shader_code_2[] = {
6028 0xfffe0200, /* vs_2_0 */
6029 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6030 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6031 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6032 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6033 0x0000ffff /* end */
6035 DWORD color_color_shader_code_1[] = {
6036 0xfffe0101, /* vs_1_1 */
6037 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6038 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6039 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6040 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6041 0x0000ffff /* end */
6043 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6044 HRESULT hr;
6045 DWORD color;
6046 float quad1[] = {
6047 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6048 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6049 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6050 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6052 float quad2[] = {
6053 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6054 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6055 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6056 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6058 float quad3[] = {
6059 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6060 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6061 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6062 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6064 float quad4[] = {
6065 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6066 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6067 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6068 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6070 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6071 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6072 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6073 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6074 D3DDECL_END()
6076 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6077 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6078 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6079 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6080 D3DDECL_END()
6082 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6083 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6084 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6085 D3DDECL_END()
6087 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6088 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6089 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6090 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6091 D3DDECL_END()
6093 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6094 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6095 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6096 D3DDECL_END()
6098 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6099 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6100 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6101 D3DDECL_END()
6103 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6104 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6105 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6106 D3DDECL_END()
6108 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6109 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6110 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6111 D3DDECL_END()
6113 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6114 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6115 unsigned int i;
6116 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6117 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6119 struct vertex quad1_color[] = {
6120 {-1.0, -1.0, 0.1, 0x00ff8040},
6121 { 0.0, -1.0, 0.1, 0x00ff8040},
6122 {-1.0, 0.0, 0.1, 0x00ff8040},
6123 { 0.0, 0.0, 0.1, 0x00ff8040}
6125 struct vertex quad2_color[] = {
6126 { 0.0, -1.0, 0.1, 0x00ff8040},
6127 { 1.0, -1.0, 0.1, 0x00ff8040},
6128 { 0.0, 0.0, 0.1, 0x00ff8040},
6129 { 1.0, 0.0, 0.1, 0x00ff8040}
6131 struct vertex quad3_color[] = {
6132 {-1.0, 0.0, 0.1, 0x00ff8040},
6133 { 0.0, 0.0, 0.1, 0x00ff8040},
6134 {-1.0, 1.0, 0.1, 0x00ff8040},
6135 { 0.0, 1.0, 0.1, 0x00ff8040}
6137 float quad4_color[] = {
6138 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6139 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6140 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6141 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6144 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6145 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6146 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6147 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6148 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6149 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6150 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6151 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6153 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6154 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6155 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6156 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6157 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6158 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6159 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6160 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6162 for(i = 1; i <= 3; i++) {
6163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6164 if(i == 3) {
6165 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6167 } else if(i == 2){
6168 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6169 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6170 } else if(i == 1) {
6171 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6175 hr = IDirect3DDevice9_BeginScene(device);
6176 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6177 if(SUCCEEDED(hr))
6179 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6182 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6183 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6184 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6185 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6187 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6188 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6190 if(i == 3 || i == 2) {
6191 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6192 } else if(i == 1) {
6193 /* Succeeds or fails, depending on SW or HW vertex processing */
6194 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6197 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6198 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6200 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6202 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6203 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6205 if(i == 3 || i == 2) {
6206 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6207 } else if(i == 1) {
6208 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6211 hr = IDirect3DDevice9_EndScene(device);
6212 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6215 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6216 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6218 if(i == 3 || i == 2) {
6219 color = getPixelColor(device, 160, 360);
6220 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6221 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6223 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6224 color = getPixelColor(device, 480, 360);
6225 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6226 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6227 color = getPixelColor(device, 160, 120);
6228 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6229 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6230 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6232 color = getPixelColor(device, 480, 160);
6233 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6234 } else if(i == 1) {
6235 color = getPixelColor(device, 160, 360);
6236 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6237 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6238 color = getPixelColor(device, 480, 360);
6239 /* Accept the clear color as well in this case, since SW VP returns an error */
6240 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6241 color = getPixelColor(device, 160, 120);
6242 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6243 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6244 color = getPixelColor(device, 480, 160);
6245 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6249 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6251 /* Now find out if the whole streams are re-read, or just the last active value for the
6252 * vertices is used.
6254 hr = IDirect3DDevice9_BeginScene(device);
6255 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6256 if(SUCCEEDED(hr))
6258 float quad1_modified[] = {
6259 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6260 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6261 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6262 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6264 float quad2_modified[] = {
6265 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6266 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6267 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6268 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6271 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6272 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6274 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6275 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6277 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6279 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6280 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6282 if(i == 3 || i == 2) {
6283 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6284 } else if(i == 1) {
6285 /* Succeeds or fails, depending on SW or HW vertex processing */
6286 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6289 hr = IDirect3DDevice9_EndScene(device);
6290 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6292 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6293 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6295 color = getPixelColor(device, 480, 350);
6296 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6297 * as well.
6299 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6300 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6301 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6302 * refrast's result.
6304 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6306 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6307 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6308 color = getPixelColor(device, 160, 120);
6310 IDirect3DDevice9_SetVertexShader(device, NULL);
6311 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6313 IDirect3DVertexShader9_Release(swapped_shader);
6316 for(i = 1; i <= 3; i++) {
6317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6318 if(i == 3) {
6319 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6321 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6322 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6323 } else if(i == 2){
6324 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6325 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6326 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6327 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6328 } else if(i == 1) {
6329 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6330 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6331 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6335 hr = IDirect3DDevice9_BeginScene(device);
6336 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6337 if(SUCCEEDED(hr))
6339 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6340 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6341 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6342 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6344 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6346 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6349 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6350 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6351 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6352 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6354 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6356 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6358 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6359 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6361 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6363 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6364 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6366 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6368 hr = IDirect3DDevice9_EndScene(device);
6369 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6371 IDirect3DDevice9_SetVertexShader(device, NULL);
6372 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6375 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6377 color = getPixelColor(device, 160, 360);
6378 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6379 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6380 color = getPixelColor(device, 480, 360);
6381 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6382 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6383 color = getPixelColor(device, 160, 120);
6384 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6385 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6386 color = getPixelColor(device, 480, 160);
6387 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6388 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6390 IDirect3DVertexShader9_Release(texcoord_color_shader);
6391 IDirect3DVertexShader9_Release(color_color_shader);
6394 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6395 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6396 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6397 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6399 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6400 IDirect3DVertexDeclaration9_Release(decl_color_color);
6401 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6402 IDirect3DVertexDeclaration9_Release(decl_color_float);
6405 static void srgbtexture_test(IDirect3DDevice9 *device)
6407 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6408 * texture stage state to render a quad using that texture. The resulting
6409 * color components should be 0x36 (~ 0.21), per this formula:
6410 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6411 * This is true where srgb_color > 0.04045.
6413 IDirect3D9 *d3d = NULL;
6414 HRESULT hr;
6415 LPDIRECT3DTEXTURE9 texture = NULL;
6416 LPDIRECT3DSURFACE9 surface = NULL;
6417 D3DLOCKED_RECT lr;
6418 DWORD color;
6419 float quad[] = {
6420 -1.0, 1.0, 0.0, 0.0, 0.0,
6421 1.0, 1.0, 0.0, 1.0, 0.0,
6422 -1.0, -1.0, 0.0, 0.0, 1.0,
6423 1.0, -1.0, 0.0, 1.0, 1.0,
6427 memset(&lr, 0, sizeof(lr));
6428 IDirect3DDevice9_GetDirect3D(device, &d3d);
6429 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6430 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6431 D3DFMT_A8R8G8B8) != D3D_OK) {
6432 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6433 goto out;
6436 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6437 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6438 &texture, NULL);
6439 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6440 if(!texture) {
6441 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6442 goto out;
6444 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6445 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6447 fill_surface(surface, 0xff7f7f7f);
6448 IDirect3DSurface9_Release(surface);
6450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6451 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6452 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6453 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6455 hr = IDirect3DDevice9_BeginScene(device);
6456 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6457 if(SUCCEEDED(hr))
6459 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6460 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6462 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6463 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6467 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6469 hr = IDirect3DDevice9_EndScene(device);
6470 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6473 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6474 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6475 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6476 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6478 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6479 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6481 color = getPixelColor(device, 320, 240);
6482 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6484 out:
6485 if(texture) IDirect3DTexture9_Release(texture);
6486 IDirect3D9_Release(d3d);
6489 static void shademode_test(IDirect3DDevice9 *device)
6491 /* Render a quad and try all of the different fixed function shading models. */
6492 HRESULT hr;
6493 DWORD color0, color1;
6494 DWORD color0_gouraud = 0, color1_gouraud = 0;
6495 DWORD shademode = D3DSHADE_FLAT;
6496 DWORD primtype = D3DPT_TRIANGLESTRIP;
6497 LPVOID data = NULL;
6498 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6499 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6500 UINT i, j;
6501 struct vertex quad_strip[] =
6503 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6504 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6505 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6506 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6508 struct vertex quad_list[] =
6510 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6511 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6512 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6514 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6515 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6516 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6519 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6520 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6521 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6522 if (FAILED(hr)) goto bail;
6524 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6525 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6526 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6527 if (FAILED(hr)) goto bail;
6529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6530 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6533 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6535 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6536 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6537 memcpy(data, quad_strip, sizeof(quad_strip));
6538 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6539 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6541 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6542 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6543 memcpy(data, quad_list, sizeof(quad_list));
6544 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6545 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6547 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6548 * the color fixups we have to do for FLAT shading will be dependent on that. */
6549 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6550 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6552 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6553 for (j=0; j<2; j++) {
6555 /* Inner loop just changes the D3DRS_SHADEMODE */
6556 for (i=0; i<3; i++) {
6557 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6558 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6561 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6563 hr = IDirect3DDevice9_BeginScene(device);
6564 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6565 if(SUCCEEDED(hr))
6567 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6568 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6570 hr = IDirect3DDevice9_EndScene(device);
6571 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6574 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6575 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6577 /* Sample two spots from the output */
6578 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6579 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6580 switch(shademode) {
6581 case D3DSHADE_FLAT:
6582 /* Should take the color of the first vertex of each triangle */
6583 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6584 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6585 shademode = D3DSHADE_GOURAUD;
6586 break;
6587 case D3DSHADE_GOURAUD:
6588 /* Should be an interpolated blend */
6590 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6591 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6592 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6593 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6595 color0_gouraud = color0;
6596 color1_gouraud = color1;
6598 shademode = D3DSHADE_PHONG;
6599 break;
6600 case D3DSHADE_PHONG:
6601 /* Should be the same as GOURAUD, since no hardware implements this */
6602 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6603 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6604 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6605 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6607 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6608 color0_gouraud, color0);
6609 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6610 color1_gouraud, color1);
6611 break;
6614 /* Now, do it all over again with a TRIANGLELIST */
6615 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6616 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6617 primtype = D3DPT_TRIANGLELIST;
6618 shademode = D3DSHADE_FLAT;
6621 bail:
6622 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6623 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6625 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6627 if (vb_strip)
6628 IDirect3DVertexBuffer9_Release(vb_strip);
6629 if (vb_list)
6630 IDirect3DVertexBuffer9_Release(vb_list);
6634 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6636 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6637 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6638 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6639 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6640 * 0.73
6642 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6643 * so use shaders for this task
6645 IDirect3DPixelShader9 *pshader;
6646 IDirect3DVertexShader9 *vshader;
6647 IDirect3D9 *d3d;
6648 DWORD vshader_code[] = {
6649 0xfffe0101, /* vs_1_1 */
6650 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6651 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6652 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6653 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6654 0x0000ffff /* end */
6656 DWORD pshader_code[] = {
6657 0xffff0101, /* ps_1_1 */
6658 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6659 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6660 0x0000ffff /* end */
6662 const float quad[] = {
6663 -1.0, -1.0, 0.1,
6664 1.0, -1.0, 0.1,
6665 -1.0, 1.0, 0.1,
6666 1.0, 1.0, 0.1
6668 HRESULT hr;
6669 DWORD color;
6671 IDirect3DDevice9_GetDirect3D(device, &d3d);
6672 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6673 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6674 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6675 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6676 * works
6678 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6679 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6680 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6681 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6682 IDirect3D9_Release(d3d);
6683 return;
6685 IDirect3D9_Release(d3d);
6687 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6688 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6695 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6697 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6701 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6703 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6704 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6705 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6706 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6707 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6708 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6709 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6710 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6712 hr = IDirect3DDevice9_BeginScene(device);
6713 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6714 if(SUCCEEDED(hr)) {
6715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6716 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6718 hr = IDirect3DDevice9_EndScene(device);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6722 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6724 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6725 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6726 IDirect3DPixelShader9_Release(pshader);
6727 IDirect3DVertexShader9_Release(vshader);
6729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6731 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6732 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6734 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6735 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6736 color = getPixelColor(device, 160, 360);
6737 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6738 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6741 static void alpha_test(IDirect3DDevice9 *device)
6743 HRESULT hr;
6744 IDirect3DTexture9 *offscreenTexture;
6745 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6746 DWORD color;
6748 struct vertex quad1[] =
6750 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6751 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6752 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6753 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6755 struct vertex quad2[] =
6757 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6758 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6759 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6760 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6762 static const float composite_quad[][5] = {
6763 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6764 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6765 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6766 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6769 /* Clear the render target with alpha = 0.5 */
6770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6771 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6773 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6774 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6776 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6777 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6778 if(!backbuffer) {
6779 goto out;
6782 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6783 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6784 if(!offscreen) {
6785 goto out;
6788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6789 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6791 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6792 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6793 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6794 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6795 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6796 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6797 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6798 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6800 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6804 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6806 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6808 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6810 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6812 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6815 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6817 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6819 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6821 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6822 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6823 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6824 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6825 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6827 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6830 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6832 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6834 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6837 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6841 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6843 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6844 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6846 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6847 * Disable alpha blending for the final composition
6849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6851 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6852 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6854 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6855 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6857 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6858 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6859 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6861 hr = IDirect3DDevice9_EndScene(device);
6862 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6865 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6867 color = getPixelColor(device, 160, 360);
6868 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6869 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6871 color = getPixelColor(device, 160, 120);
6872 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6873 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6875 color = getPixelColor(device, 480, 360);
6876 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6877 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6879 color = getPixelColor(device, 480, 120);
6880 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6881 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6883 out:
6884 /* restore things */
6885 if(backbuffer) {
6886 IDirect3DSurface9_Release(backbuffer);
6888 if(offscreenTexture) {
6889 IDirect3DTexture9_Release(offscreenTexture);
6891 if(offscreen) {
6892 IDirect3DSurface9_Release(offscreen);
6896 struct vertex_shortcolor {
6897 float x, y, z;
6898 unsigned short r, g, b, a;
6900 struct vertex_floatcolor {
6901 float x, y, z;
6902 float r, g, b, a;
6905 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6907 HRESULT hr;
6908 BOOL s_ok, ub_ok, f_ok;
6909 DWORD color, size, i;
6910 void *data;
6911 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6912 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6913 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6914 D3DDECL_END()
6916 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6917 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6918 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6919 D3DDECL_END()
6921 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6922 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6923 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6924 D3DDECL_END()
6926 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6927 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6928 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6929 D3DDECL_END()
6931 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6932 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6933 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6934 D3DDECL_END()
6936 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6937 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6938 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6939 D3DDECL_END()
6941 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6942 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6943 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6944 D3DDECL_END()
6946 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6947 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6948 IDirect3DVertexBuffer9 *vb, *vb2;
6949 struct vertex quad1[] = /* D3DCOLOR */
6951 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6952 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6953 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6954 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6956 struct vertex quad2[] = /* UBYTE4N */
6958 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6959 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6960 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6961 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6963 struct vertex_shortcolor quad3[] = /* short */
6965 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6966 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6967 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6968 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6970 struct vertex_floatcolor quad4[] =
6972 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6973 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6974 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6975 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6977 DWORD colors[] = {
6978 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6979 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6980 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6981 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6982 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6983 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6984 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6985 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6986 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6987 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6988 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6989 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6990 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6991 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6992 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6993 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6995 float quads[] = {
6996 -1.0, -1.0, 0.1,
6997 -1.0, 0.0, 0.1,
6998 0.0, -1.0, 0.1,
6999 0.0, 0.0, 0.1,
7001 0.0, -1.0, 0.1,
7002 0.0, 0.0, 0.1,
7003 1.0, -1.0, 0.1,
7004 1.0, 0.0, 0.1,
7006 0.0, 0.0, 0.1,
7007 0.0, 1.0, 0.1,
7008 1.0, 0.0, 0.1,
7009 1.0, 1.0, 0.1,
7011 -1.0, 0.0, 0.1,
7012 -1.0, 1.0, 0.1,
7013 0.0, 0.0, 0.1,
7014 0.0, 1.0, 0.1
7016 struct tvertex quad_transformed[] = {
7017 { 90, 110, 0.1, 2.0, 0x00ffff00},
7018 { 570, 110, 0.1, 2.0, 0x00ffff00},
7019 { 90, 300, 0.1, 2.0, 0x00ffff00},
7020 { 570, 300, 0.1, 2.0, 0x00ffff00}
7022 D3DCAPS9 caps;
7024 memset(&caps, 0, sizeof(caps));
7025 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7026 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7029 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7031 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7032 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7033 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7034 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7035 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7036 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7037 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7038 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7039 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7040 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7041 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7042 } else {
7043 trace("D3DDTCAPS_UBYTE4N not supported\n");
7044 dcl_ubyte_2 = NULL;
7045 dcl_ubyte = NULL;
7047 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7048 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7049 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7050 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7052 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7053 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7054 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7055 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7057 hr = IDirect3DDevice9_BeginScene(device);
7058 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7059 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7060 if(SUCCEEDED(hr)) {
7061 if(dcl_color) {
7062 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7063 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7064 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7065 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7068 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7069 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7070 * using software vertex processing. Doh!
7072 if(dcl_ubyte) {
7073 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7074 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7076 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7077 ub_ok = SUCCEEDED(hr);
7080 if(dcl_short) {
7081 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7084 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7085 s_ok = SUCCEEDED(hr);
7088 if(dcl_float) {
7089 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7090 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7092 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7093 f_ok = SUCCEEDED(hr);
7096 hr = IDirect3DDevice9_EndScene(device);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7100 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7101 if(dcl_short) {
7102 color = getPixelColor(device, 480, 360);
7103 ok(color == 0x000000ff || !s_ok,
7104 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7106 if(dcl_ubyte) {
7107 color = getPixelColor(device, 160, 120);
7108 ok(color == 0x0000ffff || !ub_ok,
7109 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7111 if(dcl_color) {
7112 color = getPixelColor(device, 160, 360);
7113 ok(color == 0x00ffff00,
7114 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7116 if(dcl_float) {
7117 color = getPixelColor(device, 480, 120);
7118 ok(color == 0x00ff0000 || !f_ok,
7119 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7122 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7123 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7124 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7125 * whether the immediate mode code works
7127 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7128 hr = IDirect3DDevice9_BeginScene(device);
7129 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7130 if(SUCCEEDED(hr)) {
7131 if(dcl_color) {
7132 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7133 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7134 memcpy(data, quad1, sizeof(quad1));
7135 hr = IDirect3DVertexBuffer9_Unlock(vb);
7136 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7137 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7139 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7140 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7141 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7142 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7145 if(dcl_ubyte) {
7146 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7147 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7148 memcpy(data, quad2, sizeof(quad2));
7149 hr = IDirect3DVertexBuffer9_Unlock(vb);
7150 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7151 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7152 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7153 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7154 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7155 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7156 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7157 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7158 ub_ok = SUCCEEDED(hr);
7161 if(dcl_short) {
7162 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7163 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7164 memcpy(data, quad3, sizeof(quad3));
7165 hr = IDirect3DVertexBuffer9_Unlock(vb);
7166 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7167 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7168 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7169 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7170 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7171 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7172 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7173 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7174 s_ok = SUCCEEDED(hr);
7177 if(dcl_float) {
7178 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7179 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7180 memcpy(data, quad4, sizeof(quad4));
7181 hr = IDirect3DVertexBuffer9_Unlock(vb);
7182 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7183 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7184 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7185 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7186 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7187 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7188 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7189 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7190 f_ok = SUCCEEDED(hr);
7193 hr = IDirect3DDevice9_EndScene(device);
7194 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7197 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7198 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7199 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7200 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7202 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7203 if(dcl_short) {
7204 color = getPixelColor(device, 480, 360);
7205 ok(color == 0x000000ff || !s_ok,
7206 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7208 if(dcl_ubyte) {
7209 color = getPixelColor(device, 160, 120);
7210 ok(color == 0x0000ffff || !ub_ok,
7211 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7213 if(dcl_color) {
7214 color = getPixelColor(device, 160, 360);
7215 ok(color == 0x00ffff00,
7216 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7218 if(dcl_float) {
7219 color = getPixelColor(device, 480, 120);
7220 ok(color == 0x00ff0000 || !f_ok,
7221 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7224 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7225 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7227 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7228 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7229 memcpy(data, quad_transformed, sizeof(quad_transformed));
7230 hr = IDirect3DVertexBuffer9_Unlock(vb);
7231 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7233 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7236 hr = IDirect3DDevice9_BeginScene(device);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7238 if(SUCCEEDED(hr)) {
7239 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7240 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7241 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7242 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7244 hr = IDirect3DDevice9_EndScene(device);
7245 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7248 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7249 color = getPixelColor(device, 88, 108);
7250 ok(color == 0x000000ff,
7251 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7252 color = getPixelColor(device, 92, 108);
7253 ok(color == 0x000000ff,
7254 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7255 color = getPixelColor(device, 88, 112);
7256 ok(color == 0x000000ff,
7257 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7258 color = getPixelColor(device, 92, 112);
7259 ok(color == 0x00ffff00,
7260 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7262 color = getPixelColor(device, 568, 108);
7263 ok(color == 0x000000ff,
7264 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7265 color = getPixelColor(device, 572, 108);
7266 ok(color == 0x000000ff,
7267 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7268 color = getPixelColor(device, 568, 112);
7269 ok(color == 0x00ffff00,
7270 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7271 color = getPixelColor(device, 572, 112);
7272 ok(color == 0x000000ff,
7273 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7275 color = getPixelColor(device, 88, 298);
7276 ok(color == 0x000000ff,
7277 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7278 color = getPixelColor(device, 92, 298);
7279 ok(color == 0x00ffff00,
7280 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7281 color = getPixelColor(device, 88, 302);
7282 ok(color == 0x000000ff,
7283 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7284 color = getPixelColor(device, 92, 302);
7285 ok(color == 0x000000ff,
7286 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7288 color = getPixelColor(device, 568, 298);
7289 ok(color == 0x00ffff00,
7290 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7291 color = getPixelColor(device, 572, 298);
7292 ok(color == 0x000000ff,
7293 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7294 color = getPixelColor(device, 568, 302);
7295 ok(color == 0x000000ff,
7296 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7297 color = getPixelColor(device, 572, 302);
7298 ok(color == 0x000000ff,
7299 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7301 /* This test is pointless without those two declarations: */
7302 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7303 skip("color-ubyte switching test declarations aren't supported\n");
7304 goto out;
7307 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7308 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7309 memcpy(data, quads, sizeof(quads));
7310 hr = IDirect3DVertexBuffer9_Unlock(vb);
7311 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7312 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7313 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7314 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7315 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7316 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7317 memcpy(data, colors, sizeof(colors));
7318 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7319 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7321 for(i = 0; i < 2; i++) {
7322 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7323 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7325 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7326 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7327 if(i == 0) {
7328 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7329 } else {
7330 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7332 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7334 hr = IDirect3DDevice9_BeginScene(device);
7335 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7336 ub_ok = FALSE;
7337 if(SUCCEEDED(hr)) {
7338 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7340 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7341 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7342 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7343 ub_ok = SUCCEEDED(hr);
7345 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7346 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7347 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7348 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7350 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7351 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7352 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7353 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7354 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7355 ub_ok = (SUCCEEDED(hr) && ub_ok);
7357 hr = IDirect3DDevice9_EndScene(device);
7358 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7361 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7362 if(i == 0) {
7363 color = getPixelColor(device, 480, 360);
7364 ok(color == 0x00ff0000,
7365 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7366 color = getPixelColor(device, 160, 120);
7367 ok(color == 0x00ffffff,
7368 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7369 color = getPixelColor(device, 160, 360);
7370 ok(color == 0x000000ff || !ub_ok,
7371 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7372 color = getPixelColor(device, 480, 120);
7373 ok(color == 0x000000ff || !ub_ok,
7374 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7375 } else {
7376 color = getPixelColor(device, 480, 360);
7377 ok(color == 0x000000ff,
7378 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7379 color = getPixelColor(device, 160, 120);
7380 ok(color == 0x00ffffff,
7381 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7382 color = getPixelColor(device, 160, 360);
7383 ok(color == 0x00ff0000 || !ub_ok,
7384 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7385 color = getPixelColor(device, 480, 120);
7386 ok(color == 0x00ff0000 || !ub_ok,
7387 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7391 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7392 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7393 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7394 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7395 IDirect3DVertexBuffer9_Release(vb2);
7397 out:
7398 IDirect3DVertexBuffer9_Release(vb);
7399 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7400 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7401 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7402 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7403 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7404 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7405 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7408 struct vertex_float16color {
7409 float x, y, z;
7410 DWORD c1, c2;
7413 static void test_vshader_float16(IDirect3DDevice9 *device)
7415 HRESULT hr;
7416 DWORD color;
7417 void *data;
7418 static const D3DVERTEXELEMENT9 decl_elements[] = {
7419 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7420 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7421 D3DDECL_END()
7423 IDirect3DVertexDeclaration9 *vdecl = NULL;
7424 IDirect3DVertexBuffer9 *buffer = NULL;
7425 IDirect3DVertexShader9 *shader;
7426 DWORD shader_code[] = {
7427 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7428 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7429 0x90e40001, 0x0000ffff
7431 struct vertex_float16color quad[] = {
7432 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7433 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7434 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7435 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7437 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7438 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7439 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7440 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7442 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7443 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7444 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7445 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7447 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7448 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7449 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7450 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7453 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7454 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7456 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7457 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7458 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7459 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7460 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7461 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7463 hr = IDirect3DDevice9_BeginScene(device);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7465 if(SUCCEEDED(hr)) {
7466 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7467 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7469 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7471 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7473 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7475 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7477 hr = IDirect3DDevice9_EndScene(device);
7478 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7480 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7481 color = getPixelColor(device, 480, 360);
7482 ok(color == 0x00ff0000,
7483 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7484 color = getPixelColor(device, 160, 120);
7485 ok(color == 0x00000000,
7486 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7487 color = getPixelColor(device, 160, 360);
7488 ok(color == 0x0000ff00,
7489 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7490 color = getPixelColor(device, 480, 120);
7491 ok(color == 0x000000ff,
7492 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7497 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7498 D3DPOOL_MANAGED, &buffer, NULL);
7499 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7500 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7501 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7502 memcpy(data, quad, sizeof(quad));
7503 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7504 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7505 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7506 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7508 hr = IDirect3DDevice9_BeginScene(device);
7509 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7510 if(SUCCEEDED(hr)) {
7511 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7512 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7513 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7514 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7515 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7516 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7517 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7518 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7520 hr = IDirect3DDevice9_EndScene(device);
7521 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7524 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7525 color = getPixelColor(device, 480, 360);
7526 ok(color == 0x00ff0000,
7527 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7528 color = getPixelColor(device, 160, 120);
7529 ok(color == 0x00000000,
7530 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7531 color = getPixelColor(device, 160, 360);
7532 ok(color == 0x0000ff00,
7533 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7534 color = getPixelColor(device, 480, 120);
7535 ok(color == 0x000000ff,
7536 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7538 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7539 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7540 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7541 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7542 IDirect3DDevice9_SetVertexShader(device, NULL);
7543 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7545 IDirect3DVertexDeclaration9_Release(vdecl);
7546 IDirect3DVertexShader9_Release(shader);
7547 IDirect3DVertexBuffer9_Release(buffer);
7550 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7552 D3DCAPS9 caps;
7553 IDirect3DTexture9 *texture;
7554 HRESULT hr;
7555 D3DLOCKED_RECT rect;
7556 unsigned int x, y;
7557 DWORD *dst, color;
7558 const float quad[] = {
7559 -1.0, -1.0, 0.1, -0.2, -0.2,
7560 1.0, -1.0, 0.1, 1.2, -0.2,
7561 -1.0, 1.0, 0.1, -0.2, 1.2,
7562 1.0, 1.0, 0.1, 1.2, 1.2
7564 memset(&caps, 0, sizeof(caps));
7566 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7567 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7568 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7569 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7570 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7571 "Card has conditional NP2 support without power of two restriction set\n");
7572 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7573 return;
7574 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7575 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7576 return;
7579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7580 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7582 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7585 memset(&rect, 0, sizeof(rect));
7586 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7587 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7588 for(y = 0; y < 10; y++) {
7589 for(x = 0; x < 10; x++) {
7590 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7591 if(x == 0 || x == 9 || y == 0 || y == 9) {
7592 *dst = 0x00ff0000;
7593 } else {
7594 *dst = 0x000000ff;
7598 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7599 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7601 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7602 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7603 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7604 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7605 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7606 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7607 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7608 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7610 hr = IDirect3DDevice9_BeginScene(device);
7611 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7612 if(SUCCEEDED(hr)) {
7613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7614 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7616 hr = IDirect3DDevice9_EndScene(device);
7617 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7620 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7622 color = getPixelColor(device, 1, 1);
7623 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7624 color = getPixelColor(device, 639, 479);
7625 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7627 color = getPixelColor(device, 135, 101);
7628 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7629 color = getPixelColor(device, 140, 101);
7630 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7631 color = getPixelColor(device, 135, 105);
7632 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7633 color = getPixelColor(device, 140, 105);
7634 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7636 color = getPixelColor(device, 135, 376);
7637 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7638 color = getPixelColor(device, 140, 376);
7639 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7640 color = getPixelColor(device, 135, 379);
7641 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7642 color = getPixelColor(device, 140, 379);
7643 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7645 color = getPixelColor(device, 500, 101);
7646 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7647 color = getPixelColor(device, 504, 101);
7648 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7649 color = getPixelColor(device, 500, 105);
7650 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7651 color = getPixelColor(device, 504, 105);
7652 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7654 color = getPixelColor(device, 500, 376);
7655 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7656 color = getPixelColor(device, 504, 376);
7657 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7658 color = getPixelColor(device, 500, 380);
7659 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7660 color = getPixelColor(device, 504, 380);
7661 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7663 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7665 IDirect3DTexture9_Release(texture);
7668 static void vFace_register_test(IDirect3DDevice9 *device)
7670 HRESULT hr;
7671 DWORD color;
7672 const DWORD shader_code[] = {
7673 0xffff0300, /* ps_3_0 */
7674 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7675 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7676 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7677 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7678 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7679 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7680 0x0000ffff /* END */
7682 IDirect3DPixelShader9 *shader;
7683 IDirect3DTexture9 *texture;
7684 IDirect3DSurface9 *surface, *backbuffer;
7685 const float quad[] = {
7686 -1.0, -1.0, 0.1,
7687 1.0, -1.0, 0.1,
7688 -1.0, 0.0, 0.1,
7690 1.0, -1.0, 0.1,
7691 1.0, 0.0, 0.1,
7692 -1.0, 0.0, 0.1,
7694 -1.0, 0.0, 0.1,
7695 -1.0, 1.0, 0.1,
7696 1.0, 0.0, 0.1,
7698 1.0, 0.0, 0.1,
7699 -1.0, 1.0, 0.1,
7700 1.0, 1.0, 0.1,
7702 const float blit[] = {
7703 0.0, -1.0, 0.1, 0.0, 0.0,
7704 1.0, -1.0, 0.1, 1.0, 0.0,
7705 0.0, 1.0, 0.1, 0.0, 1.0,
7706 1.0, 1.0, 0.1, 1.0, 1.0,
7709 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7710 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7711 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7712 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7713 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7714 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7715 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7716 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7717 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7718 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7719 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7720 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7722 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7723 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7725 hr = IDirect3DDevice9_BeginScene(device);
7726 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7727 if(SUCCEEDED(hr)) {
7728 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7729 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7731 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7732 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7733 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7734 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7735 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7736 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7738 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7740 /* Blit the texture onto the back buffer to make it visible */
7741 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7742 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7743 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7744 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7745 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7746 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7747 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7748 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7749 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7750 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7753 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7755 hr = IDirect3DDevice9_EndScene(device);
7756 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7759 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7760 color = getPixelColor(device, 160, 360);
7761 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7762 color = getPixelColor(device, 160, 120);
7763 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7764 color = getPixelColor(device, 480, 360);
7765 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7766 color = getPixelColor(device, 480, 120);
7767 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7769 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7770 IDirect3DDevice9_SetTexture(device, 0, NULL);
7771 IDirect3DPixelShader9_Release(shader);
7772 IDirect3DSurface9_Release(surface);
7773 IDirect3DSurface9_Release(backbuffer);
7774 IDirect3DTexture9_Release(texture);
7777 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7779 HRESULT hr;
7780 DWORD color;
7781 int i;
7782 D3DCAPS9 caps;
7783 BOOL L6V5U5_supported = FALSE;
7784 IDirect3DTexture9 *tex1, *tex2;
7785 D3DLOCKED_RECT locked_rect;
7787 static const float quad[][7] = {
7788 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7789 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7790 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7791 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7794 static const D3DVERTEXELEMENT9 decl_elements[] = {
7795 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7796 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7797 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7798 D3DDECL_END()
7801 /* use asymmetric matrix to test loading */
7802 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7803 float scale, offset;
7805 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7806 IDirect3DTexture9 *texture = NULL;
7808 memset(&caps, 0, sizeof(caps));
7809 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7810 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7811 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7812 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7813 return;
7814 } else {
7815 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7816 * They report that it is not supported, but after that bump mapping works properly. So just test
7817 * if the format is generally supported, and check the BUMPENVMAP flag
7819 IDirect3D9 *d3d9;
7821 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7822 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7823 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7824 L6V5U5_supported = SUCCEEDED(hr);
7825 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7826 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7827 IDirect3D9_Release(d3d9);
7828 if(FAILED(hr)) {
7829 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7830 return;
7834 /* Generate the textures */
7835 generate_bumpmap_textures(device);
7837 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7838 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7839 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7840 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7841 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7842 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7843 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7844 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7846 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7847 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7848 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7849 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7850 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7851 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7853 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7854 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7855 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7856 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7857 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7858 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7860 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7861 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7863 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7864 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7866 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7867 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7870 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7871 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7872 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7873 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7875 hr = IDirect3DDevice9_BeginScene(device);
7876 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7881 hr = IDirect3DDevice9_EndScene(device);
7882 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7885 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7887 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7888 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7889 * But since testing the color match is not the purpose of the test don't be too picky
7891 color = getPixelColor(device, 320-32, 240);
7892 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7893 color = getPixelColor(device, 320+32, 240);
7894 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7895 color = getPixelColor(device, 320, 240-32);
7896 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7897 color = getPixelColor(device, 320, 240+32);
7898 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7899 color = getPixelColor(device, 320, 240);
7900 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7901 color = getPixelColor(device, 320+32, 240+32);
7902 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7903 color = getPixelColor(device, 320-32, 240+32);
7904 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7905 color = getPixelColor(device, 320+32, 240-32);
7906 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7907 color = getPixelColor(device, 320-32, 240-32);
7908 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7910 for(i = 0; i < 2; i++) {
7911 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7912 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7913 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7914 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7915 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7916 IDirect3DTexture9_Release(texture); /* To destroy it */
7919 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7920 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7921 goto cleanup;
7923 if(L6V5U5_supported == FALSE) {
7924 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7925 goto cleanup;
7928 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7929 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7930 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7931 * would only make this test more complicated
7933 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7934 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7935 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7938 memset(&locked_rect, 0, sizeof(locked_rect));
7939 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7940 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7941 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7942 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7943 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7945 memset(&locked_rect, 0, sizeof(locked_rect));
7946 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7947 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7948 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7949 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7950 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7952 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7953 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7954 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7955 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7957 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7958 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7959 scale = 2.0;
7960 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7961 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7962 offset = 0.1;
7963 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7964 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7966 hr = IDirect3DDevice9_BeginScene(device);
7967 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7968 if(SUCCEEDED(hr)) {
7969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7970 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7971 hr = IDirect3DDevice9_EndScene(device);
7972 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7975 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7976 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7977 color = getPixelColor(device, 320, 240);
7978 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7979 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7980 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7982 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7984 /* Check a result scale factor > 1.0 */
7985 scale = 10;
7986 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7987 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7988 offset = 10;
7989 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7990 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7992 hr = IDirect3DDevice9_BeginScene(device);
7993 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7994 if(SUCCEEDED(hr)) {
7995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7996 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7997 hr = IDirect3DDevice9_EndScene(device);
7998 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8000 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8001 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8002 color = getPixelColor(device, 320, 240);
8003 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8005 /* Check clamping in the scale factor calculation */
8006 scale = 1000;
8007 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8008 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8009 offset = -1;
8010 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8011 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8013 hr = IDirect3DDevice9_BeginScene(device);
8014 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8015 if(SUCCEEDED(hr)) {
8016 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8017 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8018 hr = IDirect3DDevice9_EndScene(device);
8019 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8021 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8022 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8023 color = getPixelColor(device, 320, 240);
8024 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8026 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8027 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8028 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8029 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8031 IDirect3DTexture9_Release(tex1);
8032 IDirect3DTexture9_Release(tex2);
8034 cleanup:
8035 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8036 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8037 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8038 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8040 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8041 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8042 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8045 static void stencil_cull_test(IDirect3DDevice9 *device) {
8046 HRESULT hr;
8047 IDirect3DSurface9 *depthstencil = NULL;
8048 D3DSURFACE_DESC desc;
8049 float quad1[] = {
8050 -1.0, -1.0, 0.1,
8051 0.0, -1.0, 0.1,
8052 -1.0, 0.0, 0.1,
8053 0.0, 0.0, 0.1,
8055 float quad2[] = {
8056 0.0, -1.0, 0.1,
8057 1.0, -1.0, 0.1,
8058 0.0, 0.0, 0.1,
8059 1.0, 0.0, 0.1,
8061 float quad3[] = {
8062 0.0, 0.0, 0.1,
8063 1.0, 0.0, 0.1,
8064 0.0, 1.0, 0.1,
8065 1.0, 1.0, 0.1,
8067 float quad4[] = {
8068 -1.0, 0.0, 0.1,
8069 0.0, 0.0, 0.1,
8070 -1.0, 1.0, 0.1,
8071 0.0, 1.0, 0.1,
8073 struct vertex painter[] = {
8074 {-1.0, -1.0, 0.0, 0x00000000},
8075 { 1.0, -1.0, 0.0, 0x00000000},
8076 {-1.0, 1.0, 0.0, 0x00000000},
8077 { 1.0, 1.0, 0.0, 0x00000000},
8079 WORD indices_cw[] = {0, 1, 3};
8080 WORD indices_ccw[] = {0, 2, 3};
8081 unsigned int i;
8082 DWORD color;
8084 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8085 if(depthstencil == NULL) {
8086 skip("No depth stencil buffer\n");
8087 return;
8089 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8090 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8091 IDirect3DSurface9_Release(depthstencil);
8092 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8093 skip("No 4 or 8 bit stencil surface\n");
8094 return;
8097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8098 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8099 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8104 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8108 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8113 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8122 /* First pass: Fill the stencil buffer with some values... */
8123 hr = IDirect3DDevice9_BeginScene(device);
8124 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8125 if(SUCCEEDED(hr))
8127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8128 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8130 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8131 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8132 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8137 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8138 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8139 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8140 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8141 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8144 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8145 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8146 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8147 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8148 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8153 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8154 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8155 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8157 hr = IDirect3DDevice9_EndScene(device);
8158 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8161 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8163 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8165 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8167 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8169 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8171 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8173 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8175 /* 2nd pass: Make the stencil values visible */
8176 hr = IDirect3DDevice9_BeginScene(device);
8177 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8178 if(SUCCEEDED(hr))
8180 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8181 for(i = 0; i < 16; i++) {
8182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8183 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8185 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8186 painter[1].diffuse = (i * 16);
8187 painter[2].diffuse = (i * 16);
8188 painter[3].diffuse = (i * 16);
8189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8190 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8192 hr = IDirect3DDevice9_EndScene(device);
8193 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8200 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8202 color = getPixelColor(device, 160, 420);
8203 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8204 color = getPixelColor(device, 160, 300);
8205 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8207 color = getPixelColor(device, 480, 420);
8208 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8209 color = getPixelColor(device, 480, 300);
8210 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8212 color = getPixelColor(device, 160, 180);
8213 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8214 color = getPixelColor(device, 160, 60);
8215 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8217 color = getPixelColor(device, 480, 180);
8218 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8219 color = getPixelColor(device, 480, 60);
8220 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8223 static void vpos_register_test(IDirect3DDevice9 *device)
8225 HRESULT hr;
8226 DWORD color;
8227 const DWORD shader_code[] = {
8228 0xffff0300, /* ps_3_0 */
8229 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8230 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8231 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8232 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8233 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8234 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8235 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8236 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8237 0x0000ffff /* end */
8239 const DWORD shader_frac_code[] = {
8240 0xffff0300, /* ps_3_0 */
8241 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8242 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8243 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8244 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8245 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8246 0x0000ffff /* end */
8248 IDirect3DPixelShader9 *shader, *shader_frac;
8249 IDirect3DSurface9 *surface = NULL, *backbuffer;
8250 const float quad[] = {
8251 -1.0, -1.0, 0.1, 0.0, 0.0,
8252 1.0, -1.0, 0.1, 1.0, 0.0,
8253 -1.0, 1.0, 0.1, 0.0, 1.0,
8254 1.0, 1.0, 0.1, 1.0, 1.0,
8256 D3DLOCKED_RECT lr;
8257 float constant[4] = {1.0, 0.0, 320, 240};
8258 DWORD *pos;
8260 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8262 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8264 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8265 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8266 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8267 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8268 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8269 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8270 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8271 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8273 hr = IDirect3DDevice9_BeginScene(device);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8275 if(SUCCEEDED(hr)) {
8276 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8277 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8279 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8280 hr = IDirect3DDevice9_EndScene(device);
8281 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8284 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8285 /* This has to be pixel exact */
8286 color = getPixelColor(device, 319, 239);
8287 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8288 color = getPixelColor(device, 320, 239);
8289 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8290 color = getPixelColor(device, 319, 240);
8291 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8292 color = getPixelColor(device, 320, 240);
8293 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8295 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8296 &surface, NULL);
8297 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8298 hr = IDirect3DDevice9_BeginScene(device);
8299 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8300 if(SUCCEEDED(hr)) {
8301 constant[2] = 16; constant[3] = 16;
8302 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8304 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8307 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8308 hr = IDirect3DDevice9_EndScene(device);
8309 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8311 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8312 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8314 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8315 color = *pos & 0x00ffffff;
8316 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8317 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8318 color = *pos & 0x00ffffff;
8319 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8320 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8321 color = *pos & 0x00ffffff;
8322 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8323 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8324 color = *pos & 0x00ffffff;
8325 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8327 hr = IDirect3DSurface9_UnlockRect(surface);
8328 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8330 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8331 * have full control over the multisampling setting inside this test
8333 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8334 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8335 hr = IDirect3DDevice9_BeginScene(device);
8336 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8337 if(SUCCEEDED(hr)) {
8338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8339 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8341 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8342 hr = IDirect3DDevice9_EndScene(device);
8343 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8345 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8346 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8348 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8349 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8351 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8352 color = *pos & 0x00ffffff;
8353 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8355 hr = IDirect3DSurface9_UnlockRect(surface);
8356 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8358 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8359 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8360 IDirect3DPixelShader9_Release(shader);
8361 IDirect3DPixelShader9_Release(shader_frac);
8362 if(surface) IDirect3DSurface9_Release(surface);
8363 IDirect3DSurface9_Release(backbuffer);
8366 static void pointsize_test(IDirect3DDevice9 *device)
8368 HRESULT hr;
8369 D3DCAPS9 caps;
8370 D3DMATRIX matrix;
8371 D3DMATRIX identity;
8372 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8373 DWORD color;
8375 const float vertices[] = {
8376 64, 64, 0.1,
8377 128, 64, 0.1,
8378 192, 64, 0.1,
8379 256, 64, 0.1,
8380 320, 64, 0.1,
8381 384, 64, 0.1,
8382 448, 64, 0.1,
8383 512, 64, 0.1,
8384 576, 64, 0.1,
8387 /* 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 */
8388 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;
8389 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;
8390 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;
8391 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;
8393 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;
8394 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;
8395 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;
8396 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;
8398 memset(&caps, 0, sizeof(caps));
8399 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8400 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8401 if(caps.MaxPointSize < 32.0) {
8402 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8403 return;
8406 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8407 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8408 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8410 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8412 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8413 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8415 hr = IDirect3DDevice9_BeginScene(device);
8416 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8417 if(SUCCEEDED(hr)) {
8418 ptsize = 16.0;
8419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8420 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8422 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8424 ptsize = 32.0;
8425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8428 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8430 ptsize = 31.5;
8431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8432 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8434 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8436 if(caps.MaxPointSize >= 64.0) {
8437 ptsize = 64.0;
8438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8441 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8443 ptsize = 63.75;
8444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8447 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8450 ptsize = 1.0;
8451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8456 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8457 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8458 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemin_orig));
8459 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8461 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8462 ptsize = 16.0;
8463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8464 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8465 ptsize = 1.0;
8466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8467 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8469 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8471 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8472 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8474 ptsize = 4.0;
8475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8476 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8477 ptsize = 16.0;
8478 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8479 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8481 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8484 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8486 /* pointsize < pointsize_min < pointsize_max?
8487 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8489 ptsize = 1.0;
8490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8491 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8492 ptsize = 16.0;
8493 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8494 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8499 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8501 hr = IDirect3DDevice9_EndScene(device);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8504 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8505 color = getPixelColor(device, 64-9, 64-9);
8506 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8507 color = getPixelColor(device, 64-8, 64-8);
8508 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8509 color = getPixelColor(device, 64-7, 64-7);
8510 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8511 color = getPixelColor(device, 64+7, 64+7);
8512 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8513 color = getPixelColor(device, 64+8, 64+8);
8514 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8515 color = getPixelColor(device, 64+9, 64+9);
8516 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8518 color = getPixelColor(device, 128-17, 64-17);
8519 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8520 color = getPixelColor(device, 128-16, 64-16);
8521 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8522 color = getPixelColor(device, 128-15, 64-15);
8523 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8524 color = getPixelColor(device, 128+15, 64+15);
8525 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8526 color = getPixelColor(device, 128+16, 64+16);
8527 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8528 color = getPixelColor(device, 128+17, 64+17);
8529 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8531 color = getPixelColor(device, 192-17, 64-17);
8532 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8533 color = getPixelColor(device, 192-16, 64-16);
8534 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8535 color = getPixelColor(device, 192-15, 64-15);
8536 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8537 color = getPixelColor(device, 192+15, 64+15);
8538 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8539 color = getPixelColor(device, 192+16, 64+16);
8540 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8541 color = getPixelColor(device, 192+17, 64+17);
8542 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8544 if(caps.MaxPointSize >= 64.0) {
8545 color = getPixelColor(device, 256-33, 64-33);
8546 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8547 color = getPixelColor(device, 256-32, 64-32);
8548 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8549 color = getPixelColor(device, 256-31, 64-31);
8550 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8551 color = getPixelColor(device, 256+31, 64+31);
8552 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8553 color = getPixelColor(device, 256+32, 64+32);
8554 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8555 color = getPixelColor(device, 256+33, 64+33);
8556 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8558 color = getPixelColor(device, 384-33, 64-33);
8559 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8560 color = getPixelColor(device, 384-32, 64-32);
8561 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8562 color = getPixelColor(device, 384-31, 64-31);
8563 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8564 color = getPixelColor(device, 384+31, 64+31);
8565 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8566 color = getPixelColor(device, 384+32, 64+32);
8567 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8568 color = getPixelColor(device, 384+33, 64+33);
8569 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8572 color = getPixelColor(device, 320-1, 64-1);
8573 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8574 color = getPixelColor(device, 320-0, 64-0);
8575 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8576 color = getPixelColor(device, 320+1, 64+1);
8577 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8579 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8580 color = getPixelColor(device, 448-4, 64-4);
8581 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8582 color = getPixelColor(device, 448+4, 64+4);
8583 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8585 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8586 color = getPixelColor(device, 512-4, 64-4);
8587 ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8588 color = getPixelColor(device, 512+4, 64+4);
8589 ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8591 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8592 * Don't be overly picky - just show that the point is bigger than 1 pixel
8594 color = getPixelColor(device, 576-4, 64-4);
8595 ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8596 color = getPixelColor(device, 576+4, 64+4);
8597 ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8599 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8600 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8601 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8602 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8605 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8607 HRESULT hr;
8608 IDirect3DPixelShader9 *ps;
8609 IDirect3DTexture9 *tex1, *tex2;
8610 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8611 D3DCAPS9 caps;
8612 DWORD color;
8613 DWORD shader_code[] = {
8614 0xffff0300, /* ps_3_0 */
8615 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8616 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8617 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8618 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8619 0x0000ffff /* END */
8621 float quad[] = {
8622 -1.0, -1.0, 0.1,
8623 1.0, -1.0, 0.1,
8624 -1.0, 1.0, 0.1,
8625 1.0, 1.0, 0.1,
8627 float texquad[] = {
8628 -1.0, -1.0, 0.1, 0.0, 0.0,
8629 0.0, -1.0, 0.1, 1.0, 0.0,
8630 -1.0, 1.0, 0.1, 0.0, 1.0,
8631 0.0, 1.0, 0.1, 1.0, 1.0,
8633 0.0, -1.0, 0.1, 0.0, 0.0,
8634 1.0, -1.0, 0.1, 1.0, 0.0,
8635 0.0, 1.0, 0.1, 0.0, 1.0,
8636 1.0, 1.0, 0.1, 1.0, 1.0,
8639 memset(&caps, 0, sizeof(caps));
8640 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8641 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8642 if(caps.NumSimultaneousRTs < 2) {
8643 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8644 return;
8647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8648 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8650 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8651 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8652 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8653 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8654 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8655 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8657 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8658 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8659 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8660 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8661 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8662 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8664 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8665 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8666 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8668 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8669 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8673 hr = IDirect3DDevice9_BeginScene(device);
8674 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8675 if(SUCCEEDED(hr)) {
8676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8677 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8679 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8680 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8681 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8682 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8683 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8684 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8685 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8686 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8688 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8689 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8690 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8691 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8693 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8694 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8696 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8698 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8699 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8701 hr = IDirect3DDevice9_EndScene(device);
8702 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8705 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8706 color = getPixelColor(device, 160, 240);
8707 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8708 color = getPixelColor(device, 480, 240);
8709 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8711 IDirect3DPixelShader9_Release(ps);
8712 IDirect3DTexture9_Release(tex1);
8713 IDirect3DTexture9_Release(tex2);
8714 IDirect3DSurface9_Release(surf1);
8715 IDirect3DSurface9_Release(surf2);
8716 IDirect3DSurface9_Release(backbuf);
8719 struct formats {
8720 const char *fmtName;
8721 D3DFORMAT textureFormat;
8722 DWORD resultColorBlending;
8723 DWORD resultColorNoBlending;
8726 const struct formats test_formats[] = {
8727 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8728 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8729 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8730 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8731 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8732 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8733 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8734 { NULL, 0 }
8737 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8739 HRESULT hr;
8740 IDirect3DTexture9 *offscreenTexture = NULL;
8741 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8742 IDirect3D9 *d3d = NULL;
8743 DWORD color;
8744 DWORD r0, g0, b0, r1, g1, b1;
8745 int fmt_index;
8747 static const float quad[][5] = {
8748 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8749 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8750 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8751 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8754 /* Quad with R=0x10, G=0x20 */
8755 static const struct vertex quad1[] = {
8756 {-1.0f, -1.0f, 0.1f, 0x80102000},
8757 {-1.0f, 1.0f, 0.1f, 0x80102000},
8758 { 1.0f, -1.0f, 0.1f, 0x80102000},
8759 { 1.0f, 1.0f, 0.1f, 0x80102000},
8762 /* Quad with R=0x20, G=0x10 */
8763 static const struct vertex quad2[] = {
8764 {-1.0f, -1.0f, 0.1f, 0x80201000},
8765 {-1.0f, 1.0f, 0.1f, 0x80201000},
8766 { 1.0f, -1.0f, 0.1f, 0x80201000},
8767 { 1.0f, 1.0f, 0.1f, 0x80201000},
8770 IDirect3DDevice9_GetDirect3D(device, &d3d);
8772 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8773 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8774 if(!backbuffer) {
8775 goto out;
8778 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8780 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8781 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8782 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8783 continue;
8786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8787 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8789 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8790 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8791 if(!offscreenTexture) {
8792 continue;
8795 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8796 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8797 if(!offscreen) {
8798 continue;
8801 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8802 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8805 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8807 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8808 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8809 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8810 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8811 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8813 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8815 /* Below we will draw two quads with different colors and try to blend them together.
8816 * The result color is compared with the expected outcome.
8818 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8819 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8820 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8821 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8822 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8825 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8827 /* Draw a quad using color 0x0010200 */
8828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8829 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8831 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8833 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8835 /* Draw a quad using color 0x0020100 */
8836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8837 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8841 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8843 /* We don't want to blend the result on the backbuffer */
8844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8847 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8848 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8849 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8850 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8851 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8853 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8854 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8856 /* This time with the texture */
8857 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8858 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8860 IDirect3DDevice9_EndScene(device);
8862 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8865 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8866 /* Compare the color of the center quad with our expectation */
8867 color = getPixelColor(device, 320, 240);
8868 r0 = (color & 0x00ff0000) >> 16;
8869 g0 = (color & 0x0000ff00) >> 8;
8870 b0 = (color & 0x000000ff) >> 0;
8872 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8873 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8874 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8876 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8877 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8878 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8879 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8880 } else {
8881 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8882 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8883 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8884 color = getPixelColor(device, 320, 240);
8885 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);
8888 IDirect3DDevice9_SetTexture(device, 0, NULL);
8889 if(offscreenTexture) {
8890 IDirect3DTexture9_Release(offscreenTexture);
8892 if(offscreen) {
8893 IDirect3DSurface9_Release(offscreen);
8897 out:
8898 /* restore things */
8899 if(backbuffer) {
8900 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8901 IDirect3DSurface9_Release(backbuffer);
8905 static void tssargtemp_test(IDirect3DDevice9 *device)
8907 HRESULT hr;
8908 DWORD color;
8909 static const struct vertex quad[] = {
8910 {-1.0, -1.0, 0.1, 0x00ff0000},
8911 { 1.0, -1.0, 0.1, 0x00ff0000},
8912 {-1.0, 1.0, 0.1, 0x00ff0000},
8913 { 1.0, 1.0, 0.1, 0x00ff0000}
8915 D3DCAPS9 caps;
8917 memset(&caps, 0, sizeof(caps));
8918 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8919 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8920 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8921 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8922 return;
8925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8926 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8928 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8929 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8930 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8931 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8933 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8934 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8935 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8936 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8937 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8938 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8940 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8941 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8942 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8943 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8944 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8945 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8947 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8948 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8951 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8952 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8953 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8955 hr = IDirect3DDevice9_BeginScene(device);
8956 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8957 if(SUCCEEDED(hr)) {
8959 hr = IDirect3DDevice9_EndScene(device);
8960 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8962 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8964 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8965 color = getPixelColor(device, 320, 240);
8966 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8968 /* Set stage 1 back to default */
8969 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8970 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8971 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8972 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8973 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8974 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8975 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8976 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8977 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8978 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8981 struct testdata
8983 DWORD idxVertex; /* number of instances in the first stream */
8984 DWORD idxColor; /* number of instances in the second stream */
8985 DWORD idxInstance; /* should be 1 ?? */
8986 DWORD color1; /* color 1 instance */
8987 DWORD color2; /* color 2 instance */
8988 DWORD color3; /* color 3 instance */
8989 DWORD color4; /* color 4 instance */
8990 WORD strVertex; /* specify which stream to use 0-2*/
8991 WORD strColor;
8992 WORD strInstance;
8995 static const struct testdata testcases[]=
8997 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8998 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8999 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9000 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9001 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9002 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9003 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9004 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9005 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9006 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9007 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9008 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9009 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9010 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9011 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9013 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9014 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9018 /* Drawing Indexed Geometry with instances*/
9019 static void stream_test(IDirect3DDevice9 *device)
9021 IDirect3DVertexBuffer9 *vb = NULL;
9022 IDirect3DVertexBuffer9 *vb2 = NULL;
9023 IDirect3DVertexBuffer9 *vb3 = NULL;
9024 IDirect3DIndexBuffer9 *ib = NULL;
9025 IDirect3DVertexDeclaration9 *pDecl = NULL;
9026 IDirect3DVertexShader9 *shader = NULL;
9027 HRESULT hr;
9028 BYTE *data;
9029 DWORD color;
9030 DWORD ind;
9031 unsigned i;
9033 const DWORD shader_code[] =
9035 0xfffe0101, /* vs_1_1 */
9036 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9037 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9038 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9039 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9040 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9041 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9042 0x0000ffff
9045 const float quad[][3] =
9047 {-0.5f, -0.5f, 1.1f}, /*0 */
9048 {-0.5f, 0.5f, 1.1f}, /*1 */
9049 { 0.5f, -0.5f, 1.1f}, /*2 */
9050 { 0.5f, 0.5f, 1.1f}, /*3 */
9053 const float vertcolor[][4] =
9055 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9056 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9057 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9058 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9061 /* 4 position for 4 instances */
9062 const float instancepos[][3] =
9064 {-0.6f,-0.6f, 0.0f},
9065 { 0.6f,-0.6f, 0.0f},
9066 { 0.6f, 0.6f, 0.0f},
9067 {-0.6f, 0.6f, 0.0f},
9070 short indices[] = {0, 1, 2, 1, 2, 3};
9072 D3DVERTEXELEMENT9 decl[] =
9074 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9075 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9076 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9077 D3DDECL_END()
9080 /* set the default value because it isn't done in wine? */
9081 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9082 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9084 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9085 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9086 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9088 /* check wrong cases */
9089 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9090 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9091 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9092 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9093 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9094 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9095 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9096 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9097 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9098 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9099 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9100 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9101 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9102 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9103 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9104 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9105 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9106 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9107 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9108 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9110 /* set the default value back */
9111 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9112 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9114 /* create all VertexBuffers*/
9115 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9116 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9117 if(!vb) {
9118 skip("Failed to create a vertex buffer\n");
9119 return;
9121 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9122 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9123 if(!vb2) {
9124 skip("Failed to create a vertex buffer\n");
9125 goto out;
9127 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9128 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9129 if(!vb3) {
9130 skip("Failed to create a vertex buffer\n");
9131 goto out;
9134 /* create IndexBuffer*/
9135 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9136 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9137 if(!ib) {
9138 skip("Failed to create a index buffer\n");
9139 goto out;
9142 /* copy all Buffers (Vertex + Index)*/
9143 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9144 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9145 memcpy(data, quad, sizeof(quad));
9146 hr = IDirect3DVertexBuffer9_Unlock(vb);
9147 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9148 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9149 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9150 memcpy(data, vertcolor, sizeof(vertcolor));
9151 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9152 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9153 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9154 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9155 memcpy(data, instancepos, sizeof(instancepos));
9156 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9157 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9158 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9159 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9160 memcpy(data, indices, sizeof(indices));
9161 hr = IDirect3DIndexBuffer9_Unlock(ib);
9162 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9164 /* create VertexShader */
9165 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9166 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9167 if(!shader) {
9168 skip("Failed to create a vetex shader\n");
9169 goto out;
9172 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9173 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9175 hr = IDirect3DDevice9_SetIndices(device, ib);
9176 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9178 /* run all tests */
9179 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9181 struct testdata act = testcases[i];
9182 decl[0].Stream = act.strVertex;
9183 decl[1].Stream = act.strColor;
9184 decl[2].Stream = act.strInstance;
9185 /* create VertexDeclarations */
9186 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9187 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9190 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9192 hr = IDirect3DDevice9_BeginScene(device);
9193 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9194 if(SUCCEEDED(hr))
9196 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9197 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9199 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9200 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9201 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9202 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9204 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9205 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9206 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9207 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9209 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9210 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9211 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9212 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9214 /* don't know if this is right (1*3 and 4*1)*/
9215 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9216 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9217 hr = IDirect3DDevice9_EndScene(device);
9218 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9220 /* set all StreamSource && StreamSourceFreq back to default */
9221 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9222 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9223 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9224 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9225 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9226 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9227 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9228 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9229 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9230 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9231 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9232 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9235 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9236 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9238 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9239 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9241 color = getPixelColor(device, 160, 360);
9242 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9243 color = getPixelColor(device, 480, 360);
9244 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9245 color = getPixelColor(device, 480, 120);
9246 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9247 color = getPixelColor(device, 160, 120);
9248 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9251 hr = IDirect3DDevice9_SetIndices(device, NULL);
9252 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9254 out:
9255 if(vb) IDirect3DVertexBuffer9_Release(vb);
9256 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9257 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9258 if(ib)IDirect3DIndexBuffer9_Release(ib);
9259 if(shader)IDirect3DVertexShader9_Release(shader);
9262 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9263 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9264 IDirect3DTexture9 *dsttex = NULL;
9265 HRESULT hr;
9266 DWORD color;
9267 D3DRECT r1 = {0, 0, 50, 50 };
9268 D3DRECT r2 = {50, 0, 100, 50 };
9269 D3DRECT r3 = {50, 50, 100, 100};
9270 D3DRECT r4 = {0, 50, 50, 100};
9271 const float quad[] = {
9272 -1.0, -1.0, 0.1, 0.0, 0.0,
9273 1.0, -1.0, 0.1, 1.0, 0.0,
9274 -1.0, 1.0, 0.1, 0.0, 1.0,
9275 1.0, 1.0, 0.1, 1.0, 1.0,
9278 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9279 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9281 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9282 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9283 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9284 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9286 if(!src || !dsttex) {
9287 skip("One or more test resources could not be created\n");
9288 goto cleanup;
9291 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9292 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9294 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9295 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9297 /* Clear the StretchRect destination for debugging */
9298 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9300 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9301 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9303 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9306 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9307 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9308 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9310 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9311 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9312 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9313 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9315 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9316 * the target -> texture GL blit path
9318 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9319 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9320 IDirect3DSurface9_Release(dst);
9322 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9325 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9326 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9327 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9328 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9329 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9330 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9331 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9332 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9334 hr = IDirect3DDevice9_BeginScene(device);
9335 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9336 if(SUCCEEDED(hr)) {
9337 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9338 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9339 hr = IDirect3DDevice9_EndScene(device);
9340 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9343 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9344 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9345 color = getPixelColor(device, 160, 360);
9346 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9347 color = getPixelColor(device, 480, 360);
9348 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9349 color = getPixelColor(device, 480, 120);
9350 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9351 color = getPixelColor(device, 160, 120);
9352 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9354 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9355 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9356 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9357 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9359 cleanup:
9360 if(src) IDirect3DSurface9_Release(src);
9361 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9362 if(dsttex) IDirect3DTexture9_Release(dsttex);
9365 static void texop_test(IDirect3DDevice9 *device)
9367 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9368 IDirect3DTexture9 *texture = NULL;
9369 D3DLOCKED_RECT locked_rect;
9370 D3DCOLOR color;
9371 D3DCAPS9 caps;
9372 HRESULT hr;
9373 unsigned i;
9375 static const struct {
9376 float x, y, z;
9377 float s, t;
9378 D3DCOLOR diffuse;
9379 } quad[] = {
9380 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9381 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9382 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9383 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9386 static const D3DVERTEXELEMENT9 decl_elements[] = {
9387 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9388 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9389 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9390 D3DDECL_END()
9393 static const struct {
9394 D3DTEXTUREOP op;
9395 const char *name;
9396 DWORD caps_flag;
9397 D3DCOLOR result;
9398 } test_data[] = {
9399 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9400 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9401 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9402 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9403 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9404 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9405 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9406 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9407 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9408 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9409 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9410 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9411 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9412 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9413 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9414 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9415 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9416 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9417 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9418 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9419 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9420 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9421 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9424 memset(&caps, 0, sizeof(caps));
9425 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9426 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9428 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9429 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9430 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9431 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9433 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9434 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9435 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9436 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9437 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9438 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9439 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9440 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9441 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9443 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9444 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9445 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9446 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9447 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9448 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9450 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9451 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9454 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9456 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9458 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9461 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9463 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9465 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9467 skip("tex operation %s not supported\n", test_data[i].name);
9468 continue;
9471 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9472 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9474 hr = IDirect3DDevice9_BeginScene(device);
9475 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9478 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9480 hr = IDirect3DDevice9_EndScene(device);
9481 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9483 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9484 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9486 color = getPixelColor(device, 320, 240);
9487 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9488 test_data[i].name, color, test_data[i].result);
9491 if (texture) IDirect3DTexture9_Release(texture);
9492 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9495 static void yuv_color_test(IDirect3DDevice9 *device) {
9496 HRESULT hr;
9497 IDirect3DSurface9 *surface = NULL, *target = NULL;
9498 unsigned int fmt, i;
9499 D3DFORMAT format;
9500 const char *fmt_string;
9501 D3DLOCKED_RECT lr;
9502 IDirect3D9 *d3d;
9503 HRESULT color;
9504 DWORD ref_color_left, ref_color_right;
9506 struct {
9507 DWORD in; /* The input color */
9508 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9509 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9510 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9511 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9512 } test_data[] = {
9513 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9514 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9515 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9516 * that
9518 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9519 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9520 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9521 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9522 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9523 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9524 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9525 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9526 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9527 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9528 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9529 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9530 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9531 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9533 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9534 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9535 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9536 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9539 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9540 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9541 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9542 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9544 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9545 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9547 for(fmt = 0; fmt < 2; fmt++) {
9548 if(fmt == 0) {
9549 format = D3DFMT_UYVY;
9550 fmt_string = "D3DFMT_UYVY";
9551 } else {
9552 format = D3DFMT_YUY2;
9553 fmt_string = "D3DFMT_YUY2";
9556 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9557 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9559 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9560 D3DRTYPE_SURFACE, format) != D3D_OK) {
9561 skip("%s is not supported\n", fmt_string);
9562 continue;
9565 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9566 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9567 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9569 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9570 if(fmt == 0) {
9571 ref_color_left = test_data[i].uyvy_left;
9572 ref_color_right = test_data[i].uyvy_right;
9573 } else {
9574 ref_color_left = test_data[i].yuy2_left;
9575 ref_color_right = test_data[i].yuy2_right;
9578 memset(&lr, 0, sizeof(lr));
9579 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9580 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9581 *((DWORD *) lr.pBits) = test_data[i].in;
9582 hr = IDirect3DSurface9_UnlockRect(surface);
9583 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9585 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9586 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9587 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9588 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9589 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9590 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9592 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9593 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9594 * want to add tests for the filtered pixels as well.
9596 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9597 * differently, so we need a max diff of 16
9599 color = getPixelColor(device, 40, 240);
9600 ok(color_match(color, ref_color_left, 16),
9601 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9602 test_data[i].in, color, ref_color_left, fmt_string);
9603 color = getPixelColor(device, 600, 240);
9604 ok(color_match(color, ref_color_right, 16),
9605 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9606 test_data[i].in, color, ref_color_right, fmt_string);
9608 IDirect3DSurface9_Release(surface);
9610 IDirect3DSurface9_Release(target);
9611 IDirect3D9_Release(d3d);
9614 static void texop_range_test(IDirect3DDevice9 *device)
9616 static const struct {
9617 float x, y, z;
9618 D3DCOLOR diffuse;
9619 } quad[] = {
9620 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9621 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9622 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9623 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9625 HRESULT hr;
9626 IDirect3DTexture9 *texture;
9627 D3DLOCKED_RECT locked_rect;
9628 D3DCAPS9 caps;
9629 DWORD color;
9631 /* We need ADD and SUBTRACT operations */
9632 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9633 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9634 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9635 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9637 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9638 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9641 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9642 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9643 /* Stage 1: result = diffuse(=1.0) + diffuse
9644 * stage 2: result = result - tfactor(= 0.5)
9646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9647 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9648 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9649 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9650 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9651 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9652 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9653 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9654 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9655 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9656 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9657 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9658 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9659 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9661 hr = IDirect3DDevice9_BeginScene(device);
9662 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9664 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9665 hr = IDirect3DDevice9_EndScene(device);
9666 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9667 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9668 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9670 color = getPixelColor(device, 320, 240);
9671 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9672 color);
9674 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9675 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9676 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9677 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9678 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9679 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9680 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9681 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9682 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9684 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9685 * stage 2: result = result + diffuse(1.0)
9687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9688 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9689 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9690 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9691 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9692 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9693 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9694 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9695 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9696 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9697 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9698 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9699 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9700 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9702 hr = IDirect3DDevice9_BeginScene(device);
9703 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9705 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9706 hr = IDirect3DDevice9_EndScene(device);
9707 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9708 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9709 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9711 color = getPixelColor(device, 320, 240);
9712 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9713 color);
9715 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9716 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9717 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9718 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9719 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9720 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9721 IDirect3DTexture9_Release(texture);
9724 static void alphareplicate_test(IDirect3DDevice9 *device) {
9725 struct vertex quad[] = {
9726 { -1.0, -1.0, 0.1, 0x80ff00ff },
9727 { 1.0, -1.0, 0.1, 0x80ff00ff },
9728 { -1.0, 1.0, 0.1, 0x80ff00ff },
9729 { 1.0, 1.0, 0.1, 0x80ff00ff },
9731 HRESULT hr;
9732 DWORD color;
9734 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9735 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9738 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9740 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9741 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9742 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9743 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9745 hr = IDirect3DDevice9_BeginScene(device);
9746 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9747 if(SUCCEEDED(hr)) {
9748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9749 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9750 hr = IDirect3DDevice9_EndScene(device);
9751 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9754 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9755 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9757 color = getPixelColor(device, 320, 240);
9758 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9759 color);
9761 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9762 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9766 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9767 HRESULT hr;
9768 D3DCAPS9 caps;
9769 DWORD color;
9770 struct vertex quad[] = {
9771 { -1.0, -1.0, 0.1, 0x408080c0 },
9772 { 1.0, -1.0, 0.1, 0x408080c0 },
9773 { -1.0, 1.0, 0.1, 0x408080c0 },
9774 { 1.0, 1.0, 0.1, 0x408080c0 },
9777 memset(&caps, 0, sizeof(caps));
9778 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9779 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9780 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9781 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9782 return;
9785 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9786 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9789 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9791 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9792 * mov r0.a, diffuse.a
9793 * mov r0, r0.a
9795 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9796 * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
9797 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9800 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9802 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9803 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9804 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9805 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9806 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9808 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9809 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9810 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9811 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9812 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9814 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9816 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9818 hr = IDirect3DDevice9_BeginScene(device);
9819 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9820 if(SUCCEEDED(hr)) {
9821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9823 hr = IDirect3DDevice9_EndScene(device);
9824 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9827 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9828 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9830 color = getPixelColor(device, 320, 240);
9831 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9832 color);
9834 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9835 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9837 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9838 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9839 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9842 static void zwriteenable_test(IDirect3DDevice9 *device) {
9843 HRESULT hr;
9844 DWORD color;
9845 struct vertex quad1[] = {
9846 { -1.0, -1.0, 0.1, 0x00ff0000},
9847 { -1.0, 1.0, 0.1, 0x00ff0000},
9848 { 1.0, -1.0, 0.1, 0x00ff0000},
9849 { 1.0, 1.0, 0.1, 0x00ff0000},
9851 struct vertex quad2[] = {
9852 { -1.0, -1.0, 0.9, 0x0000ff00},
9853 { -1.0, 1.0, 0.9, 0x0000ff00},
9854 { 1.0, -1.0, 0.9, 0x0000ff00},
9855 { 1.0, 1.0, 0.9, 0x0000ff00},
9858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9859 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9861 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9862 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9864 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9866 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9868 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9870 hr = IDirect3DDevice9_BeginScene(device);
9871 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9872 if(SUCCEEDED(hr)) {
9873 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9874 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9875 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9876 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9877 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9878 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9881 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9882 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9883 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9885 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9887 hr = IDirect3DDevice9_EndScene(device);
9888 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9891 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9892 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9893 color = getPixelColor(device, 320, 240);
9894 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9895 color);
9897 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9898 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9901 static void alphatest_test(IDirect3DDevice9 *device) {
9902 #define ALPHATEST_PASSED 0x0000ff00
9903 #define ALPHATEST_FAILED 0x00ff0000
9904 struct {
9905 D3DCMPFUNC func;
9906 DWORD color_less;
9907 DWORD color_equal;
9908 DWORD color_greater;
9909 } testdata[] = {
9910 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
9911 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
9912 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
9913 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
9914 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
9915 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
9916 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
9917 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
9919 unsigned int i, j;
9920 HRESULT hr;
9921 DWORD color;
9922 struct vertex quad[] = {
9923 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
9924 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
9925 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
9926 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
9928 D3DCAPS9 caps;
9930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
9931 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9932 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9933 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9935 for(j = 0; j < 2; j++) {
9936 if(j == 1) {
9937 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
9938 * the alpha test either for performance reasons(floating point RTs) or to work
9939 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
9940 * codepath for ffp and shader in this case, and the test should cover both
9942 IDirect3DPixelShader9 *ps;
9943 DWORD shader_code[] = {
9944 0xffff0101, /* ps_1_1 */
9945 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9946 0x0000ffff /* end */
9948 memset(&caps, 0, sizeof(caps));
9949 IDirect3DDevice9_GetDeviceCaps(device, &caps);
9950 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
9951 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
9952 break;
9955 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9956 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
9957 IDirect3DDevice9_SetPixelShader(device, ps);
9958 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
9959 IDirect3DPixelShader9_Release(ps);
9962 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
9963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
9964 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9966 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
9967 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
9969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9970 hr = IDirect3DDevice9_BeginScene(device);
9971 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9972 if(SUCCEEDED(hr)) {
9973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9974 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9975 hr = IDirect3DDevice9_EndScene(device);
9976 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9978 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9979 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9980 color = getPixelColor(device, 320, 240);
9981 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
9982 color, testdata[i].color_less, testdata[i].func);
9984 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
9985 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
9987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9988 hr = IDirect3DDevice9_BeginScene(device);
9989 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9990 if(SUCCEEDED(hr)) {
9991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9992 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9993 hr = IDirect3DDevice9_EndScene(device);
9994 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9997 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9998 color = getPixelColor(device, 320, 240);
9999 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10000 color, testdata[i].color_equal, testdata[i].func);
10002 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10003 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10004 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10005 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10006 hr = IDirect3DDevice9_BeginScene(device);
10007 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10008 if(SUCCEEDED(hr)) {
10009 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10010 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10011 hr = IDirect3DDevice9_EndScene(device);
10012 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10014 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10015 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10016 color = getPixelColor(device, 320, 240);
10017 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10018 color, testdata[i].color_greater, testdata[i].func);
10022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10023 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10024 IDirect3DDevice9_SetPixelShader(device, NULL);
10025 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10028 START_TEST(visual)
10030 IDirect3DDevice9 *device_ptr;
10031 D3DCAPS9 caps;
10032 HRESULT hr;
10033 DWORD color;
10035 d3d9_handle = LoadLibraryA("d3d9.dll");
10036 if (!d3d9_handle)
10038 skip("Could not load d3d9.dll\n");
10039 return;
10042 device_ptr = init_d3d9();
10043 if (!device_ptr)
10045 skip("Creating the device failed\n");
10046 return;
10049 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10051 /* Check for the reliability of the returned data */
10052 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10053 if(FAILED(hr))
10055 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10056 goto cleanup;
10058 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10060 color = getPixelColor(device_ptr, 1, 1);
10061 if(color !=0x00ff0000)
10063 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10064 goto cleanup;
10067 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10068 if(FAILED(hr))
10070 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10071 goto cleanup;
10073 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10075 color = getPixelColor(device_ptr, 639, 479);
10076 if(color != 0x0000ddee)
10078 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10079 goto cleanup;
10082 /* Now execute the real tests */
10083 stretchrect_test(device_ptr);
10084 lighting_test(device_ptr);
10085 clear_test(device_ptr);
10086 fog_test(device_ptr);
10087 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10089 test_cube_wrap(device_ptr);
10090 } else {
10091 skip("No cube texture support\n");
10093 z_range_test(device_ptr);
10094 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10096 maxmip_test(device_ptr);
10098 else
10100 skip("No mipmap support\n");
10102 offscreen_test(device_ptr);
10103 alpha_test(device_ptr);
10104 shademode_test(device_ptr);
10105 srgbtexture_test(device_ptr);
10106 release_buffer_test(device_ptr);
10107 float_texture_test(device_ptr);
10108 g16r16_texture_test(device_ptr);
10109 pixelshader_blending_test(device_ptr);
10110 texture_transform_flags_test(device_ptr);
10111 autogen_mipmap_test(device_ptr);
10112 fixed_function_decl_test(device_ptr);
10113 conditional_np2_repeat_test(device_ptr);
10114 fixed_function_bumpmap_test(device_ptr);
10115 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10116 stencil_cull_test(device_ptr);
10117 } else {
10118 skip("No two sided stencil support\n");
10120 pointsize_test(device_ptr);
10121 tssargtemp_test(device_ptr);
10122 np2_stretch_rect_test(device_ptr);
10123 yuv_color_test(device_ptr);
10124 zwriteenable_test(device_ptr);
10125 alphatest_test(device_ptr);
10127 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10129 test_constant_clamp_vs(device_ptr);
10130 test_compare_instructions(device_ptr);
10132 else skip("No vs_1_1 support\n");
10134 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10136 test_mova(device_ptr);
10137 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10138 test_vshader_input(device_ptr);
10139 test_vshader_float16(device_ptr);
10140 stream_test(device_ptr);
10141 } else {
10142 skip("No vs_3_0 support\n");
10145 else skip("No vs_2_0 support\n");
10147 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10149 fog_with_shader_test(device_ptr);
10150 fog_srgbwrite_test(device_ptr);
10152 else skip("No vs_1_1 and ps_1_1 support\n");
10154 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10156 texbem_test(device_ptr);
10157 texdepth_test(device_ptr);
10158 texkill_test(device_ptr);
10159 x8l8v8u8_test(device_ptr);
10160 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10161 constant_clamp_ps_test(device_ptr);
10162 cnd_test(device_ptr);
10163 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10164 dp2add_ps_test(device_ptr);
10165 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10166 nested_loop_test(device_ptr);
10167 fixed_function_varying_test(device_ptr);
10168 vFace_register_test(device_ptr);
10169 vpos_register_test(device_ptr);
10170 multiple_rendertargets_test(device_ptr);
10171 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10172 vshader_version_varying_test(device_ptr);
10173 pshader_version_varying_test(device_ptr);
10174 } else {
10175 skip("No vs_3_0 support\n");
10177 } else {
10178 skip("No ps_3_0 support\n");
10180 } else {
10181 skip("No ps_2_0 support\n");
10185 else skip("No ps_1_1 support\n");
10187 texop_test(device_ptr);
10188 texop_range_test(device_ptr);
10189 alphareplicate_test(device_ptr);
10190 dp3_alpha_test(device_ptr);
10192 cleanup:
10193 if(device_ptr) {
10194 ULONG ref;
10196 D3DPRESENT_PARAMETERS present_parameters;
10197 IDirect3DSwapChain9 *swapchain;
10198 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10199 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10200 IDirect3DSwapChain9_Release(swapchain);
10201 ref = IDirect3DDevice9_Release(device_ptr);
10202 DestroyWindow(present_parameters.hDeviceWindow);
10203 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);