push 5c57339901c8d80068fee18365e7574a1e8d922a
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob092cbe96879668b15d445314884f1ed060ba3c8f
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 ok(identifier.Description[0] != '\0', "Empty driver description\n");
186 trace("Device name string: \"%s\"\n", identifier.DeviceName);
187 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
188 trace("Driver version %d.%d.%d.%d\n",
189 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
190 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
192 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
193 if(FAILED(hr)) {
194 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
195 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196 if(FAILED(hr)) {
197 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
200 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
202 return device_ptr;
205 struct vertex
207 float x, y, z;
208 DWORD diffuse;
211 struct tvertex
213 float x, y, z, rhw;
214 DWORD diffuse;
217 struct nvertex
219 float x, y, z;
220 float nx, ny, nz;
221 DWORD diffuse;
224 static void lighting_test(IDirect3DDevice9 *device)
226 HRESULT hr;
227 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
228 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
229 DWORD color;
230 D3DMATERIAL9 material, old_material;
231 DWORD cop, carg;
233 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
234 0.0f, 1.0f, 0.0f, 0.0f,
235 0.0f, 0.0f, 1.0f, 0.0f,
236 0.0f, 0.0f, 0.0f, 1.0f };
238 struct vertex unlitquad[] =
240 {-1.0f, -1.0f, 0.1f, 0xffff0000},
241 {-1.0f, 0.0f, 0.1f, 0xffff0000},
242 { 0.0f, 0.0f, 0.1f, 0xffff0000},
243 { 0.0f, -1.0f, 0.1f, 0xffff0000},
245 struct vertex litquad[] =
247 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
248 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
249 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
250 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
252 struct nvertex unlitnquad[] =
254 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
255 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
256 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
257 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
259 struct nvertex litnquad[] =
261 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
262 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
263 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
264 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
266 WORD Indices[] = {0, 1, 2, 2, 3, 0};
268 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
269 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
271 /* Setup some states that may cause issues */
272 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
297 hr = IDirect3DDevice9_SetFVF(device, 0);
298 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetFVF(device, fvf);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
303 hr = IDirect3DDevice9_BeginScene(device);
304 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
305 if(hr == D3D_OK)
307 /* No lights are defined... That means, lit vertices should be entirely black */
308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
310 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
312 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
318 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
320 hr = IDirect3DDevice9_SetFVF(device, nfvf);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
324 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
327 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
331 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
332 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
333 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
335 IDirect3DDevice9_EndScene(device);
336 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
339 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
341 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
342 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
343 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
344 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
345 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
346 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
347 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
348 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
350 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
351 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
352 memset(&material, 0, sizeof(material));
353 material.Diffuse.r = 0.0;
354 material.Diffuse.g = 0.0;
355 material.Diffuse.b = 0.0;
356 material.Diffuse.a = 1.0;
357 material.Ambient.r = 0.0;
358 material.Ambient.g = 0.0;
359 material.Ambient.b = 0.0;
360 material.Ambient.a = 0.0;
361 material.Specular.r = 0.0;
362 material.Specular.g = 0.0;
363 material.Specular.b = 0.0;
364 material.Specular.a = 0.0;
365 material.Emissive.r = 0.0;
366 material.Emissive.g = 0.0;
367 material.Emissive.b = 0.0;
368 material.Emissive.a = 0.0;
369 material.Power = 0.0;
370 IDirect3DDevice9_SetMaterial(device, &material);
371 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
374 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
376 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
378 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
379 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
381 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
382 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
383 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
384 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
385 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
387 hr = IDirect3DDevice9_BeginScene(device);
388 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
389 if(SUCCEEDED(hr)) {
390 struct vertex lighting_test[] = {
391 {-1.0, -1.0, 0.1, 0x8000ff00},
392 { 1.0, -1.0, 0.1, 0x80000000},
393 {-1.0, 1.0, 0.1, 0x8000ff00},
394 { 1.0, 1.0, 0.1, 0x80000000}
396 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
397 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
401 hr = IDirect3DDevice9_EndScene(device);
402 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
405 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
406 color = getPixelColor(device, 320, 240);
407 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
409 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
410 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
414 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
417 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
418 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
419 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
423 static void clear_test(IDirect3DDevice9 *device)
425 /* Tests the correctness of clearing parameters */
426 HRESULT hr;
427 D3DRECT rect[2];
428 D3DRECT rect_negneg;
429 DWORD color;
430 D3DVIEWPORT9 old_vp, vp;
431 RECT scissor;
432 DWORD oldColorWrite;
433 BOOL invalid_clear_failed = FALSE;
435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
436 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
438 /* Positive x, negative y */
439 rect[0].x1 = 0;
440 rect[0].y1 = 480;
441 rect[0].x2 = 320;
442 rect[0].y2 = 240;
444 /* Positive x, positive y */
445 rect[1].x1 = 0;
446 rect[1].y1 = 0;
447 rect[1].x2 = 320;
448 rect[1].y2 = 240;
449 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
450 * returns D3D_OK, but ignores the rectangle silently
452 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
453 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
454 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
456 /* negative x, negative y */
457 rect_negneg.x1 = 640;
458 rect_negneg.y1 = 240;
459 rect_negneg.x2 = 320;
460 rect_negneg.y2 = 0;
461 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
462 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
463 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
467 color = getPixelColor(device, 160, 360); /* lower left quad */
468 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
469 color = getPixelColor(device, 160, 120); /* upper left quad */
470 if(invalid_clear_failed) {
471 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
472 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
473 } else {
474 /* If the negative rectangle was dropped silently, the correct ones are cleared */
475 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
477 color = getPixelColor(device, 480, 360); /* lower right quad */
478 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
479 color = getPixelColor(device, 480, 120); /* upper right quad */
480 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
482 /* Test how the viewport affects clears */
483 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
484 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
485 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
486 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
488 vp.X = 160;
489 vp.Y = 120;
490 vp.Width = 160;
491 vp.Height = 120;
492 vp.MinZ = 0.0;
493 vp.MaxZ = 1.0;
494 hr = IDirect3DDevice9_SetViewport(device, &vp);
495 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
496 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
497 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
499 vp.X = 320;
500 vp.Y = 240;
501 vp.Width = 320;
502 vp.Height = 240;
503 vp.MinZ = 0.0;
504 vp.MaxZ = 1.0;
505 hr = IDirect3DDevice9_SetViewport(device, &vp);
506 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
507 rect[0].x1 = 160;
508 rect[0].y1 = 120;
509 rect[0].x2 = 480;
510 rect[0].y2 = 360;
511 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
512 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
514 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
515 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
518 color = getPixelColor(device, 158, 118);
519 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
520 color = getPixelColor(device, 162, 118);
521 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
522 color = getPixelColor(device, 158, 122);
523 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
524 color = getPixelColor(device, 162, 122);
525 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
527 color = getPixelColor(device, 318, 238);
528 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
529 color = getPixelColor(device, 322, 238);
530 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
531 color = getPixelColor(device, 318, 242);
532 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
533 color = getPixelColor(device, 322, 242);
534 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
536 color = getPixelColor(device, 478, 358);
537 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
538 color = getPixelColor(device, 482, 358);
539 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
540 color = getPixelColor(device, 478, 362);
541 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
542 color = getPixelColor(device, 482, 362);
543 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
545 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
546 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
548 scissor.left = 160;
549 scissor.right = 480;
550 scissor.top = 120;
551 scissor.bottom = 360;
552 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
553 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
555 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
557 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
558 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
563 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566 color = getPixelColor(device, 158, 118);
567 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
568 color = getPixelColor(device, 162, 118);
569 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
570 color = getPixelColor(device, 158, 122);
571 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
572 color = getPixelColor(device, 162, 122);
573 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
575 color = getPixelColor(device, 158, 358);
576 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
577 color = getPixelColor(device, 162, 358);
578 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
579 color = getPixelColor(device, 158, 358);
580 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
581 color = getPixelColor(device, 162, 362);
582 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
584 color = getPixelColor(device, 478, 118);
585 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
586 color = getPixelColor(device, 478, 122);
587 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
588 color = getPixelColor(device, 482, 122);
589 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
590 color = getPixelColor(device, 482, 358);
591 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
593 color = getPixelColor(device, 478, 358);
594 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
595 color = getPixelColor(device, 478, 362);
596 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
597 color = getPixelColor(device, 482, 358);
598 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
599 color = getPixelColor(device, 482, 362);
600 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
602 color = getPixelColor(device, 318, 238);
603 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
604 color = getPixelColor(device, 318, 242);
605 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
606 color = getPixelColor(device, 322, 238);
607 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
608 color = getPixelColor(device, 322, 242);
609 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
611 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
612 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
614 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
622 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
624 /* Colorwriteenable does not affect the clear */
625 color = getPixelColor(device, 320, 240);
626 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
629 typedef struct {
630 float in[4];
631 DWORD out;
632 } test_data_t;
635 * c7 mova ARGB mov ARGB
636 * -2.4 -2 0x00ffff00 -3 0x00ff0000
637 * -1.6 -2 0x00ffff00 -2 0x00ffff00
638 * -0.4 0 0x0000ffff -1 0x0000ff00
639 * 0.4 0 0x0000ffff 0 0x0000ffff
640 * 1.6 2 0x00ff00ff 1 0x000000ff
641 * 2.4 2 0x00ff00ff 2 0x00ff00ff
643 static void test_mova(IDirect3DDevice9 *device)
645 static const DWORD mova_test[] = {
646 0xfffe0200, /* vs_2_0 */
647 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
648 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
649 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
650 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
651 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
652 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
653 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
654 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
655 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
656 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
657 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
658 0x0000ffff /* END */
660 static const DWORD mov_test[] = {
661 0xfffe0101, /* vs_1_1 */
662 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
663 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
664 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
665 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
666 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
667 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
668 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
669 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
670 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
671 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
672 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
673 0x0000ffff /* END */
676 static const test_data_t test_data[2][6] = {
678 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
679 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
680 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
681 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
682 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
683 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
686 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
687 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
688 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
689 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
690 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
691 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
695 static const float quad[][3] = {
696 {-1.0f, -1.0f, 0.0f},
697 {-1.0f, 1.0f, 0.0f},
698 { 1.0f, -1.0f, 0.0f},
699 { 1.0f, 1.0f, 0.0f},
702 static const D3DVERTEXELEMENT9 decl_elements[] = {
703 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
704 D3DDECL_END()
707 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
708 IDirect3DVertexShader9 *mova_shader = NULL;
709 IDirect3DVertexShader9 *mov_shader = NULL;
710 HRESULT hr;
711 UINT i, j;
713 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
714 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
716 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
717 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
718 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
719 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
720 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
722 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
723 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
724 for(j = 0; j < 2; ++j)
726 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
728 DWORD color;
730 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
731 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
733 hr = IDirect3DDevice9_BeginScene(device);
734 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
737 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
739 hr = IDirect3DDevice9_EndScene(device);
740 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
743 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
745 color = getPixelColor(device, 320, 240);
746 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
747 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
749 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
750 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
752 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
753 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
756 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
757 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
759 IDirect3DVertexDeclaration9_Release(vertex_declaration);
760 IDirect3DVertexShader9_Release(mova_shader);
761 IDirect3DVertexShader9_Release(mov_shader);
764 struct sVertex {
765 float x, y, z;
766 DWORD diffuse;
767 DWORD specular;
770 struct sVertexT {
771 float x, y, z, rhw;
772 DWORD diffuse;
773 DWORD specular;
776 static void fog_test(IDirect3DDevice9 *device)
778 HRESULT hr;
779 D3DCOLOR color;
780 float start = 0.0f, end = 1.0f;
781 D3DCAPS9 caps;
782 int i;
784 /* Gets full z based fog with linear fog, no fog with specular color */
785 struct sVertex unstransformed_1[] = {
786 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
787 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
788 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
789 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
791 /* Ok, I am too lazy to deal with transform matrices */
792 struct sVertex unstransformed_2[] = {
793 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
794 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
795 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
796 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
798 /* Untransformed ones. Give them a different diffuse color to make the test look
799 * nicer. It also makes making sure that they are drawn correctly easier.
801 struct sVertexT transformed_1[] = {
802 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
803 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
804 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
805 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
807 struct sVertexT transformed_2[] = {
808 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
809 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
810 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
811 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
813 struct vertex rev_fog_quads[] = {
814 {-1.0, -1.0, 0.1, 0x000000ff},
815 {-1.0, 0.0, 0.1, 0x000000ff},
816 { 0.0, 0.0, 0.1, 0x000000ff},
817 { 0.0, -1.0, 0.1, 0x000000ff},
819 { 0.0, -1.0, 0.9, 0x000000ff},
820 { 0.0, 0.0, 0.9, 0x000000ff},
821 { 1.0, 0.0, 0.9, 0x000000ff},
822 { 1.0, -1.0, 0.9, 0x000000ff},
824 { 0.0, 0.0, 0.4, 0x000000ff},
825 { 0.0, 1.0, 0.4, 0x000000ff},
826 { 1.0, 1.0, 0.4, 0x000000ff},
827 { 1.0, 0.0, 0.4, 0x000000ff},
829 {-1.0, 0.0, 0.7, 0x000000ff},
830 {-1.0, 1.0, 0.7, 0x000000ff},
831 { 0.0, 1.0, 0.7, 0x000000ff},
832 { 0.0, 0.0, 0.7, 0x000000ff},
834 WORD Indices[] = {0, 1, 2, 2, 3, 0};
836 memset(&caps, 0, sizeof(caps));
837 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
838 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
840 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
842 /* Setup initial states: No lighting, fog on, fog color */
843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
844 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
846 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
848 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
850 /* First test: Both table fog and vertex fog off */
851 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
852 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
854 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
856 /* Start = 0, end = 1. Should be default, but set them */
857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
858 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
860 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
862 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
864 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
865 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
866 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
867 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
868 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
869 sizeof(unstransformed_1[0]));
870 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
872 /* That makes it use the Z value */
873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
874 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
875 /* Untransformed, vertex fog != none (or table fog != none):
876 * Use the Z value as input into the equation
878 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
879 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
880 sizeof(unstransformed_1[0]));
881 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
883 /* transformed verts */
884 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
885 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
886 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
887 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
888 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
889 sizeof(transformed_1[0]));
890 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
893 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
894 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
895 * equation
897 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
898 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
899 sizeof(transformed_2[0]));
901 hr = IDirect3DDevice9_EndScene(device);
902 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
904 else
906 ok(FALSE, "BeginScene failed\n");
909 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
910 color = getPixelColor(device, 160, 360);
911 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
912 color = getPixelColor(device, 160, 120);
913 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
914 color = getPixelColor(device, 480, 120);
915 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
916 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
918 color = getPixelColor(device, 480, 360);
919 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
921 else
923 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
924 * The settings above result in no fogging with vertex fog
926 color = getPixelColor(device, 480, 120);
927 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
928 trace("Info: Table fog not supported by this device\n");
931 /* Now test the special case fogstart == fogend */
932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
933 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
935 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
937 start = 512;
938 end = 512;
939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
940 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
942 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
944 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
945 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
947 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
949 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
951 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
952 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
953 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
954 * The third transformed quad remains unfogged because the fogcoords are read from the specular
955 * color and has fixed fogstart and fogend.
957 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
959 sizeof(unstransformed_1[0]));
960 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
961 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
962 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
963 sizeof(unstransformed_1[0]));
964 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
966 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
967 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
968 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
969 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
970 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
971 sizeof(transformed_1[0]));
972 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
974 hr = IDirect3DDevice9_EndScene(device);
975 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
977 else
979 ok(FALSE, "BeginScene failed\n");
981 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
982 color = getPixelColor(device, 160, 360);
983 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
984 color = getPixelColor(device, 160, 120);
985 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
986 color = getPixelColor(device, 480, 120);
987 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
989 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
990 * but without shaders it seems to work everywhere
992 end = 0.2;
993 start = 0.8;
994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
995 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
997 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
998 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
999 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1001 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1002 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1003 * so skip this for now
1005 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1006 const char *mode = (i ? "table" : "vertex");
1007 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1008 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1010 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1012 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1013 hr = IDirect3DDevice9_BeginScene(device);
1014 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1015 if(SUCCEEDED(hr)) {
1016 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1017 4, 5, 6, 6, 7, 4,
1018 8, 9, 10, 10, 11, 8,
1019 12, 13, 14, 14, 15, 12};
1021 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1022 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1023 sizeof(rev_fog_quads[0]));
1025 hr = IDirect3DDevice9_EndScene(device);
1026 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1028 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1029 color = getPixelColor(device, 160, 360);
1030 ok(color_match(color, 0x0000ff00, 1),
1031 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1033 color = getPixelColor(device, 160, 120);
1034 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1035 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1037 color = getPixelColor(device, 480, 120);
1038 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1039 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1041 color = getPixelColor(device, 480, 360);
1042 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1044 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1045 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1046 break;
1049 /* Turn off the fog master switch to avoid confusing other tests */
1050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1051 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1052 start = 0.0;
1053 end = 1.0;
1054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1055 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1057 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1059 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1061 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1064 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1065 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1066 * regardless of the actual addressing mode set. */
1067 static void test_cube_wrap(IDirect3DDevice9 *device)
1069 static const float quad[][6] = {
1070 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1071 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1072 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1073 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1076 static const D3DVERTEXELEMENT9 decl_elements[] = {
1077 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1078 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1079 D3DDECL_END()
1082 static const struct {
1083 D3DTEXTUREADDRESS mode;
1084 const char *name;
1085 } address_modes[] = {
1086 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1087 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1088 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1089 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1090 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1093 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1094 IDirect3DCubeTexture9 *texture = NULL;
1095 IDirect3DSurface9 *surface = NULL;
1096 D3DLOCKED_RECT locked_rect;
1097 HRESULT hr;
1098 UINT x;
1099 INT y, face;
1101 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1102 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1103 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1104 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1106 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1107 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1108 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1110 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1111 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1113 for (y = 0; y < 128; ++y)
1115 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1116 for (x = 0; x < 64; ++x)
1118 *ptr++ = 0xffff0000;
1120 for (x = 64; x < 128; ++x)
1122 *ptr++ = 0xff0000ff;
1126 hr = IDirect3DSurface9_UnlockRect(surface);
1127 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1129 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1130 D3DPOOL_DEFAULT, &texture, NULL);
1131 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1133 /* Create cube faces */
1134 for (face = 0; face < 6; ++face)
1136 IDirect3DSurface9 *face_surface = NULL;
1138 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1139 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1141 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1142 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1144 IDirect3DSurface9_Release(face_surface);
1147 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1148 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1150 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1151 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1152 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1153 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1154 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1155 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1158 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1160 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1162 DWORD color;
1164 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1165 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1166 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1167 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1169 hr = IDirect3DDevice9_BeginScene(device);
1170 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1172 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1173 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1175 hr = IDirect3DDevice9_EndScene(device);
1176 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1178 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1179 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1181 /* Due to the nature of this test, we sample essentially at the edge
1182 * between two faces. Because of this it's undefined from which face
1183 * the driver will sample. Fortunately that's not important for this
1184 * test, since all we care about is that it doesn't sample from the
1185 * other side of the surface or from the border. */
1186 color = getPixelColor(device, 320, 240);
1187 ok(color == 0x00ff0000 || color == 0x000000ff,
1188 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1189 color, address_modes[x].name);
1191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1192 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1195 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1196 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1198 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1199 IDirect3DCubeTexture9_Release(texture);
1200 IDirect3DSurface9_Release(surface);
1203 static void offscreen_test(IDirect3DDevice9 *device)
1205 HRESULT hr;
1206 IDirect3DTexture9 *offscreenTexture = NULL;
1207 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1208 DWORD color;
1210 static const float quad[][5] = {
1211 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1212 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1213 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1214 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1217 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1218 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1220 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1221 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1222 if(!offscreenTexture) {
1223 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1224 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, 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 skip("Cannot create an offscreen render target\n");
1228 goto out;
1232 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1233 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1234 if(!backbuffer) {
1235 goto out;
1238 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1239 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1240 if(!offscreen) {
1241 goto out;
1244 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1245 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1247 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1248 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1249 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1250 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1251 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1252 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1253 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1254 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1258 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1259 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1260 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1262 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1264 /* Draw without textures - Should result in a white quad */
1265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1266 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1268 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1269 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1270 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1271 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1273 /* This time with the texture */
1274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1275 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1277 IDirect3DDevice9_EndScene(device);
1280 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1282 /* Center quad - should be white */
1283 color = getPixelColor(device, 320, 240);
1284 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1285 /* Some quad in the cleared part of the texture */
1286 color = getPixelColor(device, 170, 240);
1287 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1288 /* Part of the originally cleared back buffer */
1289 color = getPixelColor(device, 10, 10);
1290 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1291 if(0) {
1292 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1293 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1294 * the offscreen rendering mode this test would succeed or fail
1296 color = getPixelColor(device, 10, 470);
1297 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1300 out:
1301 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1303 /* restore things */
1304 if(backbuffer) {
1305 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1306 IDirect3DSurface9_Release(backbuffer);
1308 if(offscreenTexture) {
1309 IDirect3DTexture9_Release(offscreenTexture);
1311 if(offscreen) {
1312 IDirect3DSurface9_Release(offscreen);
1316 /* This test tests fog in combination with shaders.
1317 * What's tested: linear fog (vertex and table) with pixel shader
1318 * linear table fog with non foggy vertex shader
1319 * vertex fog with foggy vertex shader, non-linear
1320 * fog with shader, non-linear fog with foggy shader,
1321 * linear table fog with foggy shader
1323 static void fog_with_shader_test(IDirect3DDevice9 *device)
1325 HRESULT hr;
1326 DWORD color;
1327 union {
1328 float f;
1329 DWORD i;
1330 } start, end;
1331 unsigned int i, j;
1333 /* basic vertex shader without fog computation ("non foggy") */
1334 static const DWORD vertex_shader_code1[] = {
1335 0xfffe0101, /* vs_1_1 */
1336 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1337 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1338 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1339 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1340 0x0000ffff
1342 /* basic vertex shader with reversed fog computation ("foggy") */
1343 static const DWORD vertex_shader_code2[] = {
1344 0xfffe0101, /* vs_1_1 */
1345 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1346 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1347 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1348 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1349 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1350 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1351 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1352 0x0000ffff
1354 /* basic pixel shader */
1355 static const DWORD pixel_shader_code[] = {
1356 0xffff0101, /* ps_1_1 */
1357 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1358 0x0000ffff
1361 static struct vertex quad[] = {
1362 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1363 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1364 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1365 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1368 static const D3DVERTEXELEMENT9 decl_elements[] = {
1369 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1370 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1371 D3DDECL_END()
1374 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1375 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1376 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1378 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1379 static const struct test_data_t {
1380 int vshader;
1381 int pshader;
1382 D3DFOGMODE vfog;
1383 D3DFOGMODE tfog;
1384 unsigned int color[11];
1385 } test_data[] = {
1386 /* only pixel shader: */
1387 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1388 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1389 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1390 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1391 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1392 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1393 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1394 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1395 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1396 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1397 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1398 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1399 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1400 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1401 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403 /* vertex shader */
1404 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1405 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1406 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1407 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1408 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1411 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1415 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1417 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1418 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1419 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421 /* vertex shader and pixel shader */
1422 /* The next 4 tests would read the fog coord output, but it isn't available.
1423 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1424 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1425 * These tests should be disabled if some other hardware behaves differently
1427 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1428 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1429 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1430 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1431 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1432 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1433 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1434 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1435 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1436 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1437 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1438 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1440 /* These use the Z coordinate with linear table fog */
1441 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1442 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1443 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1444 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1445 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1446 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1447 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1448 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1449 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1450 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1451 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1452 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1454 /* Non-linear table fog without fog coord */
1455 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1456 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1457 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1458 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1459 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1460 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1462 #if 0 /* FIXME: these fail on GeForce 8500 */
1463 /* foggy vertex shader */
1464 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1465 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1468 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1470 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1471 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1472 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1473 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1474 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1475 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1476 #endif
1478 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1479 * all using the fixed fog-coord linear fog
1481 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1482 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1483 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1484 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1485 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1488 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1491 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1494 /* These use table fog. Here the shader-provided fog coordinate is
1495 * ignored and the z coordinate used instead
1497 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1498 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1499 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1500 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1501 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1502 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1503 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1504 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1508 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1509 start.f=0.1f;
1510 end.f=0.9f;
1512 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1513 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1514 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1515 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1516 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1517 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1518 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1519 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1521 /* Setup initial states: No lighting, fog on, fog color */
1522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1523 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1525 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1527 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1528 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1529 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1532 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1533 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1534 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1536 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1538 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1539 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1540 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1542 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1544 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1545 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1546 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1547 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1549 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1551 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1553 for(j=0; j < 11; j++)
1555 /* Don't use the whole zrange to prevent rounding errors */
1556 quad[0].z = 0.001f + (float)j / 10.02f;
1557 quad[1].z = 0.001f + (float)j / 10.02f;
1558 quad[2].z = 0.001f + (float)j / 10.02f;
1559 quad[3].z = 0.001f + (float)j / 10.02f;
1561 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1562 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1564 hr = IDirect3DDevice9_BeginScene(device);
1565 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1568 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1570 hr = IDirect3DDevice9_EndScene(device);
1571 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1573 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1575 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1576 color = getPixelColor(device, 128, 240);
1577 ok(color_match(color, test_data[i].color[j], 13),
1578 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1579 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1583 /* reset states */
1584 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1585 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1586 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1587 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1588 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1589 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1590 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1591 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1593 IDirect3DVertexShader9_Release(vertex_shader[1]);
1594 IDirect3DVertexShader9_Release(vertex_shader[2]);
1595 IDirect3DPixelShader9_Release(pixel_shader[1]);
1596 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1599 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1600 unsigned int i, x, y;
1601 HRESULT hr;
1602 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1603 D3DLOCKED_RECT locked_rect;
1605 /* Generate the textures */
1606 for(i=0; i<2; i++)
1608 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1609 D3DPOOL_MANAGED, &texture[i], NULL);
1610 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1612 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1613 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1614 for (y = 0; y < 128; ++y)
1616 if(i)
1617 { /* Set up black texture with 2x2 texel white spot in the middle */
1618 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1619 for (x = 0; x < 128; ++x)
1621 if(y>62 && y<66 && x>62 && x<66)
1622 *ptr++ = 0xffffffff;
1623 else
1624 *ptr++ = 0xff000000;
1627 else
1628 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1629 * (if multiplied with bumpenvmat)
1631 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1632 for (x = 0; x < 128; ++x)
1634 if(abs(x-64)>abs(y-64))
1636 if(x < 64)
1637 *ptr++ = 0xc000;
1638 else
1639 *ptr++ = 0x4000;
1641 else
1643 if(y < 64)
1644 *ptr++ = 0x0040;
1645 else
1646 *ptr++ = 0x00c0;
1651 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1652 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1654 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1655 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1657 /* Disable texture filtering */
1658 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1659 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1660 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1661 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1663 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1664 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1665 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1666 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1670 /* test the behavior of the texbem instruction
1671 * with normal 2D and projective 2D textures
1673 static void texbem_test(IDirect3DDevice9 *device)
1675 HRESULT hr;
1676 DWORD color;
1677 int i;
1679 static const DWORD pixel_shader_code[] = {
1680 0xffff0101, /* ps_1_1*/
1681 0x00000042, 0xb00f0000, /* tex t0*/
1682 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1683 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1684 0x0000ffff
1686 static const DWORD double_texbem_code[] = {
1687 0xffff0103, /* ps_1_3 */
1688 0x00000042, 0xb00f0000, /* tex t0 */
1689 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1690 0x00000042, 0xb00f0002, /* tex t2 */
1691 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1692 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1693 0x0000ffff /* end */
1697 static const float quad[][7] = {
1698 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1699 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1700 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1701 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1703 static const float quad_proj[][9] = {
1704 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1705 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1706 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1707 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1710 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1711 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1712 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1713 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1714 D3DDECL_END()
1716 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1717 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1718 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1719 D3DDECL_END()
1720 } };
1722 /* use asymmetric matrix to test loading */
1723 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1725 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1726 IDirect3DPixelShader9 *pixel_shader = NULL;
1727 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1728 D3DLOCKED_RECT locked_rect;
1730 generate_bumpmap_textures(device);
1732 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1733 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1734 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1735 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1736 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1738 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1739 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1744 for(i=0; i<2; i++)
1746 if(i)
1748 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1749 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1752 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1753 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1754 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1755 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1757 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1758 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1759 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1760 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1762 hr = IDirect3DDevice9_BeginScene(device);
1763 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1765 if(!i)
1766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1767 else
1768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1769 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1771 hr = IDirect3DDevice9_EndScene(device);
1772 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1774 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1775 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1777 color = getPixelColor(device, 320-32, 240);
1778 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1779 color = getPixelColor(device, 320+32, 240);
1780 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1781 color = getPixelColor(device, 320, 240-32);
1782 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783 color = getPixelColor(device, 320, 240+32);
1784 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1786 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1787 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1788 IDirect3DPixelShader9_Release(pixel_shader);
1790 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1791 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1792 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1795 /* clean up */
1796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1797 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1799 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1800 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1802 for(i=0; i<2; i++)
1804 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1805 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1806 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1807 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1808 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1809 IDirect3DTexture9_Release(texture);
1812 /* Test double texbem */
1813 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1814 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1815 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1816 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1817 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1818 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1819 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1820 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1822 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1823 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1824 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1825 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1827 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1828 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1830 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1831 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1832 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1833 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1834 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1835 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1838 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1839 #define tex 0x00ff0000
1840 #define tex1 0x0000ff00
1841 #define origin 0x000000ff
1842 static const DWORD pixel_data[] = {
1843 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1844 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1845 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1846 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1847 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1848 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1852 #undef tex1
1853 #undef tex2
1854 #undef origin
1856 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1857 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1858 for(i = 0; i < 8; i++) {
1859 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1861 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1862 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1865 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1866 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1867 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1868 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1870 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1872 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1873 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1874 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1875 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1876 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1878 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1879 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1880 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1881 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1882 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1883 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1885 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1886 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1887 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1888 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1889 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1890 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1892 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1893 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1894 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1895 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1896 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1897 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1898 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1899 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1901 hr = IDirect3DDevice9_BeginScene(device);
1902 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1903 if(SUCCEEDED(hr)) {
1904 static const float double_quad[] = {
1905 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1906 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1907 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1908 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1912 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1913 hr = IDirect3DDevice9_EndScene(device);
1914 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1916 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1917 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1918 color = getPixelColor(device, 320, 240);
1919 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1921 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1922 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1923 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1924 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1925 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1929 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1930 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1932 IDirect3DPixelShader9_Release(pixel_shader);
1933 IDirect3DTexture9_Release(texture);
1934 IDirect3DTexture9_Release(texture1);
1935 IDirect3DTexture9_Release(texture2);
1938 static void z_range_test(IDirect3DDevice9 *device)
1940 const struct vertex quad[] =
1942 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1943 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1944 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1945 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1947 const struct vertex quad2[] =
1949 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1950 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1951 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1952 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1955 const struct tvertex quad3[] =
1957 { 0, 240, 1.1f, 1.0, 0xffffff00},
1958 { 0, 480, 1.1f, 1.0, 0xffffff00},
1959 { 640, 240, -1.1f, 1.0, 0xffffff00},
1960 { 640, 480, -1.1f, 1.0, 0xffffff00},
1962 const struct tvertex quad4[] =
1964 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1965 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1966 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1967 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1969 HRESULT hr;
1970 DWORD color;
1971 IDirect3DVertexShader9 *shader;
1972 IDirect3DVertexDeclaration9 *decl;
1973 D3DCAPS9 caps;
1974 const DWORD shader_code[] = {
1975 0xfffe0101, /* vs_1_1 */
1976 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1977 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1978 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1979 0x0000ffff /* end */
1981 static const D3DVERTEXELEMENT9 decl_elements[] = {
1982 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1983 D3DDECL_END()
1985 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1986 * then call Present. Then clear the color buffer to make sure it has some defined content
1987 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1988 * by the depth value.
1990 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1991 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1998 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2000 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2002 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2004 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2006 hr = IDirect3DDevice9_BeginScene(device);
2007 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2008 if(hr == D3D_OK)
2010 /* Test the untransformed vertex path */
2011 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2012 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2014 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2016 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2018 /* Test the transformed vertex path */
2019 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2020 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2022 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2023 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2025 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2027 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2029 hr = IDirect3DDevice9_EndScene(device);
2030 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2033 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2034 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2036 /* Do not test the exact corner pixels, but go pretty close to them */
2038 /* Clipped because z > 1.0 */
2039 color = getPixelColor(device, 28, 238);
2040 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2041 color = getPixelColor(device, 28, 241);
2042 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2044 /* Not clipped, > z buffer clear value(0.75) */
2045 color = getPixelColor(device, 31, 238);
2046 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2047 color = getPixelColor(device, 31, 241);
2048 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2049 color = getPixelColor(device, 100, 238);
2050 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2051 color = getPixelColor(device, 100, 241);
2052 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2054 /* Not clipped, < z buffer clear value */
2055 color = getPixelColor(device, 104, 238);
2056 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2057 color = getPixelColor(device, 104, 241);
2058 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2059 color = getPixelColor(device, 318, 238);
2060 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2061 color = getPixelColor(device, 318, 241);
2062 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2064 /* Clipped because z < 0.0 */
2065 color = getPixelColor(device, 321, 238);
2066 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2067 color = getPixelColor(device, 321, 241);
2068 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2070 /* Test the shader path */
2071 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2072 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2073 skip("Vertex shaders not supported\n");
2074 goto out;
2076 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2077 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2078 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2079 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2081 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2083 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2084 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2085 IDirect3DDevice9_SetVertexShader(device, shader);
2086 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2088 hr = IDirect3DDevice9_BeginScene(device);
2089 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2090 if(hr == D3D_OK)
2092 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2093 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2094 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2096 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2098 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2099 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2101 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2103 hr = IDirect3DDevice9_EndScene(device);
2104 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2107 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2108 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2109 IDirect3DDevice9_SetVertexShader(device, NULL);
2110 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2112 IDirect3DVertexDeclaration9_Release(decl);
2113 IDirect3DVertexShader9_Release(shader);
2115 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2116 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2117 /* Z < 1.0 */
2118 color = getPixelColor(device, 28, 238);
2119 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2121 /* 1.0 < z < 0.75 */
2122 color = getPixelColor(device, 31, 238);
2123 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2124 color = getPixelColor(device, 100, 238);
2125 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2127 /* 0.75 < z < 0.0 */
2128 color = getPixelColor(device, 104, 238);
2129 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2130 color = getPixelColor(device, 318, 238);
2131 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2133 /* 0.0 < z */
2134 color = getPixelColor(device, 321, 238);
2135 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2137 out:
2138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2148 D3DSURFACE_DESC desc;
2149 D3DLOCKED_RECT l;
2150 HRESULT hr;
2151 unsigned int x, y;
2152 DWORD *mem;
2154 memset(&desc, 0, sizeof(desc));
2155 memset(&l, 0, sizeof(l));
2156 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2157 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2158 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2159 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2160 if(FAILED(hr)) return;
2162 for(y = 0; y < desc.Height; y++)
2164 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2165 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2167 mem[x] = color;
2170 hr = IDirect3DSurface9_UnlockRect(surface);
2171 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2174 /* This tests a variety of possible StretchRect() situations */
2175 static void stretchrect_test(IDirect3DDevice9 *device)
2177 HRESULT hr;
2178 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2179 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2180 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2181 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2182 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2183 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2184 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2185 IDirect3DSurface9 *orig_rt = NULL;
2186 DWORD color;
2188 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2189 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2190 if(!orig_rt) {
2191 goto out;
2194 /* Create our temporary surfaces in system memory */
2195 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2196 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2197 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2198 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2200 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2201 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2203 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2205 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2208 /* Create render target surfaces */
2209 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2210 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2211 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2212 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2213 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2214 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2216 /* Create render target textures */
2217 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2218 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2219 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2220 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2221 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2222 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2223 if (tex_rt32) {
2224 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2225 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2227 if (tex_rt64) {
2228 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2229 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2231 if (tex_rt_dest64) {
2232 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2233 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2236 /* Create regular textures in D3DPOOL_DEFAULT */
2237 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2238 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2239 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2240 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2241 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2242 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2243 if (tex32) {
2244 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2245 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2247 if (tex64) {
2248 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2249 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2251 if (tex_dest64) {
2252 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2253 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2256 /*********************************************************************
2257 * Tests for when the source parameter is an offscreen plain surface *
2258 *********************************************************************/
2260 /* Fill the offscreen 64x64 surface with green */
2261 if (surf_offscreen64)
2262 fill_surface(surf_offscreen64, 0xff00ff00);
2264 /* offscreenplain ==> offscreenplain, same size */
2265 if(surf_offscreen64 && surf_offscreen_dest64) {
2266 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2267 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2269 if (hr == D3D_OK) {
2270 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2271 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2275 /* offscreenplain ==> rendertarget texture, same size */
2276 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2277 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2278 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2280 /* We can't lock rendertarget textures, so copy to our temp surface first */
2281 if (hr == D3D_OK) {
2282 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2283 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2286 if (hr == D3D_OK) {
2287 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2288 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2292 /* offscreenplain ==> rendertarget surface, same size */
2293 if(surf_offscreen64 && surf_rt_dest64) {
2294 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2295 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2297 if (hr == D3D_OK) {
2298 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2299 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2303 /* offscreenplain ==> texture, same size (should fail) */
2304 if(surf_offscreen64 && surf_tex_dest64) {
2305 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2306 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2309 /* Fill the smaller offscreen surface with red */
2310 fill_surface(surf_offscreen32, 0xffff0000);
2312 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2313 if(surf_offscreen32 && surf_offscreen64) {
2314 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2315 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2318 /* offscreenplain ==> rendertarget texture, scaling */
2319 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2320 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2321 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2323 /* We can't lock rendertarget textures, so copy to our temp surface first */
2324 if (hr == D3D_OK) {
2325 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2326 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2329 if (hr == D3D_OK) {
2330 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2331 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2335 /* offscreenplain ==> rendertarget surface, scaling */
2336 if(surf_offscreen32 && surf_rt_dest64) {
2337 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2338 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2340 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2341 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2344 /* offscreenplain ==> texture, scaling (should fail) */
2345 if(surf_offscreen32 && surf_tex_dest64) {
2346 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2347 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2350 /************************************************************
2351 * Tests for when the source parameter is a regular texture *
2352 ************************************************************/
2354 /* Fill the surface of the regular texture with blue */
2355 if (surf_tex64 && surf_temp64) {
2356 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2357 fill_surface(surf_temp64, 0xff0000ff);
2358 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2359 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2362 /* texture ==> offscreenplain, same size */
2363 if(surf_tex64 && surf_offscreen64) {
2364 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2365 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2368 /* texture ==> rendertarget texture, same size */
2369 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2370 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2371 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2373 /* We can't lock rendertarget textures, so copy to our temp surface first */
2374 if (hr == D3D_OK) {
2375 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2376 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2379 if (hr == D3D_OK) {
2380 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2381 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2385 /* texture ==> rendertarget surface, same size */
2386 if(surf_tex64 && surf_rt_dest64) {
2387 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2388 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2390 if (hr == D3D_OK) {
2391 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2392 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2396 /* texture ==> texture, same size (should fail) */
2397 if(surf_tex64 && surf_tex_dest64) {
2398 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2399 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2402 /* Fill the surface of the smaller regular texture with red */
2403 if (surf_tex32 && surf_temp32) {
2404 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2405 fill_surface(surf_temp32, 0xffff0000);
2406 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2407 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2410 /* texture ==> offscreenplain, scaling (should fail) */
2411 if(surf_tex32 && surf_offscreen64) {
2412 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2413 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2416 /* texture ==> rendertarget texture, scaling */
2417 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2418 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2419 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421 /* We can't lock rendertarget textures, so copy to our temp surface first */
2422 if (hr == D3D_OK) {
2423 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2424 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2427 if (hr == D3D_OK) {
2428 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2429 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2433 /* texture ==> rendertarget surface, scaling */
2434 if(surf_tex32 && surf_rt_dest64) {
2435 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2436 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2438 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2439 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2442 /* texture ==> texture, scaling (should fail) */
2443 if(surf_tex32 && surf_tex_dest64) {
2444 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2445 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2448 /*****************************************************************
2449 * Tests for when the source parameter is a rendertarget texture *
2450 *****************************************************************/
2452 /* Fill the surface of the rendertarget texture with white */
2453 if (surf_tex_rt64 && surf_temp64) {
2454 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2455 fill_surface(surf_temp64, 0xffffffff);
2456 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2457 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2460 /* rendertarget texture ==> offscreenplain, same size */
2461 if(surf_tex_rt64 && surf_offscreen64) {
2462 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2463 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2466 /* rendertarget texture ==> rendertarget texture, same size */
2467 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2468 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2469 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2471 /* We can't lock rendertarget textures, so copy to our temp surface first */
2472 if (hr == D3D_OK) {
2473 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2474 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2477 if (hr == D3D_OK) {
2478 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2479 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2483 /* rendertarget texture ==> rendertarget surface, same size */
2484 if(surf_tex_rt64 && surf_rt_dest64) {
2485 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2486 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2488 if (hr == D3D_OK) {
2489 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2490 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2494 /* rendertarget texture ==> texture, same size (should fail) */
2495 if(surf_tex_rt64 && surf_tex_dest64) {
2496 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2497 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2500 /* Fill the surface of the smaller rendertarget texture with red */
2501 if (surf_tex_rt32 && surf_temp32) {
2502 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2503 fill_surface(surf_temp32, 0xffff0000);
2504 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2505 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2508 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2509 if(surf_tex_rt32 && surf_offscreen64) {
2510 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2511 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2514 /* rendertarget texture ==> rendertarget texture, scaling */
2515 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2516 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2517 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519 /* We can't lock rendertarget textures, so copy to our temp surface first */
2520 if (hr == D3D_OK) {
2521 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2522 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2525 if (hr == D3D_OK) {
2526 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2527 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2531 /* rendertarget texture ==> rendertarget surface, scaling */
2532 if(surf_tex_rt32 && surf_rt_dest64) {
2533 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2534 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2536 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2537 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2540 /* rendertarget texture ==> texture, scaling (should fail) */
2541 if(surf_tex_rt32 && surf_tex_dest64) {
2542 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2543 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546 /*****************************************************************
2547 * Tests for when the source parameter is a rendertarget surface *
2548 *****************************************************************/
2550 /* Fill the surface of the rendertarget surface with black */
2551 if (surf_rt64)
2552 fill_surface(surf_rt64, 0xff000000);
2554 /* rendertarget texture ==> offscreenplain, same size */
2555 if(surf_rt64 && surf_offscreen64) {
2556 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2557 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2560 /* rendertarget surface ==> rendertarget texture, same size */
2561 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2562 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2563 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2565 /* We can't lock rendertarget textures, so copy to our temp surface first */
2566 if (hr == D3D_OK) {
2567 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2568 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2571 if (hr == D3D_OK) {
2572 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2573 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2577 /* rendertarget surface ==> rendertarget surface, same size */
2578 if(surf_rt64 && surf_rt_dest64) {
2579 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2580 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2582 if (hr == D3D_OK) {
2583 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2588 /* rendertarget surface ==> texture, same size (should fail) */
2589 if(surf_rt64 && surf_tex_dest64) {
2590 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2591 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2594 /* Fill the surface of the smaller rendertarget texture with red */
2595 if (surf_rt32)
2596 fill_surface(surf_rt32, 0xffff0000);
2598 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2599 if(surf_rt32 && surf_offscreen64) {
2600 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2601 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604 /* rendertarget surface ==> rendertarget texture, scaling */
2605 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2606 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2607 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2609 /* We can't lock rendertarget textures, so copy to our temp surface first */
2610 if (hr == D3D_OK) {
2611 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2612 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2615 if (hr == D3D_OK) {
2616 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2617 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2621 /* rendertarget surface ==> rendertarget surface, scaling */
2622 if(surf_rt32 && surf_rt_dest64) {
2623 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2624 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2626 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2627 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2630 /* rendertarget surface ==> texture, scaling (should fail) */
2631 if(surf_rt32 && surf_tex_dest64) {
2632 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2633 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2636 /* TODO: Test when source and destination RECT parameters are given... */
2637 /* TODO: Test format conversions */
2640 out:
2641 /* Clean up */
2642 if (surf_rt32)
2643 IDirect3DSurface9_Release(surf_rt32);
2644 if (surf_rt64)
2645 IDirect3DSurface9_Release(surf_rt64);
2646 if (surf_rt_dest64)
2647 IDirect3DSurface9_Release(surf_rt_dest64);
2648 if (surf_temp32)
2649 IDirect3DSurface9_Release(surf_temp32);
2650 if (surf_temp64)
2651 IDirect3DSurface9_Release(surf_temp64);
2652 if (surf_offscreen32)
2653 IDirect3DSurface9_Release(surf_offscreen32);
2654 if (surf_offscreen64)
2655 IDirect3DSurface9_Release(surf_offscreen64);
2656 if (surf_offscreen_dest64)
2657 IDirect3DSurface9_Release(surf_offscreen_dest64);
2659 if (tex_rt32) {
2660 if (surf_tex_rt32)
2661 IDirect3DSurface9_Release(surf_tex_rt32);
2662 IDirect3DTexture9_Release(tex_rt32);
2664 if (tex_rt64) {
2665 if (surf_tex_rt64)
2666 IDirect3DSurface9_Release(surf_tex_rt64);
2667 IDirect3DTexture9_Release(tex_rt64);
2669 if (tex_rt_dest64) {
2670 if (surf_tex_rt_dest64)
2671 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2672 IDirect3DTexture9_Release(tex_rt_dest64);
2674 if (tex32) {
2675 if (surf_tex32)
2676 IDirect3DSurface9_Release(surf_tex32);
2677 IDirect3DTexture9_Release(tex32);
2679 if (tex64) {
2680 if (surf_tex64)
2681 IDirect3DSurface9_Release(surf_tex64);
2682 IDirect3DTexture9_Release(tex64);
2684 if (tex_dest64) {
2685 if (surf_tex_dest64)
2686 IDirect3DSurface9_Release(surf_tex_dest64);
2687 IDirect3DTexture9_Release(tex_dest64);
2690 if (orig_rt) {
2691 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2692 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2693 IDirect3DSurface9_Release(orig_rt);
2697 static void maxmip_test(IDirect3DDevice9 *device)
2699 IDirect3DTexture9 *texture = NULL;
2700 IDirect3DSurface9 *surface = NULL;
2701 HRESULT hr;
2702 DWORD color;
2703 const float quads[] = {
2704 -1.0, -1.0, 0.0, 0.0, 0.0,
2705 -1.0, 0.0, 0.0, 0.0, 1.0,
2706 0.0, -1.0, 0.0, 1.0, 0.0,
2707 0.0, 0.0, 0.0, 1.0, 1.0,
2709 0.0, -1.0, 0.0, 0.0, 0.0,
2710 0.0, 0.0, 0.0, 0.0, 1.0,
2711 1.0, -1.0, 0.0, 1.0, 0.0,
2712 1.0, 0.0, 0.0, 1.0, 1.0,
2714 0.0, 0.0, 0.0, 0.0, 0.0,
2715 0.0, 1.0, 0.0, 0.0, 1.0,
2716 1.0, 0.0, 0.0, 1.0, 0.0,
2717 1.0, 1.0, 0.0, 1.0, 1.0,
2719 -1.0, 0.0, 0.0, 0.0, 0.0,
2720 -1.0, 1.0, 0.0, 0.0, 1.0,
2721 0.0, 0.0, 0.0, 1.0, 0.0,
2722 0.0, 1.0, 0.0, 1.0, 1.0,
2725 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2726 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2728 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2729 &texture, NULL);
2730 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2731 if(!texture)
2733 skip("Failed to create test texture\n");
2734 return;
2737 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2738 fill_surface(surface, 0xffff0000);
2739 IDirect3DSurface9_Release(surface);
2740 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2741 fill_surface(surface, 0xff00ff00);
2742 IDirect3DSurface9_Release(surface);
2743 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2744 fill_surface(surface, 0xff0000ff);
2745 IDirect3DSurface9_Release(surface);
2747 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2748 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2749 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2750 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2752 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2753 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2755 hr = IDirect3DDevice9_BeginScene(device);
2756 if(SUCCEEDED(hr))
2758 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2759 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2761 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2763 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2764 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2766 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2768 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2769 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2771 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2773 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2774 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2776 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2777 hr = IDirect3DDevice9_EndScene(device);
2780 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2781 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2782 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2783 color = getPixelColor(device, 160, 360);
2784 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2785 color = getPixelColor(device, 160, 120);
2786 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2787 color = getPixelColor(device, 480, 120);
2788 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2789 color = getPixelColor(device, 480, 360);
2790 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2792 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2793 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2795 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2796 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2798 hr = IDirect3DDevice9_BeginScene(device);
2799 if(SUCCEEDED(hr))
2801 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2802 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2804 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2806 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2807 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2809 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2811 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2812 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2816 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2817 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2819 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2820 hr = IDirect3DDevice9_EndScene(device);
2823 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2824 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2825 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2826 * samples from the highest level in the texture(level 2)
2828 color = getPixelColor(device, 160, 360);
2829 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2830 color = getPixelColor(device, 160, 120);
2831 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2832 color = getPixelColor(device, 480, 120);
2833 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2834 color = getPixelColor(device, 480, 360);
2835 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2837 hr = IDirect3DDevice9_BeginScene(device);
2838 if(SUCCEEDED(hr))
2840 DWORD ret;
2842 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2843 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2844 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2846 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2847 ret = IDirect3DTexture9_SetLOD(texture, 1);
2848 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2849 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2850 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2852 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2853 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2854 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2855 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2856 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2857 ret = IDirect3DTexture9_SetLOD(texture, 2);
2858 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2860 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2862 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2863 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2864 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2865 ret = IDirect3DTexture9_SetLOD(texture, 1);
2866 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2868 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2870 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2871 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2872 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2873 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2874 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2875 ret = IDirect3DTexture9_SetLOD(texture, 1);
2876 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2878 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2879 hr = IDirect3DDevice9_EndScene(device);
2882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2883 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2884 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2885 * samples from the highest level in the texture(level 2)
2887 color = getPixelColor(device, 160, 360);
2888 ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2889 color = getPixelColor(device, 160, 120);
2890 ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2891 color = getPixelColor(device, 480, 120);
2892 ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2893 color = getPixelColor(device, 480, 360);
2894 ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2896 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2897 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2898 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2899 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2900 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2901 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2902 IDirect3DTexture9_Release(texture);
2905 static void release_buffer_test(IDirect3DDevice9 *device)
2907 IDirect3DVertexBuffer9 *vb = NULL;
2908 IDirect3DIndexBuffer9 *ib = NULL;
2909 HRESULT hr;
2910 BYTE *data;
2911 LONG ref;
2913 static const struct vertex quad[] = {
2914 {-1.0, -1.0, 0.1, 0xffff0000},
2915 {-1.0, 1.0, 0.1, 0xffff0000},
2916 { 1.0, 1.0, 0.1, 0xffff0000},
2918 {-1.0, -1.0, 0.1, 0xff00ff00},
2919 {-1.0, 1.0, 0.1, 0xff00ff00},
2920 { 1.0, 1.0, 0.1, 0xff00ff00}
2922 short indices[] = {3, 4, 5};
2924 /* Index and vertex buffers should always be creatable */
2925 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2926 D3DPOOL_MANAGED, &vb, NULL);
2927 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2928 if(!vb) {
2929 skip("Failed to create a vertex buffer\n");
2930 return;
2932 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2933 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2934 if(!ib) {
2935 skip("Failed to create an index buffer\n");
2936 return;
2939 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2940 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2941 memcpy(data, quad, sizeof(quad));
2942 hr = IDirect3DVertexBuffer9_Unlock(vb);
2943 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2945 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2946 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2947 memcpy(data, indices, sizeof(indices));
2948 hr = IDirect3DIndexBuffer9_Unlock(ib);
2949 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2951 hr = IDirect3DDevice9_SetIndices(device, ib);
2952 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2953 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2954 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2955 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2956 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2958 /* Now destroy the bound index buffer and draw again */
2959 ref = IDirect3DIndexBuffer9_Release(ib);
2960 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2963 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2965 hr = IDirect3DDevice9_BeginScene(device);
2966 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2967 if(SUCCEEDED(hr))
2969 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2970 * making assumptions about the indices or vertices
2972 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2973 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2974 hr = IDirect3DDevice9_EndScene(device);
2975 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2978 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2979 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2981 hr = IDirect3DDevice9_SetIndices(device, NULL);
2982 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2983 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2984 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2986 /* Index buffer was already destroyed as part of the test */
2987 IDirect3DVertexBuffer9_Release(vb);
2990 static void float_texture_test(IDirect3DDevice9 *device)
2992 IDirect3D9 *d3d = NULL;
2993 HRESULT hr;
2994 IDirect3DTexture9 *texture = NULL;
2995 D3DLOCKED_RECT lr;
2996 float *data;
2997 DWORD color;
2998 float quad[] = {
2999 -1.0, -1.0, 0.1, 0.0, 0.0,
3000 -1.0, 1.0, 0.1, 0.0, 1.0,
3001 1.0, -1.0, 0.1, 1.0, 0.0,
3002 1.0, 1.0, 0.1, 1.0, 1.0,
3005 memset(&lr, 0, sizeof(lr));
3006 IDirect3DDevice9_GetDirect3D(device, &d3d);
3007 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3008 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3009 skip("D3DFMT_R32F textures not supported\n");
3010 goto out;
3013 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3014 D3DPOOL_MANAGED, &texture, NULL);
3015 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3016 if(!texture) {
3017 skip("Failed to create R32F texture\n");
3018 goto out;
3021 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3022 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3023 data = lr.pBits;
3024 *data = 0.0;
3025 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3026 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3028 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3029 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3031 hr = IDirect3DDevice9_BeginScene(device);
3032 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3033 if(SUCCEEDED(hr))
3035 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3039 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3041 hr = IDirect3DDevice9_EndScene(device);
3042 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3044 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3045 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3047 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3048 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3050 color = getPixelColor(device, 240, 320);
3051 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3053 out:
3054 if(texture) IDirect3DTexture9_Release(texture);
3055 IDirect3D9_Release(d3d);
3058 static void g16r16_texture_test(IDirect3DDevice9 *device)
3060 IDirect3D9 *d3d = NULL;
3061 HRESULT hr;
3062 IDirect3DTexture9 *texture = NULL;
3063 D3DLOCKED_RECT lr;
3064 DWORD *data;
3065 DWORD color;
3066 float quad[] = {
3067 -1.0, -1.0, 0.1, 0.0, 0.0,
3068 -1.0, 1.0, 0.1, 0.0, 1.0,
3069 1.0, -1.0, 0.1, 1.0, 0.0,
3070 1.0, 1.0, 0.1, 1.0, 1.0,
3073 memset(&lr, 0, sizeof(lr));
3074 IDirect3DDevice9_GetDirect3D(device, &d3d);
3075 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3076 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3077 skip("D3DFMT_G16R16 textures not supported\n");
3078 goto out;
3081 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3082 D3DPOOL_MANAGED, &texture, NULL);
3083 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3084 if(!texture) {
3085 skip("Failed to create D3DFMT_G16R16 texture\n");
3086 goto out;
3089 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3090 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3091 data = lr.pBits;
3092 *data = 0x0f00f000;
3093 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3094 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3096 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3097 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3099 hr = IDirect3DDevice9_BeginScene(device);
3100 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3101 if(SUCCEEDED(hr))
3103 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3104 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3107 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3109 hr = IDirect3DDevice9_EndScene(device);
3110 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3112 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3113 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3115 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3116 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3118 color = getPixelColor(device, 240, 320);
3119 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3120 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3122 out:
3123 if(texture) IDirect3DTexture9_Release(texture);
3124 IDirect3D9_Release(d3d);
3127 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3129 HRESULT hr;
3130 IDirect3D9 *d3d;
3131 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3132 D3DCAPS9 caps;
3133 IDirect3DTexture9 *texture = NULL;
3134 IDirect3DVolumeTexture9 *volume = NULL;
3135 unsigned int x, y, z;
3136 D3DLOCKED_RECT lr;
3137 D3DLOCKED_BOX lb;
3138 DWORD color;
3139 UINT w, h;
3140 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3141 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3142 0.0, 1.0, 0.0, 0.0,
3143 0.0, 0.0, 1.0, 0.0,
3144 0.0, 0.0, 0.0, 1.0};
3145 static const D3DVERTEXELEMENT9 decl_elements[] = {
3146 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3147 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3148 D3DDECL_END()
3150 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3151 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3152 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3153 D3DDECL_END()
3155 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3156 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3157 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3158 D3DDECL_END()
3160 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3161 0x00, 0xff, 0x00, 0x00,
3162 0x00, 0x00, 0x00, 0x00,
3163 0x00, 0x00, 0x00, 0x00};
3165 memset(&lr, 0, sizeof(lr));
3166 memset(&lb, 0, sizeof(lb));
3167 IDirect3DDevice9_GetDirect3D(device, &d3d);
3168 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3169 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3170 fmt = D3DFMT_A16B16G16R16;
3172 IDirect3D9_Release(d3d);
3174 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3175 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3176 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3177 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3178 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3179 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3180 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3181 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3182 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3183 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3184 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3185 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3188 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3189 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3190 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3191 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3192 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3193 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3195 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3196 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3197 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3199 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3200 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3201 w = min(1024, caps.MaxTextureWidth);
3202 h = min(1024, caps.MaxTextureHeight);
3203 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3204 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3205 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3206 if(!texture) {
3207 skip("Failed to create the test texture\n");
3208 return;
3211 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3212 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3213 * 1.0 in red and green for the x and y coords
3215 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3216 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3217 for(y = 0; y < h; y++) {
3218 for(x = 0; x < w; x++) {
3219 double r_f = (double) y / (double) h;
3220 double g_f = (double) x / (double) w;
3221 if(fmt == D3DFMT_A16B16G16R16) {
3222 unsigned short r, g;
3223 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3224 r = (unsigned short) (r_f * 65536.0);
3225 g = (unsigned short) (g_f * 65536.0);
3226 dst[0] = r;
3227 dst[1] = g;
3228 dst[2] = 0;
3229 dst[3] = 65535;
3230 } else {
3231 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3232 unsigned char r = (unsigned char) (r_f * 255.0);
3233 unsigned char g = (unsigned char) (g_f * 255.0);
3234 dst[0] = 0;
3235 dst[1] = g;
3236 dst[2] = r;
3237 dst[3] = 255;
3241 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3242 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3243 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3244 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3246 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3247 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3248 hr = IDirect3DDevice9_BeginScene(device);
3249 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3250 if(SUCCEEDED(hr))
3252 float quad1[] = {
3253 -1.0, -1.0, 0.1, 1.0, 1.0,
3254 -1.0, 0.0, 0.1, 1.0, 1.0,
3255 0.0, -1.0, 0.1, 1.0, 1.0,
3256 0.0, 0.0, 0.1, 1.0, 1.0,
3258 float quad2[] = {
3259 -1.0, 0.0, 0.1, 1.0, 1.0,
3260 -1.0, 1.0, 0.1, 1.0, 1.0,
3261 0.0, 0.0, 0.1, 1.0, 1.0,
3262 0.0, 1.0, 0.1, 1.0, 1.0,
3264 float quad3[] = {
3265 0.0, 0.0, 0.1, 0.5, 0.5,
3266 0.0, 1.0, 0.1, 0.5, 0.5,
3267 1.0, 0.0, 0.1, 0.5, 0.5,
3268 1.0, 1.0, 0.1, 0.5, 0.5,
3270 float quad4[] = {
3271 320, 480, 0.1, 1.0, 0.0, 1.0,
3272 320, 240, 0.1, 1.0, 0.0, 1.0,
3273 640, 480, 0.1, 1.0, 0.0, 1.0,
3274 640, 240, 0.1, 1.0, 0.0, 1.0,
3276 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3277 0.0, 0.0, 0.0, 0.0,
3278 0.0, 0.0, 0.0, 0.0,
3279 0.0, 0.0, 0.0, 0.0};
3281 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3285 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3287 /* What happens with transforms enabled? */
3288 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3289 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3290 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3291 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3293 /* What happens if 4 coords are used, but only 2 given ?*/
3294 mat[8] = 1.0;
3295 mat[13] = 1.0;
3296 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3297 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3298 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3299 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3301 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3303 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3304 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3305 * due to the coords in the vertices. (turns out red, indeed)
3307 memset(mat, 0, sizeof(mat));
3308 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3309 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3310 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3311 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3312 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3313 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3315 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3317 hr = IDirect3DDevice9_EndScene(device);
3318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3320 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3321 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3322 color = getPixelColor(device, 160, 360);
3323 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3324 color = getPixelColor(device, 160, 120);
3325 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3326 color = getPixelColor(device, 480, 120);
3327 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3328 color = getPixelColor(device, 480, 360);
3329 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3332 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3334 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3335 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3336 hr = IDirect3DDevice9_BeginScene(device);
3337 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3338 if(SUCCEEDED(hr))
3340 float quad1[] = {
3341 -1.0, -1.0, 0.1, 0.8, 0.2,
3342 -1.0, 0.0, 0.1, 0.8, 0.2,
3343 0.0, -1.0, 0.1, 0.8, 0.2,
3344 0.0, 0.0, 0.1, 0.8, 0.2,
3346 float quad2[] = {
3347 -1.0, 0.0, 0.1, 0.5, 1.0,
3348 -1.0, 1.0, 0.1, 0.5, 1.0,
3349 0.0, 0.0, 0.1, 0.5, 1.0,
3350 0.0, 1.0, 0.1, 0.5, 1.0,
3352 float quad3[] = {
3353 0.0, 0.0, 0.1, 0.5, 1.0,
3354 0.0, 1.0, 0.1, 0.5, 1.0,
3355 1.0, 0.0, 0.1, 0.5, 1.0,
3356 1.0, 1.0, 0.1, 0.5, 1.0,
3358 float quad4[] = {
3359 0.0, -1.0, 0.1, 0.8, 0.2,
3360 0.0, 0.0, 0.1, 0.8, 0.2,
3361 1.0, -1.0, 0.1, 0.8, 0.2,
3362 1.0, 0.0, 0.1, 0.8, 0.2,
3364 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3365 0.0, 0.0, 0.0, 0.0,
3366 0.0, 1.0, 0.0, 0.0,
3367 0.0, 0.0, 0.0, 0.0};
3369 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3371 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3372 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3373 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3374 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3376 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3377 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3379 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3380 * it behaves like COUNT2 because normal textures require 2 coords
3382 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3387 /* Just to be sure, the same as quad2 above */
3388 memset(mat, 0, sizeof(mat));
3389 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3390 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3391 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3392 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3394 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3397 * used? And what happens to the first?
3399 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3400 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3402 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3404 hr = IDirect3DDevice9_EndScene(device);
3405 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409 color = getPixelColor(device, 160, 360);
3410 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3411 color = getPixelColor(device, 160, 120);
3412 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3413 color = getPixelColor(device, 480, 120);
3414 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3415 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3416 color = getPixelColor(device, 480, 360);
3417 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3418 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3420 IDirect3DTexture9_Release(texture);
3422 /* Test projected textures, without any fancy matrices */
3423 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3424 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3425 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3426 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3427 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3428 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3429 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3430 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3432 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3433 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3434 for(x = 0; x < 4; x++) {
3435 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3437 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3438 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3439 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3440 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3442 hr = IDirect3DDevice9_BeginScene(device);
3443 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3444 if(SUCCEEDED(hr))
3446 const float proj_quads[] = {
3447 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3448 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3449 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3450 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3451 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3452 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3453 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3454 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3457 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3458 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3460 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3462 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3463 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3465 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3467 hr = IDirect3DDevice9_EndScene(device);
3468 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3471 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3472 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3473 IDirect3DTexture9_Release(texture);
3475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3476 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3477 color = getPixelColor(device, 158, 118);
3478 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3479 color = getPixelColor(device, 162, 118);
3480 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3481 color = getPixelColor(device, 158, 122);
3482 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3483 color = getPixelColor(device, 162, 122);
3484 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3486 color = getPixelColor(device, 158, 178);
3487 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3488 color = getPixelColor(device, 162, 178);
3489 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3490 color = getPixelColor(device, 158, 182);
3491 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3492 color = getPixelColor(device, 162, 182);
3493 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3495 color = getPixelColor(device, 318, 118);
3496 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3497 color = getPixelColor(device, 322, 118);
3498 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3499 color = getPixelColor(device, 318, 122);
3500 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3501 color = getPixelColor(device, 322, 122);
3502 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3504 color = getPixelColor(device, 318, 178);
3505 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3506 color = getPixelColor(device, 322, 178);
3507 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3508 color = getPixelColor(device, 318, 182);
3509 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3510 color = getPixelColor(device, 322, 182);
3511 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3513 color = getPixelColor(device, 238, 298);
3514 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3515 color = getPixelColor(device, 242, 298);
3516 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3517 color = getPixelColor(device, 238, 302);
3518 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3519 color = getPixelColor(device, 242, 302);
3520 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3522 color = getPixelColor(device, 238, 388);
3523 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3524 color = getPixelColor(device, 242, 388);
3525 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3526 color = getPixelColor(device, 238, 392);
3527 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3528 color = getPixelColor(device, 242, 392);
3529 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3531 color = getPixelColor(device, 478, 298);
3532 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3533 color = getPixelColor(device, 482, 298);
3534 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3535 color = getPixelColor(device, 478, 302);
3536 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3537 color = getPixelColor(device, 482, 302);
3538 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3540 color = getPixelColor(device, 478, 388);
3541 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3542 color = getPixelColor(device, 482, 388);
3543 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3544 color = getPixelColor(device, 478, 392);
3545 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3546 color = getPixelColor(device, 482, 392);
3547 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3550 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3551 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3552 * Thus watch out if sampling from texels between 0 and 1.
3554 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3555 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3556 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3557 if(!volume) {
3558 skip("Failed to create a volume texture\n");
3559 goto out;
3562 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3563 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3564 for(z = 0; z < 32; z++) {
3565 for(y = 0; y < 32; y++) {
3566 for(x = 0; x < 32; x++) {
3567 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3568 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3569 float r_f = (float) x / 31.0;
3570 float g_f = (float) y / 31.0;
3571 float b_f = (float) z / 31.0;
3573 if(fmt == D3DFMT_A16B16G16R16) {
3574 unsigned short *mem_s = mem;
3575 mem_s[0] = r_f * 65535.0;
3576 mem_s[1] = g_f * 65535.0;
3577 mem_s[2] = b_f * 65535.0;
3578 mem_s[3] = 65535;
3579 } else {
3580 unsigned char *mem_c = mem;
3581 mem_c[0] = b_f * 255.0;
3582 mem_c[1] = g_f * 255.0;
3583 mem_c[2] = r_f * 255.0;
3584 mem_c[3] = 255;
3589 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3590 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3592 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3593 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3595 hr = IDirect3DDevice9_BeginScene(device);
3596 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3597 if(SUCCEEDED(hr))
3599 float quad1[] = {
3600 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3601 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3602 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3603 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3605 float quad2[] = {
3606 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3607 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3608 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3609 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3611 float quad3[] = {
3612 0.0, 0.0, 0.1, 0.0, 0.0,
3613 0.0, 1.0, 0.1, 0.0, 0.0,
3614 1.0, 0.0, 0.1, 0.0, 0.0,
3615 1.0, 1.0, 0.1, 0.0, 0.0
3617 float quad4[] = {
3618 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3619 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3620 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3621 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3623 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3624 0.0, 0.0, 1.0, 0.0,
3625 0.0, 1.0, 0.0, 0.0,
3626 0.0, 0.0, 0.0, 1.0};
3627 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3628 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3630 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3631 * values
3633 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3634 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3635 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3638 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3640 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3641 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3642 * otherwise the w will be missing(blue).
3643 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3644 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3646 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3647 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3649 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3651 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3652 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3653 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3654 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3656 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3657 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3659 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3661 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3662 * disable. ATI extends it up to the amount of values needed for the volume texture
3664 memset(mat, 0, sizeof(mat));
3665 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3666 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3667 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3668 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3669 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3670 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3672 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3674 hr = IDirect3DDevice9_EndScene(device);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3678 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3680 color = getPixelColor(device, 160, 360);
3681 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3682 color = getPixelColor(device, 160, 120);
3683 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3684 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3685 color = getPixelColor(device, 480, 120);
3686 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3687 color = getPixelColor(device, 480, 360);
3688 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3690 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3691 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3692 hr = IDirect3DDevice9_BeginScene(device);
3693 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3694 if(SUCCEEDED(hr))
3696 float quad1[] = {
3697 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3698 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3699 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3700 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3702 float quad2[] = {
3703 -1.0, 0.0, 0.1,
3704 -1.0, 1.0, 0.1,
3705 0.0, 0.0, 0.1,
3706 0.0, 1.0, 0.1,
3708 float quad3[] = {
3709 0.0, 0.0, 0.1, 1.0,
3710 0.0, 1.0, 0.1, 1.0,
3711 1.0, 0.0, 0.1, 1.0,
3712 1.0, 1.0, 0.1, 1.0
3714 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3715 0.0, 0.0, 0.0, 0.0,
3716 0.0, 0.0, 0.0, 0.0,
3717 0.0, 1.0, 0.0, 0.0};
3718 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3719 1.0, 0.0, 0.0, 0.0,
3720 0.0, 1.0, 0.0, 0.0,
3721 0.0, 0.0, 1.0, 0.0};
3722 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3723 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3725 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3727 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3729 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3730 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3732 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3734 /* None passed */
3735 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3736 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3738 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3740 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3742 /* 4 used, 1 passed */
3743 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3744 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3745 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3746 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3748 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3750 hr = IDirect3DDevice9_EndScene(device);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3753 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3754 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3755 color = getPixelColor(device, 160, 360);
3756 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3757 color = getPixelColor(device, 160, 120);
3758 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3759 color = getPixelColor(device, 480, 120);
3760 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3761 /* Quad4: unused */
3763 IDirect3DVolumeTexture9_Release(volume);
3765 out:
3766 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3768 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3769 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3770 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3771 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3772 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3774 IDirect3DVertexDeclaration9_Release(decl);
3775 IDirect3DVertexDeclaration9_Release(decl2);
3776 IDirect3DVertexDeclaration9_Release(decl3);
3779 static void texdepth_test(IDirect3DDevice9 *device)
3781 IDirect3DPixelShader9 *shader;
3782 HRESULT hr;
3783 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3784 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3785 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3786 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3787 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3788 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3789 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3790 DWORD shader_code[] = {
3791 0xffff0104, /* ps_1_4 */
3792 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3793 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3794 0x0000fffd, /* phase */
3795 0x00000057, 0x800f0005, /* texdepth r5 */
3796 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3797 0x0000ffff /* end */
3799 DWORD color;
3800 float vertex[] = {
3801 -1.0, -1.0, 0.0,
3802 1.0, -1.0, 1.0,
3803 -1.0, 1.0, 0.0,
3804 1.0, 1.0, 1.0
3807 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3808 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3811 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3813 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3815 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3817 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3818 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3820 /* Fill the depth buffer with a gradient */
3821 hr = IDirect3DDevice9_BeginScene(device);
3822 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3823 if(SUCCEEDED(hr))
3825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3826 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3827 hr = IDirect3DDevice9_EndScene(device);
3828 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3831 /* Now perform the actual tests. Same geometry, but with the shader */
3832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3833 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3835 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3836 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3837 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3839 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3840 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3841 hr = IDirect3DDevice9_BeginScene(device);
3842 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3843 if(SUCCEEDED(hr))
3845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3846 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3848 hr = IDirect3DDevice9_EndScene(device);
3849 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3853 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3854 color = getPixelColor(device, 158, 240);
3855 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3856 color = getPixelColor(device, 162, 240);
3857 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3861 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3863 hr = IDirect3DDevice9_BeginScene(device);
3864 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3865 if(SUCCEEDED(hr))
3867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3868 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3870 hr = IDirect3DDevice9_EndScene(device);
3871 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3874 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3875 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3876 color = getPixelColor(device, 318, 240);
3877 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3878 color = getPixelColor(device, 322, 240);
3879 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3883 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3884 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3885 hr = IDirect3DDevice9_BeginScene(device);
3886 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3887 if(SUCCEEDED(hr))
3889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3890 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3892 hr = IDirect3DDevice9_EndScene(device);
3893 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3895 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3896 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3898 color = getPixelColor(device, 1, 240);
3899 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3901 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3903 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3905 hr = IDirect3DDevice9_BeginScene(device);
3906 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3907 if(SUCCEEDED(hr))
3909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3910 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3912 hr = IDirect3DDevice9_EndScene(device);
3913 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3915 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3916 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3917 color = getPixelColor(device, 318, 240);
3918 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3919 color = getPixelColor(device, 322, 240);
3920 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3922 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3924 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3925 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3926 hr = IDirect3DDevice9_BeginScene(device);
3927 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3928 if(SUCCEEDED(hr))
3930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3931 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3933 hr = IDirect3DDevice9_EndScene(device);
3934 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3937 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3939 color = getPixelColor(device, 1, 240);
3940 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3944 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3945 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3946 hr = IDirect3DDevice9_BeginScene(device);
3947 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3948 if(SUCCEEDED(hr))
3950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3951 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3953 hr = IDirect3DDevice9_EndScene(device);
3954 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3956 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3957 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3959 color = getPixelColor(device, 638, 240);
3960 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3964 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3965 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3966 hr = IDirect3DDevice9_BeginScene(device);
3967 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3968 if(SUCCEEDED(hr))
3970 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3971 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3973 hr = IDirect3DDevice9_EndScene(device);
3974 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3977 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3979 color = getPixelColor(device, 638, 240);
3980 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3982 /* Cleanup */
3983 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3984 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3985 IDirect3DPixelShader9_Release(shader);
3987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3988 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3990 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3993 static void texkill_test(IDirect3DDevice9 *device)
3995 IDirect3DPixelShader9 *shader;
3996 HRESULT hr;
3997 DWORD color;
3999 const float vertex[] = {
4000 /* bottom top right left */
4001 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4002 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4003 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4004 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4007 DWORD shader_code_11[] = {
4008 0xffff0101, /* ps_1_1 */
4009 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4010 0x00000041, 0xb00f0000, /* texkill t0 */
4011 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4012 0x0000ffff /* end */
4014 DWORD shader_code_20[] = {
4015 0xffff0200, /* ps_2_0 */
4016 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4017 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4018 0x01000041, 0xb00f0000, /* texkill t0 */
4019 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4020 0x0000ffff /* end */
4023 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4025 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4026 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4028 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4029 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4030 hr = IDirect3DDevice9_BeginScene(device);
4031 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4032 if(SUCCEEDED(hr))
4034 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4035 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4036 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4037 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4038 hr = IDirect3DDevice9_EndScene(device);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4041 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4043 color = getPixelColor(device, 63, 46);
4044 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4045 color = getPixelColor(device, 66, 46);
4046 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4047 color = getPixelColor(device, 63, 49);
4048 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4049 color = getPixelColor(device, 66, 49);
4050 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4052 color = getPixelColor(device, 578, 46);
4053 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4054 color = getPixelColor(device, 575, 46);
4055 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4056 color = getPixelColor(device, 578, 49);
4057 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4058 color = getPixelColor(device, 575, 49);
4059 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4061 color = getPixelColor(device, 63, 430);
4062 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4063 color = getPixelColor(device, 63, 433);
4064 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4065 color = getPixelColor(device, 66, 433);
4066 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4067 color = getPixelColor(device, 66, 430);
4068 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4070 color = getPixelColor(device, 578, 430);
4071 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4072 color = getPixelColor(device, 578, 433);
4073 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4074 color = getPixelColor(device, 575, 433);
4075 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4076 color = getPixelColor(device, 575, 430);
4077 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4079 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4080 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4081 IDirect3DPixelShader9_Release(shader);
4083 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4084 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4085 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4086 if(FAILED(hr)) {
4087 skip("Failed to create 2.0 test shader, most likely not supported\n");
4088 return;
4091 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4092 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4093 hr = IDirect3DDevice9_BeginScene(device);
4094 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4095 if(SUCCEEDED(hr))
4097 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4098 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4099 hr = IDirect3DDevice9_EndScene(device);
4100 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4102 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4104 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4105 color = getPixelColor(device, 63, 46);
4106 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4107 color = getPixelColor(device, 66, 46);
4108 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4109 color = getPixelColor(device, 63, 49);
4110 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4111 color = getPixelColor(device, 66, 49);
4112 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4114 color = getPixelColor(device, 578, 46);
4115 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4116 color = getPixelColor(device, 575, 46);
4117 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4118 color = getPixelColor(device, 578, 49);
4119 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4120 color = getPixelColor(device, 575, 49);
4121 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4123 color = getPixelColor(device, 63, 430);
4124 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4125 color = getPixelColor(device, 63, 433);
4126 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4127 color = getPixelColor(device, 66, 433);
4128 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4129 color = getPixelColor(device, 66, 430);
4130 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4132 color = getPixelColor(device, 578, 430);
4133 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4134 color = getPixelColor(device, 578, 433);
4135 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4136 color = getPixelColor(device, 575, 433);
4137 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4138 color = getPixelColor(device, 575, 430);
4139 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4141 /* Cleanup */
4142 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4143 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4144 IDirect3DPixelShader9_Release(shader);
4147 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4149 IDirect3D9 *d3d9;
4150 HRESULT hr;
4151 IDirect3DTexture9 *texture;
4152 IDirect3DPixelShader9 *shader;
4153 IDirect3DPixelShader9 *shader2;
4154 D3DLOCKED_RECT lr;
4155 DWORD color;
4156 DWORD shader_code[] = {
4157 0xffff0101, /* ps_1_1 */
4158 0x00000042, 0xb00f0000, /* tex t0 */
4159 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4160 0x0000ffff /* end */
4162 DWORD shader_code2[] = {
4163 0xffff0101, /* ps_1_1 */
4164 0x00000042, 0xb00f0000, /* tex t0 */
4165 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4166 0x0000ffff /* end */
4169 float quad[] = {
4170 -1.0, -1.0, 0.1, 0.5, 0.5,
4171 1.0, -1.0, 0.1, 0.5, 0.5,
4172 -1.0, 1.0, 0.1, 0.5, 0.5,
4173 1.0, 1.0, 0.1, 0.5, 0.5,
4176 memset(&lr, 0, sizeof(lr));
4177 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4178 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4179 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4180 IDirect3D9_Release(d3d9);
4181 if(FAILED(hr)) {
4182 skip("No D3DFMT_X8L8V8U8 support\n");
4185 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4186 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4188 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4189 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4190 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4191 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4192 *((DWORD *) lr.pBits) = 0x11ca3141;
4193 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4194 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4196 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4197 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4198 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4199 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4201 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4202 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4203 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4204 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4205 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4206 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4208 hr = IDirect3DDevice9_BeginScene(device);
4209 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4210 if(SUCCEEDED(hr))
4212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4213 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4215 hr = IDirect3DDevice9_EndScene(device);
4216 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4218 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4220 color = getPixelColor(device, 578, 430);
4221 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4222 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4224 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4225 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4226 hr = IDirect3DDevice9_BeginScene(device);
4227 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4228 if(SUCCEEDED(hr))
4230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4231 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4233 hr = IDirect3DDevice9_EndScene(device);
4234 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4237 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4238 color = getPixelColor(device, 578, 430);
4239 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4241 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4242 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4243 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4245 IDirect3DPixelShader9_Release(shader);
4246 IDirect3DPixelShader9_Release(shader2);
4247 IDirect3DTexture9_Release(texture);
4250 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4252 HRESULT hr;
4253 IDirect3D9 *d3d;
4254 IDirect3DTexture9 *texture = NULL;
4255 IDirect3DSurface9 *surface;
4256 DWORD color;
4257 const RECT r1 = {256, 256, 512, 512};
4258 const RECT r2 = {512, 256, 768, 512};
4259 const RECT r3 = {256, 512, 512, 768};
4260 const RECT r4 = {512, 512, 768, 768};
4261 unsigned int x, y;
4262 D3DLOCKED_RECT lr;
4263 memset(&lr, 0, sizeof(lr));
4265 IDirect3DDevice9_GetDirect3D(device, &d3d);
4266 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4267 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4268 skip("No autogenmipmap support\n");
4269 IDirect3D9_Release(d3d);
4270 return;
4272 IDirect3D9_Release(d3d);
4274 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4275 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4277 /* Make the mipmap big, so that a smaller mipmap is used
4279 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4280 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4281 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4283 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4284 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4285 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4286 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4287 for(y = 0; y < 1024; y++) {
4288 for(x = 0; x < 1024; x++) {
4289 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4290 POINT pt;
4292 pt.x = x;
4293 pt.y = y;
4294 if(PtInRect(&r1, pt)) {
4295 *dst = 0xffff0000;
4296 } else if(PtInRect(&r2, pt)) {
4297 *dst = 0xff00ff00;
4298 } else if(PtInRect(&r3, pt)) {
4299 *dst = 0xff0000ff;
4300 } else if(PtInRect(&r4, pt)) {
4301 *dst = 0xff000000;
4302 } else {
4303 *dst = 0xffffffff;
4307 hr = IDirect3DSurface9_UnlockRect(surface);
4308 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4309 IDirect3DSurface9_Release(surface);
4311 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4312 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4313 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4314 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4316 hr = IDirect3DDevice9_BeginScene(device);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4318 if(SUCCEEDED(hr)) {
4319 const float quad[] = {
4320 -0.5, -0.5, 0.1, 0.0, 0.0,
4321 -0.5, 0.5, 0.1, 0.0, 1.0,
4322 0.5, -0.5, 0.1, 1.0, 0.0,
4323 0.5, 0.5, 0.1, 1.0, 1.0
4326 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4327 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4329 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4330 hr = IDirect3DDevice9_EndScene(device);
4331 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4333 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4334 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4335 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4336 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4337 IDirect3DTexture9_Release(texture);
4339 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4340 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4341 color = getPixelColor(device, 200, 200);
4342 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4343 color = getPixelColor(device, 280, 200);
4344 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4345 color = getPixelColor(device, 360, 200);
4346 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4347 color = getPixelColor(device, 440, 200);
4348 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4349 color = getPixelColor(device, 200, 270);
4350 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4351 color = getPixelColor(device, 280, 270);
4352 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4353 color = getPixelColor(device, 360, 270);
4354 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4355 color = getPixelColor(device, 440, 270);
4356 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4359 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4361 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4362 IDirect3DVertexDeclaration9 *decl;
4363 HRESULT hr;
4364 DWORD color;
4365 DWORD shader_code_11[] = {
4366 0xfffe0101, /* vs_1_1 */
4367 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4368 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4369 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4370 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4371 0x0000ffff /* end */
4373 DWORD shader_code_11_2[] = {
4374 0xfffe0101, /* vs_1_1 */
4375 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4376 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4377 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4378 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4379 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4380 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4381 0x0000ffff /* end */
4383 DWORD shader_code_20[] = {
4384 0xfffe0200, /* vs_2_0 */
4385 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4386 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4387 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4388 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4389 0x0000ffff /* end */
4391 DWORD shader_code_20_2[] = {
4392 0xfffe0200, /* vs_2_0 */
4393 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4394 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4395 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4396 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4397 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4398 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4399 0x0000ffff /* end */
4401 static const D3DVERTEXELEMENT9 decl_elements[] = {
4402 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4403 D3DDECL_END()
4405 float quad1[] = {
4406 -1.0, -1.0, 0.1,
4407 0.0, -1.0, 0.1,
4408 -1.0, 0.0, 0.1,
4409 0.0, 0.0, 0.1
4411 float quad2[] = {
4412 0.0, -1.0, 0.1,
4413 1.0, -1.0, 0.1,
4414 0.0, 0.0, 0.1,
4415 1.0, 0.0, 0.1
4417 float quad3[] = {
4418 0.0, 0.0, 0.1,
4419 1.0, 0.0, 0.1,
4420 0.0, 1.0, 0.1,
4421 1.0, 1.0, 0.1
4423 float quad4[] = {
4424 -1.0, 0.0, 0.1,
4425 0.0, 0.0, 0.1,
4426 -1.0, 1.0, 0.1,
4427 0.0, 1.0, 0.1
4429 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4430 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4432 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4435 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4437 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4438 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4439 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4440 if(FAILED(hr)) shader_20 = NULL;
4441 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4442 if(FAILED(hr)) shader_20_2 = NULL;
4443 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4444 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4446 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4447 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4448 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4449 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4450 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4451 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4453 hr = IDirect3DDevice9_BeginScene(device);
4454 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4455 if(SUCCEEDED(hr))
4457 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4458 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4460 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4462 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4465 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4467 if(shader_20) {
4468 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4469 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4471 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4474 if(shader_20_2) {
4475 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4476 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4478 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4481 hr = IDirect3DDevice9_EndScene(device);
4482 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4484 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4485 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4487 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4488 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4489 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4490 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4492 color = getPixelColor(device, 160, 360);
4493 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4494 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4495 color = getPixelColor(device, 480, 360);
4496 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4497 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4498 if(shader_20) {
4499 color = getPixelColor(device, 160, 120);
4500 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4501 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4503 if(shader_20_2) {
4504 color = getPixelColor(device, 480, 120);
4505 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4506 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4509 IDirect3DVertexDeclaration9_Release(decl);
4510 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4511 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4512 IDirect3DVertexShader9_Release(shader_11_2);
4513 IDirect3DVertexShader9_Release(shader_11);
4516 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4518 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4519 HRESULT hr;
4520 DWORD color;
4521 DWORD shader_code_11[] = {
4522 0xffff0101, /* ps_1_1 */
4523 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4524 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4525 0x0000ffff /* end */
4527 DWORD shader_code_12[] = {
4528 0xffff0102, /* ps_1_2 */
4529 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4530 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4531 0x0000ffff /* end */
4533 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4534 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4535 * During development of this test, 1.3 shaders were verified too
4537 DWORD shader_code_14[] = {
4538 0xffff0104, /* ps_1_4 */
4539 /* Try to make one constant local. It gets clamped too, although the binary contains
4540 * the bigger numbers
4542 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4543 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4544 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4545 0x0000ffff /* end */
4547 DWORD shader_code_20[] = {
4548 0xffff0200, /* ps_2_0 */
4549 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4550 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4551 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4552 0x0000ffff /* end */
4554 float quad1[] = {
4555 -1.0, -1.0, 0.1,
4556 0.0, -1.0, 0.1,
4557 -1.0, 0.0, 0.1,
4558 0.0, 0.0, 0.1
4560 float quad2[] = {
4561 0.0, -1.0, 0.1,
4562 1.0, -1.0, 0.1,
4563 0.0, 0.0, 0.1,
4564 1.0, 0.0, 0.1
4566 float quad3[] = {
4567 0.0, 0.0, 0.1,
4568 1.0, 0.0, 0.1,
4569 0.0, 1.0, 0.1,
4570 1.0, 1.0, 0.1
4572 float quad4[] = {
4573 -1.0, 0.0, 0.1,
4574 0.0, 0.0, 0.1,
4575 -1.0, 1.0, 0.1,
4576 0.0, 1.0, 0.1
4578 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4579 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4582 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4584 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4585 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4586 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4587 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4588 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4589 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4590 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4591 if(FAILED(hr)) shader_20 = NULL;
4593 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4594 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4595 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4596 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4597 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4598 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4600 hr = IDirect3DDevice9_BeginScene(device);
4601 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4602 if(SUCCEEDED(hr))
4604 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4605 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4607 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4609 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4610 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4612 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4614 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4615 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4617 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4619 if(shader_20) {
4620 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4621 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4623 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4626 hr = IDirect3DDevice9_EndScene(device);
4627 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4629 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4630 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4632 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4633 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4635 color = getPixelColor(device, 160, 360);
4636 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4637 "quad 1 has color %08x, expected 0x00808000\n", color);
4638 color = getPixelColor(device, 480, 360);
4639 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4640 "quad 2 has color %08x, expected 0x00808000\n", color);
4641 color = getPixelColor(device, 480, 120);
4642 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4643 "quad 3 has color %08x, expected 0x00808000\n", color);
4644 if(shader_20) {
4645 color = getPixelColor(device, 160, 120);
4646 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4647 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4650 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4651 IDirect3DPixelShader9_Release(shader_14);
4652 IDirect3DPixelShader9_Release(shader_12);
4653 IDirect3DPixelShader9_Release(shader_11);
4656 static void dp2add_ps_test(IDirect3DDevice9 *device)
4658 IDirect3DPixelShader9 *shader_dp2add = NULL;
4659 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4660 HRESULT hr;
4661 DWORD color;
4663 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4664 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4665 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4666 * r0 first.
4667 * The result here for the r,g,b components should be roughly 0.5:
4668 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4669 static const DWORD shader_code_dp2add[] = {
4670 0xffff0200, /* ps_2_0 */
4671 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4673 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4674 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4676 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4677 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4678 0x0000ffff /* end */
4681 /* Test the _sat modifier, too. Result here should be:
4682 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4683 * _SAT: ==> 1.0
4684 * ADD: (1.0 + -0.5) = 0.5
4686 static const DWORD shader_code_dp2add_sat[] = {
4687 0xffff0200, /* ps_2_0 */
4688 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4690 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4691 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4692 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4694 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4695 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4696 0x0000ffff /* end */
4699 const float quad[] = {
4700 -1.0, -1.0, 0.1,
4701 1.0, -1.0, 0.1,
4702 -1.0, 1.0, 0.1,
4703 1.0, 1.0, 0.1
4707 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4708 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4710 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4711 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4713 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4714 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4716 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4717 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4719 if (shader_dp2add) {
4721 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4722 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4724 hr = IDirect3DDevice9_BeginScene(device);
4725 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4726 if(SUCCEEDED(hr))
4728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4729 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4731 hr = IDirect3DDevice9_EndScene(device);
4732 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4734 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4735 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4737 color = getPixelColor(device, 360, 240);
4738 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4739 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4741 IDirect3DPixelShader9_Release(shader_dp2add);
4742 } else {
4743 skip("dp2add shader creation failed\n");
4746 if (shader_dp2add_sat) {
4748 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4749 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4751 hr = IDirect3DDevice9_BeginScene(device);
4752 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4753 if(SUCCEEDED(hr))
4755 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4756 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4758 hr = IDirect3DDevice9_EndScene(device);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4761 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4764 color = getPixelColor(device, 360, 240);
4765 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4766 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4768 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4769 } else {
4770 skip("dp2add shader creation failed\n");
4773 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4774 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4777 static void cnd_test(IDirect3DDevice9 *device)
4779 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4780 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4781 HRESULT hr;
4782 DWORD color;
4783 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4784 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4785 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4787 DWORD shader_code_11[] = {
4788 0xffff0101, /* ps_1_1 */
4789 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4790 0x00000040, 0xb00f0000, /* texcoord t0 */
4791 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4792 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4793 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4794 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4795 0x0000ffff /* end */
4797 DWORD shader_code_12[] = {
4798 0xffff0102, /* ps_1_2 */
4799 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4800 0x00000040, 0xb00f0000, /* texcoord t0 */
4801 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4802 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4803 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4804 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4805 0x0000ffff /* end */
4807 DWORD shader_code_13[] = {
4808 0xffff0103, /* ps_1_3 */
4809 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4810 0x00000040, 0xb00f0000, /* texcoord t0 */
4811 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4812 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4813 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4814 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4815 0x0000ffff /* end */
4817 DWORD shader_code_14[] = {
4818 0xffff0104, /* ps_1_3 */
4819 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4820 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4821 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4822 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4823 0x0000ffff /* end */
4826 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4827 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4828 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4829 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4830 * native CreatePixelShader returns an error.
4832 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4833 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4834 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4835 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4837 DWORD shader_code_11_coissue[] = {
4838 0xffff0101, /* ps_1_1 */
4839 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4840 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4841 0x00000040, 0xb00f0000, /* texcoord t0 */
4842 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4843 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4844 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4845 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4846 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4847 /* 0x40000000 = D3DSI_COISSUE */
4848 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4849 0x0000ffff /* end */
4851 DWORD shader_code_12_coissue[] = {
4852 0xffff0102, /* ps_1_2 */
4853 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4854 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4855 0x00000040, 0xb00f0000, /* texcoord t0 */
4856 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4857 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4858 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4859 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4860 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4861 /* 0x40000000 = D3DSI_COISSUE */
4862 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4863 0x0000ffff /* end */
4865 DWORD shader_code_13_coissue[] = {
4866 0xffff0103, /* ps_1_3 */
4867 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4868 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4869 0x00000040, 0xb00f0000, /* texcoord t0 */
4870 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4871 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4872 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4873 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4874 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4875 /* 0x40000000 = D3DSI_COISSUE */
4876 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4877 0x0000ffff /* end */
4879 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4880 * compare against 0.5
4882 DWORD shader_code_14_coissue[] = {
4883 0xffff0104, /* ps_1_4 */
4884 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4885 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4886 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4887 /* 0x40000000 = D3DSI_COISSUE */
4888 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4889 0x0000ffff /* end */
4891 float quad1[] = {
4892 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4893 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4894 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4895 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4897 float quad2[] = {
4898 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4899 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4900 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4901 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4903 float quad3[] = {
4904 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4905 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4906 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4907 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4909 float quad4[] = {
4910 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4911 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4912 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4913 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4915 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4916 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4917 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4918 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4921 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4923 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4924 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4925 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4926 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4927 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4928 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4929 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4930 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4931 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4932 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4933 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4934 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4935 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4936 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4937 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4938 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4941 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4942 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4944 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4945 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4947 hr = IDirect3DDevice9_BeginScene(device);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4949 if(SUCCEEDED(hr))
4951 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4952 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4954 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4956 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4957 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4959 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4961 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4962 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4964 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4966 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4967 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4969 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4971 hr = IDirect3DDevice9_EndScene(device);
4972 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4975 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4977 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4980 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4981 color = getPixelColor(device, 158, 118);
4982 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4983 color = getPixelColor(device, 162, 118);
4984 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4985 color = getPixelColor(device, 158, 122);
4986 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4987 color = getPixelColor(device, 162, 122);
4988 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4990 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4991 color = getPixelColor(device, 158, 358);
4992 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4993 color = getPixelColor(device, 162, 358);
4994 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4995 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4996 color = getPixelColor(device, 158, 362);
4997 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4998 color = getPixelColor(device, 162, 362);
4999 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5000 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5002 /* 1.2 shader */
5003 color = getPixelColor(device, 478, 358);
5004 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5005 color = getPixelColor(device, 482, 358);
5006 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5007 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5008 color = getPixelColor(device, 478, 362);
5009 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5010 color = getPixelColor(device, 482, 362);
5011 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5012 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5014 /* 1.3 shader */
5015 color = getPixelColor(device, 478, 118);
5016 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5017 color = getPixelColor(device, 482, 118);
5018 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5019 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5020 color = getPixelColor(device, 478, 122);
5021 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5022 color = getPixelColor(device, 482, 122);
5023 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5024 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5026 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5027 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5028 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5029 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5030 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5031 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5033 hr = IDirect3DDevice9_BeginScene(device);
5034 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5035 if(SUCCEEDED(hr))
5037 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5038 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5040 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5042 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5043 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5045 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5047 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5048 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5050 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5052 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5053 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5055 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5057 hr = IDirect3DDevice9_EndScene(device);
5058 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5060 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5061 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5063 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5064 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5066 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5067 * that we swapped the values in c1 and c2 to make the other tests return some color
5069 color = getPixelColor(device, 158, 118);
5070 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5071 color = getPixelColor(device, 162, 118);
5072 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5073 color = getPixelColor(device, 158, 122);
5074 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5075 color = getPixelColor(device, 162, 122);
5076 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5078 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5079 color = getPixelColor(device, 158, 358);
5080 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5081 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5082 color = getPixelColor(device, 162, 358);
5083 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5084 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5085 color = getPixelColor(device, 158, 362);
5086 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5087 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5088 color = getPixelColor(device, 162, 362);
5089 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5090 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5092 /* 1.2 shader */
5093 color = getPixelColor(device, 478, 358);
5094 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5095 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5096 color = getPixelColor(device, 482, 358);
5097 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5098 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5099 color = getPixelColor(device, 478, 362);
5100 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5101 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5102 color = getPixelColor(device, 482, 362);
5103 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5104 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5106 /* 1.3 shader */
5107 color = getPixelColor(device, 478, 118);
5108 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5109 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5110 color = getPixelColor(device, 482, 118);
5111 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5112 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5113 color = getPixelColor(device, 478, 122);
5114 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5115 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5116 color = getPixelColor(device, 482, 122);
5117 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5118 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5120 IDirect3DPixelShader9_Release(shader_14_coissue);
5121 IDirect3DPixelShader9_Release(shader_13_coissue);
5122 IDirect3DPixelShader9_Release(shader_12_coissue);
5123 IDirect3DPixelShader9_Release(shader_11_coissue);
5124 IDirect3DPixelShader9_Release(shader_14);
5125 IDirect3DPixelShader9_Release(shader_13);
5126 IDirect3DPixelShader9_Release(shader_12);
5127 IDirect3DPixelShader9_Release(shader_11);
5130 static void nested_loop_test(IDirect3DDevice9 *device) {
5131 const DWORD shader_code[] = {
5132 0xffff0300, /* ps_3_0 */
5133 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5134 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5135 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5136 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5137 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5138 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5139 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5140 0x0000001d, /* endloop */
5141 0x0000001d, /* endloop */
5142 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5143 0x0000ffff /* end */
5145 IDirect3DPixelShader9 *shader;
5146 HRESULT hr;
5147 DWORD color;
5148 const float quad[] = {
5149 -1.0, -1.0, 0.1,
5150 1.0, -1.0, 0.1,
5151 -1.0, 1.0, 0.1,
5152 1.0, 1.0, 0.1
5155 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5156 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5157 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5158 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5159 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5160 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5162 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5164 hr = IDirect3DDevice9_BeginScene(device);
5165 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5166 if(SUCCEEDED(hr))
5168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5169 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5170 hr = IDirect3DDevice9_EndScene(device);
5171 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5174 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5176 color = getPixelColor(device, 360, 240);
5177 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5178 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5180 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5181 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5182 IDirect3DPixelShader9_Release(shader);
5185 struct varying_test_struct
5187 const DWORD *shader_code;
5188 IDirect3DPixelShader9 *shader;
5189 DWORD color, color_rhw;
5190 const char *name;
5191 BOOL todo, todo_rhw;
5194 struct hugeVertex
5196 float pos_x, pos_y, pos_z, rhw;
5197 float weight_1, weight_2, weight_3, weight_4;
5198 float index_1, index_2, index_3, index_4;
5199 float normal_1, normal_2, normal_3, normal_4;
5200 float fog_1, fog_2, fog_3, fog_4;
5201 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5202 float tangent_1, tangent_2, tangent_3, tangent_4;
5203 float binormal_1, binormal_2, binormal_3, binormal_4;
5204 float depth_1, depth_2, depth_3, depth_4;
5205 DWORD diffuse, specular;
5208 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5209 /* dcl_position: fails to compile */
5210 const DWORD blendweight_code[] = {
5211 0xffff0300, /* ps_3_0 */
5212 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5213 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5214 0x0000ffff /* end */
5216 const DWORD blendindices_code[] = {
5217 0xffff0300, /* ps_3_0 */
5218 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5219 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5220 0x0000ffff /* end */
5222 const DWORD normal_code[] = {
5223 0xffff0300, /* ps_3_0 */
5224 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5225 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5226 0x0000ffff /* end */
5228 /* psize: fails? */
5229 const DWORD texcoord0_code[] = {
5230 0xffff0300, /* ps_3_0 */
5231 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5232 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5233 0x0000ffff /* end */
5235 const DWORD tangent_code[] = {
5236 0xffff0300, /* ps_3_0 */
5237 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5238 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5239 0x0000ffff /* end */
5241 const DWORD binormal_code[] = {
5242 0xffff0300, /* ps_3_0 */
5243 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5244 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5245 0x0000ffff /* end */
5247 /* tessfactor: fails */
5248 /* positiont: fails */
5249 const DWORD color_code[] = {
5250 0xffff0300, /* ps_3_0 */
5251 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5252 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5253 0x0000ffff /* end */
5255 const DWORD fog_code[] = {
5256 0xffff0300, /* ps_3_0 */
5257 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5258 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5259 0x0000ffff /* end */
5261 const DWORD depth_code[] = {
5262 0xffff0300, /* ps_3_0 */
5263 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5264 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5265 0x0000ffff /* end */
5267 const DWORD specular_code[] = {
5268 0xffff0300, /* ps_3_0 */
5269 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5270 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5271 0x0000ffff /* end */
5273 /* sample: fails */
5275 struct varying_test_struct tests[] = {
5276 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5277 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5278 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5279 /* Why does dx not forward the texcoord? */
5280 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5281 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5282 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5283 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5284 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5285 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5286 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5288 /* Declare a monster vertex type :-) */
5289 static const D3DVERTEXELEMENT9 decl_elements[] = {
5290 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5291 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5292 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5293 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5294 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5295 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5296 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5297 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5298 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5299 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5300 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5301 D3DDECL_END()
5303 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5304 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5305 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5306 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5307 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5308 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5309 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5310 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5311 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5312 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5313 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5314 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5315 D3DDECL_END()
5317 struct hugeVertex data[4] = {
5319 -1.0, -1.0, 0.1, 1.0,
5320 0.1, 0.1, 0.1, 0.1,
5321 0.2, 0.2, 0.2, 0.2,
5322 0.3, 0.3, 0.3, 0.3,
5323 0.4, 0.4, 0.4, 0.4,
5324 0.50, 0.55, 0.55, 0.55,
5325 0.6, 0.6, 0.6, 0.7,
5326 0.7, 0.7, 0.7, 0.6,
5327 0.8, 0.8, 0.8, 0.8,
5328 0xe6e6e6e6, /* 0.9 * 256 */
5329 0x224488ff /* Nothing special */
5332 1.0, -1.0, 0.1, 1.0,
5333 0.1, 0.1, 0.1, 0.1,
5334 0.2, 0.2, 0.2, 0.2,
5335 0.3, 0.3, 0.3, 0.3,
5336 0.4, 0.4, 0.4, 0.4,
5337 0.50, 0.55, 0.55, 0.55,
5338 0.6, 0.6, 0.6, 0.7,
5339 0.7, 0.7, 0.7, 0.6,
5340 0.8, 0.8, 0.8, 0.8,
5341 0xe6e6e6e6, /* 0.9 * 256 */
5342 0x224488ff /* Nothing special */
5345 -1.0, 1.0, 0.1, 1.0,
5346 0.1, 0.1, 0.1, 0.1,
5347 0.2, 0.2, 0.2, 0.2,
5348 0.3, 0.3, 0.3, 0.3,
5349 0.4, 0.4, 0.4, 0.4,
5350 0.50, 0.55, 0.55, 0.55,
5351 0.6, 0.6, 0.6, 0.7,
5352 0.7, 0.7, 0.7, 0.6,
5353 0.8, 0.8, 0.8, 0.8,
5354 0xe6e6e6e6, /* 0.9 * 256 */
5355 0x224488ff /* Nothing special */
5358 1.0, 1.0, 0.1, 1.0,
5359 0.1, 0.1, 0.1, 0.1,
5360 0.2, 0.2, 0.2, 0.2,
5361 0.3, 0.3, 0.3, 0.3,
5362 0.4, 0.4, 0.4, 0.4,
5363 0.50, 0.55, 0.55, 0.55,
5364 0.6, 0.6, 0.6, 0.7,
5365 0.7, 0.7, 0.7, 0.6,
5366 0.8, 0.8, 0.8, 0.8,
5367 0xe6e6e6e6, /* 0.9 * 256 */
5368 0x224488ff /* Nothing special */
5371 struct hugeVertex data2[4];
5372 IDirect3DVertexDeclaration9 *decl;
5373 IDirect3DVertexDeclaration9 *decl2;
5374 HRESULT hr;
5375 unsigned int i;
5376 DWORD color, r, g, b, r_e, g_e, b_e;
5377 BOOL drawok;
5379 memcpy(data2, data, sizeof(data2));
5380 data2[0].pos_x = 0; data2[0].pos_y = 0;
5381 data2[1].pos_x = 640; data2[1].pos_y = 0;
5382 data2[2].pos_x = 0; data2[2].pos_y = 480;
5383 data2[3].pos_x = 640; data2[3].pos_y = 480;
5385 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5386 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5387 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5388 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5389 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5390 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5392 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5394 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5395 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5396 tests[i].name, hr);
5399 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5404 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5405 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5407 hr = IDirect3DDevice9_BeginScene(device);
5408 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5409 drawok = FALSE;
5410 if(SUCCEEDED(hr))
5412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5413 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5414 drawok = SUCCEEDED(hr);
5415 hr = IDirect3DDevice9_EndScene(device);
5416 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5418 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5419 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5421 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5422 * the failure and do not check the color if it failed
5424 if(!drawok) {
5425 continue;
5428 color = getPixelColor(device, 360, 240);
5429 r = color & 0x00ff0000 >> 16;
5430 g = color & 0x0000ff00 >> 8;
5431 b = color & 0x000000ff;
5432 r_e = tests[i].color & 0x00ff0000 >> 16;
5433 g_e = tests[i].color & 0x0000ff00 >> 8;
5434 b_e = tests[i].color & 0x000000ff;
5436 if(tests[i].todo) {
5437 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5438 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5439 tests[i].name, color, tests[i].color);
5440 } else {
5441 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5442 "Test %s returned color 0x%08x, expected 0x%08x\n",
5443 tests[i].name, color, tests[i].color);
5447 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5448 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5449 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5451 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5452 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5454 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5457 hr = IDirect3DDevice9_BeginScene(device);
5458 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5459 if(SUCCEEDED(hr))
5461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5462 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5463 hr = IDirect3DDevice9_EndScene(device);
5464 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5466 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5467 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5469 color = getPixelColor(device, 360, 240);
5470 r = color & 0x00ff0000 >> 16;
5471 g = color & 0x0000ff00 >> 8;
5472 b = color & 0x000000ff;
5473 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5474 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5475 b_e = tests[i].color_rhw & 0x000000ff;
5477 if(tests[i].todo_rhw) {
5478 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5479 * pipeline
5481 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5482 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5483 tests[i].name, color, tests[i].color_rhw);
5484 } else {
5485 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5486 "Test %s returned color 0x%08x, expected 0x%08x\n",
5487 tests[i].name, color, tests[i].color_rhw);
5491 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5493 IDirect3DPixelShader9_Release(tests[i].shader);
5496 IDirect3DVertexDeclaration9_Release(decl2);
5497 IDirect3DVertexDeclaration9_Release(decl);
5500 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5501 static const DWORD ps_code[] = {
5502 0xffff0300, /* ps_3_0 */
5503 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5504 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5505 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5506 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5507 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5508 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5509 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5510 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5511 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5513 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5514 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5515 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5516 0x0000001d, /* endloop */
5517 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5518 0x0000ffff /* end */
5520 static const DWORD vs_1_code[] = {
5521 0xfffe0101, /* vs_1_1 */
5522 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5523 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5524 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5525 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5526 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5527 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5528 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5529 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5530 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5531 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5532 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5533 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5534 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5535 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5536 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5537 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5538 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5539 0x0000ffff
5541 DWORD vs_2_code[] = {
5542 0xfffe0200, /* vs_2_0 */
5543 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5544 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5545 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5546 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5547 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5548 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5549 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5550 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5551 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5552 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5553 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5554 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5555 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5556 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5557 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5558 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5559 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5560 0x0000ffff /* end */
5562 /* TODO: Define normal, tangent, blendweight and depth here */
5563 static const DWORD vs_3_code[] = {
5564 0xfffe0300, /* vs_3_0 */
5565 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5566 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5567 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5568 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5569 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5570 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5571 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5572 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5573 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5574 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5575 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5576 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5577 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5578 0x0000ffff /* end */
5580 float quad1[] = {
5581 -1.0, -1.0, 0.1,
5582 0.0, -1.0, 0.1,
5583 -1.0, 0.0, 0.1,
5584 0.0, 0.0, 0.1
5586 float quad2[] = {
5587 0.0, -1.0, 0.1,
5588 1.0, -1.0, 0.1,
5589 0.0, 0.0, 0.1,
5590 1.0, 0.0, 0.1
5592 float quad3[] = {
5593 -1.0, 0.0, 0.1,
5594 0.0, 0.0, 0.1,
5595 -1.0, 1.0, 0.1,
5596 0.0, 1.0, 0.1
5599 HRESULT hr;
5600 DWORD color;
5601 IDirect3DPixelShader9 *pixelshader = NULL;
5602 IDirect3DVertexShader9 *vs_1_shader = NULL;
5603 IDirect3DVertexShader9 *vs_2_shader = NULL;
5604 IDirect3DVertexShader9 *vs_3_shader = NULL;
5606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5608 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5609 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5610 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5611 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5612 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5613 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5614 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5615 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5616 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5617 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5618 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5620 hr = IDirect3DDevice9_BeginScene(device);
5621 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5622 if(SUCCEEDED(hr))
5624 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5625 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5627 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5629 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5630 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5632 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5634 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5635 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5637 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5639 hr = IDirect3DDevice9_EndScene(device);
5640 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5642 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5643 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5645 color = getPixelColor(device, 160, 120);
5646 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5647 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5648 /* Accept two ways of oFog handling:
5650 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5651 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5653 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5654 * This happens with software vertex processing and on Intel cards
5656 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5657 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5659 color = getPixelColor(device, 160, 360);
5660 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5661 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5662 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5663 color = getPixelColor(device, 480, 360);
5664 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5665 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5666 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5668 /* cleanup */
5669 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5670 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5671 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5672 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5673 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5674 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5675 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5676 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5679 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5680 static const DWORD vs_code[] = {
5681 0xfffe0300, /* vs_3_0 */
5682 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5683 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5684 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5685 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5686 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5687 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5688 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5689 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5690 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5691 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5692 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5693 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5694 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5696 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5697 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5698 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5699 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5700 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5701 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5702 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5703 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5704 0x0000ffff /* end */
5706 static const DWORD ps_1_code[] = {
5707 0xffff0104, /* ps_1_4 */
5708 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5709 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5710 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5711 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5712 0x0000ffff /* end */
5714 static const DWORD ps_2_code[] = {
5715 0xffff0200, /* ps_2_0 */
5716 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5717 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5718 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5720 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5721 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5722 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5723 0x0000ffff /* end */
5725 static const DWORD ps_3_code[] = {
5726 0xffff0300, /* ps_3_0 */
5727 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5728 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5729 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5731 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5732 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5733 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5734 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5735 0x0000ffff /* end */
5738 float quad1[] = {
5739 -1.0, -1.0, 0.1,
5740 0.0, -1.0, 0.1,
5741 -1.0, 0.0, 0.1,
5742 0.0, 0.0, 0.1
5744 float quad2[] = {
5745 0.0, -1.0, 0.1,
5746 1.0, -1.0, 0.1,
5747 0.0, 0.0, 0.1,
5748 1.0, 0.0, 0.1
5750 float quad3[] = {
5751 -1.0, 0.0, 0.1,
5752 0.0, 0.0, 0.1,
5753 -1.0, 1.0, 0.1,
5754 0.0, 1.0, 0.1
5756 float quad4[] = {
5757 0.0, 0.0, 0.1,
5758 1.0, 0.0, 0.1,
5759 0.0, 1.0, 0.1,
5760 1.0, 1.0, 0.1
5763 HRESULT hr;
5764 DWORD color;
5765 IDirect3DVertexShader9 *vertexshader = NULL;
5766 IDirect3DPixelShader9 *ps_1_shader = NULL;
5767 IDirect3DPixelShader9 *ps_2_shader = NULL;
5768 IDirect3DPixelShader9 *ps_3_shader = NULL;
5769 IDirect3DTexture9 *texture = NULL;
5770 D3DLOCKED_RECT lr;
5771 unsigned int x, y;
5773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5775 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5777 if(FAILED(hr)) {
5778 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5779 return;
5781 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5782 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5783 for(y = 0; y < 512; y++) {
5784 for(x = 0; x < 512; x++) {
5785 double r_f = (double) x / (double) 512;
5786 double g_f = (double) y / (double) 512;
5787 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5788 unsigned short r = (unsigned short) (r_f * 65535.0);
5789 unsigned short g = (unsigned short) (g_f * 65535.0);
5790 dst[0] = r;
5791 dst[1] = g;
5792 dst[2] = 0;
5793 dst[3] = 65535;
5796 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5797 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5799 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5800 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5801 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5802 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5803 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5804 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5805 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5806 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5807 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5808 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5809 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5811 hr = IDirect3DDevice9_BeginScene(device);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5813 if(SUCCEEDED(hr))
5815 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5816 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5818 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5820 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5821 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5823 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5825 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5826 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5828 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5830 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5831 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5832 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5833 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5834 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5835 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5837 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5839 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5841 hr = IDirect3DDevice9_EndScene(device);
5842 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5844 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5845 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5847 color = getPixelColor(device, 160, 120);
5848 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5849 (color & 0x0000ff00) == 0x0000ff00 &&
5850 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5851 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5852 color = getPixelColor(device, 160, 360);
5853 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5854 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5855 (color & 0x000000ff) == 0x00000000,
5856 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5857 color = getPixelColor(device, 480, 360);
5858 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5859 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5860 (color & 0x000000ff) == 0x00000000,
5861 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5862 color = getPixelColor(device, 480, 160);
5863 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5864 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5865 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5866 (color & 0x000000ff) == 0x00000000),
5867 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5869 /* cleanup */
5870 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5871 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5872 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5873 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5874 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5875 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5876 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5877 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5878 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5879 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5880 if(texture) IDirect3DTexture9_Release(texture);
5883 static void test_compare_instructions(IDirect3DDevice9 *device)
5885 DWORD shader_sge_vec_code[] = {
5886 0xfffe0101, /* vs_1_1 */
5887 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5888 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5889 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5890 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5891 0x0000ffff /* end */
5893 DWORD shader_slt_vec_code[] = {
5894 0xfffe0101, /* vs_1_1 */
5895 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5896 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5897 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5898 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5899 0x0000ffff /* end */
5901 DWORD shader_sge_scalar_code[] = {
5902 0xfffe0101, /* vs_1_1 */
5903 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5904 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5905 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5906 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5907 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5908 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5909 0x0000ffff /* end */
5911 DWORD shader_slt_scalar_code[] = {
5912 0xfffe0101, /* vs_1_1 */
5913 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5914 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5915 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5916 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5917 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5918 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5919 0x0000ffff /* end */
5921 IDirect3DVertexShader9 *shader_sge_vec;
5922 IDirect3DVertexShader9 *shader_slt_vec;
5923 IDirect3DVertexShader9 *shader_sge_scalar;
5924 IDirect3DVertexShader9 *shader_slt_scalar;
5925 HRESULT hr, color;
5926 float quad1[] = {
5927 -1.0, -1.0, 0.1,
5928 0.0, -1.0, 0.1,
5929 -1.0, 0.0, 0.1,
5930 0.0, 0.0, 0.1
5932 float quad2[] = {
5933 0.0, -1.0, 0.1,
5934 1.0, -1.0, 0.1,
5935 0.0, 0.0, 0.1,
5936 1.0, 0.0, 0.1
5938 float quad3[] = {
5939 -1.0, 0.0, 0.1,
5940 0.0, 0.0, 0.1,
5941 -1.0, 1.0, 0.1,
5942 0.0, 1.0, 0.1
5944 float quad4[] = {
5945 0.0, 0.0, 0.1,
5946 1.0, 0.0, 0.1,
5947 0.0, 1.0, 0.1,
5948 1.0, 1.0, 0.1
5950 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5951 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5953 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5955 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5956 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5957 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5958 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5959 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5960 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5961 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5962 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5963 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5964 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5965 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5966 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5967 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5968 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5970 hr = IDirect3DDevice9_BeginScene(device);
5971 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5972 if(SUCCEEDED(hr))
5974 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5975 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5977 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5979 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5980 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5982 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5984 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5985 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5987 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5989 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5990 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5992 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5993 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5995 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5997 hr = IDirect3DDevice9_EndScene(device);
5998 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6001 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6002 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6003 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6004 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6006 color = getPixelColor(device, 160, 360);
6007 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6008 color = getPixelColor(device, 480, 360);
6009 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6010 color = getPixelColor(device, 160, 120);
6011 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6012 color = getPixelColor(device, 480, 160);
6013 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6015 IDirect3DVertexShader9_Release(shader_sge_vec);
6016 IDirect3DVertexShader9_Release(shader_slt_vec);
6017 IDirect3DVertexShader9_Release(shader_sge_scalar);
6018 IDirect3DVertexShader9_Release(shader_slt_scalar);
6021 static void test_vshader_input(IDirect3DDevice9 *device)
6023 DWORD swapped_shader_code_3[] = {
6024 0xfffe0300, /* vs_3_0 */
6025 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6026 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6027 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6028 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6029 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6030 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6031 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6032 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6033 0x0000ffff /* end */
6035 DWORD swapped_shader_code_1[] = {
6036 0xfffe0101, /* vs_1_1 */
6037 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6038 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6039 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6040 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6041 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6042 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6043 0x0000ffff /* end */
6045 DWORD swapped_shader_code_2[] = {
6046 0xfffe0200, /* vs_2_0 */
6047 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6048 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6049 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6050 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6051 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6052 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6053 0x0000ffff /* end */
6055 DWORD texcoord_color_shader_code_3[] = {
6056 0xfffe0300, /* vs_3_0 */
6057 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6058 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6059 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6060 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6061 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6062 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6063 0x0000ffff /* end */
6065 DWORD texcoord_color_shader_code_2[] = {
6066 0xfffe0200, /* vs_2_0 */
6067 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6068 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6069 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6070 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6071 0x0000ffff /* end */
6073 DWORD texcoord_color_shader_code_1[] = {
6074 0xfffe0101, /* vs_1_1 */
6075 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6076 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6077 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6078 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6079 0x0000ffff /* end */
6081 DWORD color_color_shader_code_3[] = {
6082 0xfffe0300, /* vs_3_0 */
6083 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6084 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6085 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6086 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6087 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6088 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6089 0x0000ffff /* end */
6091 DWORD color_color_shader_code_2[] = {
6092 0xfffe0200, /* vs_2_0 */
6093 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6094 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6095 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6096 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6097 0x0000ffff /* end */
6099 DWORD color_color_shader_code_1[] = {
6100 0xfffe0101, /* vs_1_1 */
6101 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6102 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6103 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6104 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6105 0x0000ffff /* end */
6107 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6108 HRESULT hr;
6109 DWORD color;
6110 float quad1[] = {
6111 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6112 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6113 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6114 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6116 float quad2[] = {
6117 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6118 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6119 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6120 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6122 float quad3[] = {
6123 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6124 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6125 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6126 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6128 float quad4[] = {
6129 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6130 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6131 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6132 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6134 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6135 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6136 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6137 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6138 D3DDECL_END()
6140 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6141 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6142 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6143 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6144 D3DDECL_END()
6146 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6147 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6148 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6149 D3DDECL_END()
6151 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6152 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6153 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6154 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6155 D3DDECL_END()
6157 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6158 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6159 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6160 D3DDECL_END()
6162 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6163 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6164 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6165 D3DDECL_END()
6167 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6168 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6169 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6170 D3DDECL_END()
6172 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6173 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6174 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6175 D3DDECL_END()
6177 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6178 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6179 unsigned int i;
6180 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6181 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6183 struct vertex quad1_color[] = {
6184 {-1.0, -1.0, 0.1, 0x00ff8040},
6185 { 0.0, -1.0, 0.1, 0x00ff8040},
6186 {-1.0, 0.0, 0.1, 0x00ff8040},
6187 { 0.0, 0.0, 0.1, 0x00ff8040}
6189 struct vertex quad2_color[] = {
6190 { 0.0, -1.0, 0.1, 0x00ff8040},
6191 { 1.0, -1.0, 0.1, 0x00ff8040},
6192 { 0.0, 0.0, 0.1, 0x00ff8040},
6193 { 1.0, 0.0, 0.1, 0x00ff8040}
6195 struct vertex quad3_color[] = {
6196 {-1.0, 0.0, 0.1, 0x00ff8040},
6197 { 0.0, 0.0, 0.1, 0x00ff8040},
6198 {-1.0, 1.0, 0.1, 0x00ff8040},
6199 { 0.0, 1.0, 0.1, 0x00ff8040}
6201 float quad4_color[] = {
6202 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6203 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6204 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6205 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6208 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6209 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6210 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6212 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6213 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6214 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6215 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6217 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6218 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6219 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6220 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6221 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6222 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6223 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6226 for(i = 1; i <= 3; i++) {
6227 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6228 if(i == 3) {
6229 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6230 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6231 } else if(i == 2){
6232 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6233 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6234 } else if(i == 1) {
6235 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6236 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6239 hr = IDirect3DDevice9_BeginScene(device);
6240 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6241 if(SUCCEEDED(hr))
6243 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6244 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6246 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6247 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6249 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6251 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6252 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6254 if(i == 3 || i == 2) {
6255 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6256 } else if(i == 1) {
6257 /* Succeeds or fails, depending on SW or HW vertex processing */
6258 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6261 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6262 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6263 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6264 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6266 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6267 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6269 if(i == 3 || i == 2) {
6270 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6271 } else if(i == 1) {
6272 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6275 hr = IDirect3DDevice9_EndScene(device);
6276 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6279 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6280 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6282 if(i == 3 || i == 2) {
6283 color = getPixelColor(device, 160, 360);
6284 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6285 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6287 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6288 color = getPixelColor(device, 480, 360);
6289 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6290 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6291 color = getPixelColor(device, 160, 120);
6292 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6293 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6294 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6296 color = getPixelColor(device, 480, 160);
6297 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6298 } else if(i == 1) {
6299 color = getPixelColor(device, 160, 360);
6300 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6301 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6302 color = getPixelColor(device, 480, 360);
6303 /* Accept the clear color as well in this case, since SW VP returns an error */
6304 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6305 color = getPixelColor(device, 160, 120);
6306 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6307 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6308 color = getPixelColor(device, 480, 160);
6309 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6312 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6313 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6315 /* Now find out if the whole streams are re-read, or just the last active value for the
6316 * vertices is used.
6318 hr = IDirect3DDevice9_BeginScene(device);
6319 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6320 if(SUCCEEDED(hr))
6322 float quad1_modified[] = {
6323 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6324 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6325 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6326 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6328 float quad2_modified[] = {
6329 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6330 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6331 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6332 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6335 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6336 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6338 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6341 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6343 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6346 if(i == 3 || i == 2) {
6347 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6348 } else if(i == 1) {
6349 /* Succeeds or fails, depending on SW or HW vertex processing */
6350 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6353 hr = IDirect3DDevice9_EndScene(device);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6356 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6359 color = getPixelColor(device, 480, 350);
6360 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6361 * as well.
6363 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6364 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6365 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6366 * refrast's result.
6368 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6370 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6371 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6372 color = getPixelColor(device, 160, 120);
6374 IDirect3DDevice9_SetVertexShader(device, NULL);
6375 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6377 IDirect3DVertexShader9_Release(swapped_shader);
6380 for(i = 1; i <= 3; i++) {
6381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6382 if(i == 3) {
6383 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6385 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6386 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6387 } else if(i == 2){
6388 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6389 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392 } else if(i == 1) {
6393 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6394 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6395 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6396 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6399 hr = IDirect3DDevice9_BeginScene(device);
6400 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6401 if(SUCCEEDED(hr))
6403 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6404 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6405 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6408 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6410 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6413 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6414 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6415 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6418 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6420 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6421 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6422 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6423 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6425 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6427 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6428 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6430 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6432 hr = IDirect3DDevice9_EndScene(device);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6435 IDirect3DDevice9_SetVertexShader(device, NULL);
6436 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6438 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6439 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6441 color = getPixelColor(device, 160, 360);
6442 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6443 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6444 color = getPixelColor(device, 480, 360);
6445 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6446 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6447 color = getPixelColor(device, 160, 120);
6448 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6449 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6450 color = getPixelColor(device, 480, 160);
6451 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6452 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6454 IDirect3DVertexShader9_Release(texcoord_color_shader);
6455 IDirect3DVertexShader9_Release(color_color_shader);
6458 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6459 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6460 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6461 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6463 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6464 IDirect3DVertexDeclaration9_Release(decl_color_color);
6465 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6466 IDirect3DVertexDeclaration9_Release(decl_color_float);
6469 static void srgbtexture_test(IDirect3DDevice9 *device)
6471 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6472 * texture stage state to render a quad using that texture. The resulting
6473 * color components should be 0x36 (~ 0.21), per this formula:
6474 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6475 * This is true where srgb_color > 0.04045.
6477 IDirect3D9 *d3d = NULL;
6478 HRESULT hr;
6479 LPDIRECT3DTEXTURE9 texture = NULL;
6480 LPDIRECT3DSURFACE9 surface = NULL;
6481 D3DLOCKED_RECT lr;
6482 DWORD color;
6483 float quad[] = {
6484 -1.0, 1.0, 0.0, 0.0, 0.0,
6485 1.0, 1.0, 0.0, 1.0, 0.0,
6486 -1.0, -1.0, 0.0, 0.0, 1.0,
6487 1.0, -1.0, 0.0, 1.0, 1.0,
6491 memset(&lr, 0, sizeof(lr));
6492 IDirect3DDevice9_GetDirect3D(device, &d3d);
6493 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6494 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6495 D3DFMT_A8R8G8B8) != D3D_OK) {
6496 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6497 goto out;
6500 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6501 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6502 &texture, NULL);
6503 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6504 if(!texture) {
6505 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6506 goto out;
6508 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6509 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6511 fill_surface(surface, 0xff7f7f7f);
6512 IDirect3DSurface9_Release(surface);
6514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6515 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6516 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6517 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6519 hr = IDirect3DDevice9_BeginScene(device);
6520 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6521 if(SUCCEEDED(hr))
6523 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6524 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6526 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6527 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6531 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6533 hr = IDirect3DDevice9_EndScene(device);
6534 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6537 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6538 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6539 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6540 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6542 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6543 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6545 color = getPixelColor(device, 320, 240);
6546 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6548 out:
6549 if(texture) IDirect3DTexture9_Release(texture);
6550 IDirect3D9_Release(d3d);
6553 static void shademode_test(IDirect3DDevice9 *device)
6555 /* Render a quad and try all of the different fixed function shading models. */
6556 HRESULT hr;
6557 DWORD color0, color1;
6558 DWORD color0_gouraud = 0, color1_gouraud = 0;
6559 DWORD shademode = D3DSHADE_FLAT;
6560 DWORD primtype = D3DPT_TRIANGLESTRIP;
6561 LPVOID data = NULL;
6562 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6563 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6564 UINT i, j;
6565 struct vertex quad_strip[] =
6567 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6568 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6569 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6570 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6572 struct vertex quad_list[] =
6574 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6575 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6576 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6578 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6579 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6580 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6583 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6584 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6585 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6586 if (FAILED(hr)) goto bail;
6588 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6589 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6590 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6591 if (FAILED(hr)) goto bail;
6593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6596 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6597 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6599 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6600 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6601 memcpy(data, quad_strip, sizeof(quad_strip));
6602 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6603 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6605 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6606 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6607 memcpy(data, quad_list, sizeof(quad_list));
6608 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6609 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6611 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6612 * the color fixups we have to do for FLAT shading will be dependent on that. */
6613 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6614 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6616 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6617 for (j=0; j<2; j++) {
6619 /* Inner loop just changes the D3DRS_SHADEMODE */
6620 for (i=0; i<3; i++) {
6621 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6622 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6625 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6627 hr = IDirect3DDevice9_BeginScene(device);
6628 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6629 if(SUCCEEDED(hr))
6631 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6632 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6634 hr = IDirect3DDevice9_EndScene(device);
6635 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6638 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6639 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6641 /* Sample two spots from the output */
6642 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6643 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6644 switch(shademode) {
6645 case D3DSHADE_FLAT:
6646 /* Should take the color of the first vertex of each triangle */
6647 if (0)
6649 /* This test depends on EXT_provoking_vertex being
6650 * available. This extension is currently (20090810)
6651 * not common enough to let the test fail if it isn't
6652 * present. */
6653 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6654 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6656 shademode = D3DSHADE_GOURAUD;
6657 break;
6658 case D3DSHADE_GOURAUD:
6659 /* Should be an interpolated blend */
6661 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6662 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6663 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6664 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6666 color0_gouraud = color0;
6667 color1_gouraud = color1;
6669 shademode = D3DSHADE_PHONG;
6670 break;
6671 case D3DSHADE_PHONG:
6672 /* Should be the same as GOURAUD, since no hardware implements this */
6673 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6674 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6675 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6676 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6678 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6679 color0_gouraud, color0);
6680 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6681 color1_gouraud, color1);
6682 break;
6685 /* Now, do it all over again with a TRIANGLELIST */
6686 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6687 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6688 primtype = D3DPT_TRIANGLELIST;
6689 shademode = D3DSHADE_FLAT;
6692 bail:
6693 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6694 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6696 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6698 if (vb_strip)
6699 IDirect3DVertexBuffer9_Release(vb_strip);
6700 if (vb_list)
6701 IDirect3DVertexBuffer9_Release(vb_list);
6705 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6707 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6708 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6709 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6710 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6711 * 0.73
6713 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6714 * so use shaders for this task
6716 IDirect3DPixelShader9 *pshader;
6717 IDirect3DVertexShader9 *vshader;
6718 IDirect3D9 *d3d;
6719 DWORD vshader_code[] = {
6720 0xfffe0101, /* vs_1_1 */
6721 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6722 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6723 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6724 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6725 0x0000ffff /* end */
6727 DWORD pshader_code[] = {
6728 0xffff0101, /* ps_1_1 */
6729 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6730 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6731 0x0000ffff /* end */
6733 const float quad[] = {
6734 -1.0, -1.0, 0.1,
6735 1.0, -1.0, 0.1,
6736 -1.0, 1.0, 0.1,
6737 1.0, 1.0, 0.1
6739 HRESULT hr;
6740 D3DCOLOR color;
6742 IDirect3DDevice9_GetDirect3D(device, &d3d);
6743 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6744 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6745 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6746 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6747 * works
6749 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6750 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6751 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6752 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6753 IDirect3D9_Release(d3d);
6754 return;
6756 IDirect3D9_Release(d3d);
6758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6759 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6762 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6764 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6766 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6767 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6768 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6770 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6772 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6774 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6775 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6777 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6778 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6779 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6780 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6781 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6783 hr = IDirect3DDevice9_BeginScene(device);
6784 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6785 if(SUCCEEDED(hr)) {
6786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6787 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6789 hr = IDirect3DDevice9_EndScene(device);
6790 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6793 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6795 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6796 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6797 IDirect3DPixelShader9_Release(pshader);
6798 IDirect3DVertexShader9_Release(vshader);
6800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6801 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6806 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6807 color = getPixelColor(device, 160, 360);
6808 ok(color_match(color, 0x00808080, 1),
6809 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6812 static void alpha_test(IDirect3DDevice9 *device)
6814 HRESULT hr;
6815 IDirect3DTexture9 *offscreenTexture;
6816 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6817 DWORD color;
6819 struct vertex quad1[] =
6821 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6822 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6823 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6824 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6826 struct vertex quad2[] =
6828 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6829 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6830 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6831 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6833 static const float composite_quad[][5] = {
6834 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6835 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6836 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6837 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6840 /* Clear the render target with alpha = 0.5 */
6841 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6842 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6844 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6845 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6847 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6848 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6849 if(!backbuffer) {
6850 goto out;
6853 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6854 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6855 if(!offscreen) {
6856 goto out;
6859 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6860 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6862 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6863 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6864 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6865 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6866 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6867 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6868 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6869 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6871 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6874 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6875 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6877 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6881 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6883 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6887 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6890 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6892 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6893 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6894 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6895 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6896 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6897 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6898 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6901 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6905 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6908 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6910 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6912 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6914 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6915 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6917 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6918 * Disable alpha blending for the final composition
6920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6921 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6922 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6923 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6925 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6926 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6928 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6929 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6930 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6932 hr = IDirect3DDevice9_EndScene(device);
6933 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6936 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6938 color = getPixelColor(device, 160, 360);
6939 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6940 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6942 color = getPixelColor(device, 160, 120);
6943 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6944 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6946 color = getPixelColor(device, 480, 360);
6947 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6948 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6950 color = getPixelColor(device, 480, 120);
6951 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6952 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6954 out:
6955 /* restore things */
6956 if(backbuffer) {
6957 IDirect3DSurface9_Release(backbuffer);
6959 if(offscreenTexture) {
6960 IDirect3DTexture9_Release(offscreenTexture);
6962 if(offscreen) {
6963 IDirect3DSurface9_Release(offscreen);
6967 struct vertex_shortcolor {
6968 float x, y, z;
6969 unsigned short r, g, b, a;
6971 struct vertex_floatcolor {
6972 float x, y, z;
6973 float r, g, b, a;
6976 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6978 HRESULT hr;
6979 BOOL s_ok, ub_ok, f_ok;
6980 DWORD color, size, i;
6981 void *data;
6982 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6983 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6984 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6985 D3DDECL_END()
6987 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6988 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6989 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6990 D3DDECL_END()
6992 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6993 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6994 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6995 D3DDECL_END()
6997 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6998 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6999 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7000 D3DDECL_END()
7002 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7003 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7004 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7005 D3DDECL_END()
7007 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7008 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7009 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7010 D3DDECL_END()
7012 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7013 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7014 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7015 D3DDECL_END()
7017 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7018 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7019 IDirect3DVertexBuffer9 *vb, *vb2;
7020 struct vertex quad1[] = /* D3DCOLOR */
7022 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7023 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7024 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7025 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7027 struct vertex quad2[] = /* UBYTE4N */
7029 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7030 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7031 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7032 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7034 struct vertex_shortcolor quad3[] = /* short */
7036 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7037 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7038 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7039 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7041 struct vertex_floatcolor quad4[] =
7043 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7044 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7045 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7046 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7048 DWORD colors[] = {
7049 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7050 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7051 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7052 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7053 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7054 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7055 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7056 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7057 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7058 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7059 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7060 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7061 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7062 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7063 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7064 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7066 float quads[] = {
7067 -1.0, -1.0, 0.1,
7068 -1.0, 0.0, 0.1,
7069 0.0, -1.0, 0.1,
7070 0.0, 0.0, 0.1,
7072 0.0, -1.0, 0.1,
7073 0.0, 0.0, 0.1,
7074 1.0, -1.0, 0.1,
7075 1.0, 0.0, 0.1,
7077 0.0, 0.0, 0.1,
7078 0.0, 1.0, 0.1,
7079 1.0, 0.0, 0.1,
7080 1.0, 1.0, 0.1,
7082 -1.0, 0.0, 0.1,
7083 -1.0, 1.0, 0.1,
7084 0.0, 0.0, 0.1,
7085 0.0, 1.0, 0.1
7087 struct tvertex quad_transformed[] = {
7088 { 90, 110, 0.1, 2.0, 0x00ffff00},
7089 { 570, 110, 0.1, 2.0, 0x00ffff00},
7090 { 90, 300, 0.1, 2.0, 0x00ffff00},
7091 { 570, 300, 0.1, 2.0, 0x00ffff00}
7093 D3DCAPS9 caps;
7095 memset(&caps, 0, sizeof(caps));
7096 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7097 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7099 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7100 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7102 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7103 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7104 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7105 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7106 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7107 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7108 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7109 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7110 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7111 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7112 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7113 } else {
7114 trace("D3DDTCAPS_UBYTE4N not supported\n");
7115 dcl_ubyte_2 = NULL;
7116 dcl_ubyte = NULL;
7118 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7119 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7120 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7121 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7123 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7124 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7125 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7126 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7128 hr = IDirect3DDevice9_BeginScene(device);
7129 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7130 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7131 if(SUCCEEDED(hr)) {
7132 if(dcl_color) {
7133 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7134 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7136 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7139 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7140 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7141 * using software vertex processing. Doh!
7143 if(dcl_ubyte) {
7144 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7145 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7147 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7148 ub_ok = SUCCEEDED(hr);
7151 if(dcl_short) {
7152 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7153 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7155 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7156 s_ok = SUCCEEDED(hr);
7159 if(dcl_float) {
7160 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7161 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7163 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7164 f_ok = SUCCEEDED(hr);
7167 hr = IDirect3DDevice9_EndScene(device);
7168 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7171 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7172 if(dcl_short) {
7173 color = getPixelColor(device, 480, 360);
7174 ok(color == 0x000000ff || !s_ok,
7175 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7177 if(dcl_ubyte) {
7178 color = getPixelColor(device, 160, 120);
7179 ok(color == 0x0000ffff || !ub_ok,
7180 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7182 if(dcl_color) {
7183 color = getPixelColor(device, 160, 360);
7184 ok(color == 0x00ffff00,
7185 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7187 if(dcl_float) {
7188 color = getPixelColor(device, 480, 120);
7189 ok(color == 0x00ff0000 || !f_ok,
7190 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7193 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7194 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7195 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7196 * whether the immediate mode code works
7198 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7199 hr = IDirect3DDevice9_BeginScene(device);
7200 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7201 if(SUCCEEDED(hr)) {
7202 if(dcl_color) {
7203 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7204 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7205 memcpy(data, quad1, sizeof(quad1));
7206 hr = IDirect3DVertexBuffer9_Unlock(vb);
7207 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7208 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7209 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7210 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7211 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7212 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7213 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7216 if(dcl_ubyte) {
7217 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7218 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7219 memcpy(data, quad2, sizeof(quad2));
7220 hr = IDirect3DVertexBuffer9_Unlock(vb);
7221 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7222 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7223 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7224 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7225 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7226 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7227 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7228 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7229 ub_ok = SUCCEEDED(hr);
7232 if(dcl_short) {
7233 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7234 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7235 memcpy(data, quad3, sizeof(quad3));
7236 hr = IDirect3DVertexBuffer9_Unlock(vb);
7237 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7238 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7240 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7241 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7242 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7243 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7244 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7245 s_ok = SUCCEEDED(hr);
7248 if(dcl_float) {
7249 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7250 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7251 memcpy(data, quad4, sizeof(quad4));
7252 hr = IDirect3DVertexBuffer9_Unlock(vb);
7253 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7254 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7255 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7256 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7258 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7259 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7260 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7261 f_ok = SUCCEEDED(hr);
7264 hr = IDirect3DDevice9_EndScene(device);
7265 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7268 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7269 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7270 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7271 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7273 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7274 if(dcl_short) {
7275 color = getPixelColor(device, 480, 360);
7276 ok(color == 0x000000ff || !s_ok,
7277 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7279 if(dcl_ubyte) {
7280 color = getPixelColor(device, 160, 120);
7281 ok(color == 0x0000ffff || !ub_ok,
7282 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7284 if(dcl_color) {
7285 color = getPixelColor(device, 160, 360);
7286 ok(color == 0x00ffff00,
7287 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7289 if(dcl_float) {
7290 color = getPixelColor(device, 480, 120);
7291 ok(color == 0x00ff0000 || !f_ok,
7292 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7295 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7296 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7298 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7299 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7300 memcpy(data, quad_transformed, sizeof(quad_transformed));
7301 hr = IDirect3DVertexBuffer9_Unlock(vb);
7302 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7304 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7305 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307 hr = IDirect3DDevice9_BeginScene(device);
7308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7309 if(SUCCEEDED(hr)) {
7310 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7311 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7312 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7313 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7315 hr = IDirect3DDevice9_EndScene(device);
7316 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7319 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7320 color = getPixelColor(device, 88, 108);
7321 ok(color == 0x000000ff,
7322 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7323 color = getPixelColor(device, 92, 108);
7324 ok(color == 0x000000ff,
7325 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7326 color = getPixelColor(device, 88, 112);
7327 ok(color == 0x000000ff,
7328 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7329 color = getPixelColor(device, 92, 112);
7330 ok(color == 0x00ffff00,
7331 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7333 color = getPixelColor(device, 568, 108);
7334 ok(color == 0x000000ff,
7335 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7336 color = getPixelColor(device, 572, 108);
7337 ok(color == 0x000000ff,
7338 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7339 color = getPixelColor(device, 568, 112);
7340 ok(color == 0x00ffff00,
7341 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7342 color = getPixelColor(device, 572, 112);
7343 ok(color == 0x000000ff,
7344 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7346 color = getPixelColor(device, 88, 298);
7347 ok(color == 0x000000ff,
7348 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7349 color = getPixelColor(device, 92, 298);
7350 ok(color == 0x00ffff00,
7351 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7352 color = getPixelColor(device, 88, 302);
7353 ok(color == 0x000000ff,
7354 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7355 color = getPixelColor(device, 92, 302);
7356 ok(color == 0x000000ff,
7357 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7359 color = getPixelColor(device, 568, 298);
7360 ok(color == 0x00ffff00,
7361 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7362 color = getPixelColor(device, 572, 298);
7363 ok(color == 0x000000ff,
7364 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7365 color = getPixelColor(device, 568, 302);
7366 ok(color == 0x000000ff,
7367 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7368 color = getPixelColor(device, 572, 302);
7369 ok(color == 0x000000ff,
7370 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7372 /* This test is pointless without those two declarations: */
7373 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7374 skip("color-ubyte switching test declarations aren't supported\n");
7375 goto out;
7378 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7379 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7380 memcpy(data, quads, sizeof(quads));
7381 hr = IDirect3DVertexBuffer9_Unlock(vb);
7382 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7383 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7384 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7385 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7386 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7387 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7388 memcpy(data, colors, sizeof(colors));
7389 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7390 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7392 for(i = 0; i < 2; i++) {
7393 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7394 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7396 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7397 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7398 if(i == 0) {
7399 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7400 } else {
7401 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7405 hr = IDirect3DDevice9_BeginScene(device);
7406 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7407 ub_ok = FALSE;
7408 if(SUCCEEDED(hr)) {
7409 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7410 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7411 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7412 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7413 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7414 ub_ok = SUCCEEDED(hr);
7416 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7417 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7418 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7419 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7421 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7422 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7423 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7424 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7425 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7426 ub_ok = (SUCCEEDED(hr) && ub_ok);
7428 hr = IDirect3DDevice9_EndScene(device);
7429 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7432 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7433 if(i == 0) {
7434 color = getPixelColor(device, 480, 360);
7435 ok(color == 0x00ff0000,
7436 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7437 color = getPixelColor(device, 160, 120);
7438 ok(color == 0x00ffffff,
7439 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7440 color = getPixelColor(device, 160, 360);
7441 ok(color == 0x000000ff || !ub_ok,
7442 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7443 color = getPixelColor(device, 480, 120);
7444 ok(color == 0x000000ff || !ub_ok,
7445 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7446 } else {
7447 color = getPixelColor(device, 480, 360);
7448 ok(color == 0x000000ff,
7449 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7450 color = getPixelColor(device, 160, 120);
7451 ok(color == 0x00ffffff,
7452 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7453 color = getPixelColor(device, 160, 360);
7454 ok(color == 0x00ff0000 || !ub_ok,
7455 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7456 color = getPixelColor(device, 480, 120);
7457 ok(color == 0x00ff0000 || !ub_ok,
7458 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7462 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7463 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7464 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7465 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7466 IDirect3DVertexBuffer9_Release(vb2);
7468 out:
7469 IDirect3DVertexBuffer9_Release(vb);
7470 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7471 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7472 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7473 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7474 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7475 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7476 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7479 struct vertex_float16color {
7480 float x, y, z;
7481 DWORD c1, c2;
7484 static void test_vshader_float16(IDirect3DDevice9 *device)
7486 HRESULT hr;
7487 DWORD color;
7488 void *data;
7489 static const D3DVERTEXELEMENT9 decl_elements[] = {
7490 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7491 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7492 D3DDECL_END()
7494 IDirect3DVertexDeclaration9 *vdecl = NULL;
7495 IDirect3DVertexBuffer9 *buffer = NULL;
7496 IDirect3DVertexShader9 *shader;
7497 DWORD shader_code[] = {
7498 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7499 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7500 0x90e40001, 0x0000ffff
7502 struct vertex_float16color quad[] = {
7503 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7504 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7505 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7506 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7508 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7509 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7510 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7511 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7513 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7514 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7515 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7516 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7518 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7519 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7520 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7521 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7525 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7527 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7528 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7529 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7530 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7531 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7532 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7534 hr = IDirect3DDevice9_BeginScene(device);
7535 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7536 if(SUCCEEDED(hr)) {
7537 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7538 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7540 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7542 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7544 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7546 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7548 hr = IDirect3DDevice9_EndScene(device);
7549 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7551 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7552 color = getPixelColor(device, 480, 360);
7553 ok(color == 0x00ff0000,
7554 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7555 color = getPixelColor(device, 160, 120);
7556 ok(color == 0x00000000,
7557 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7558 color = getPixelColor(device, 160, 360);
7559 ok(color == 0x0000ff00,
7560 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7561 color = getPixelColor(device, 480, 120);
7562 ok(color == 0x000000ff,
7563 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7566 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7568 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7569 D3DPOOL_MANAGED, &buffer, NULL);
7570 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7571 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7572 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7573 memcpy(data, quad, sizeof(quad));
7574 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7575 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7576 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7577 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7579 hr = IDirect3DDevice9_BeginScene(device);
7580 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7581 if(SUCCEEDED(hr)) {
7582 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7583 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7584 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7585 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7586 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7587 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7588 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7589 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7591 hr = IDirect3DDevice9_EndScene(device);
7592 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7595 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7596 color = getPixelColor(device, 480, 360);
7597 ok(color == 0x00ff0000,
7598 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7599 color = getPixelColor(device, 160, 120);
7600 ok(color == 0x00000000,
7601 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7602 color = getPixelColor(device, 160, 360);
7603 ok(color == 0x0000ff00,
7604 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7605 color = getPixelColor(device, 480, 120);
7606 ok(color == 0x000000ff,
7607 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7609 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7610 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7611 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7612 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7613 IDirect3DDevice9_SetVertexShader(device, NULL);
7614 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7616 IDirect3DVertexDeclaration9_Release(vdecl);
7617 IDirect3DVertexShader9_Release(shader);
7618 IDirect3DVertexBuffer9_Release(buffer);
7621 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7623 D3DCAPS9 caps;
7624 IDirect3DTexture9 *texture;
7625 HRESULT hr;
7626 D3DLOCKED_RECT rect;
7627 unsigned int x, y;
7628 DWORD *dst, color;
7629 const float quad[] = {
7630 -1.0, -1.0, 0.1, -0.2, -0.2,
7631 1.0, -1.0, 0.1, 1.2, -0.2,
7632 -1.0, 1.0, 0.1, -0.2, 1.2,
7633 1.0, 1.0, 0.1, 1.2, 1.2
7635 memset(&caps, 0, sizeof(caps));
7637 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7638 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7639 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7640 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7641 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7642 "Card has conditional NP2 support without power of two restriction set\n");
7643 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7644 return;
7645 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7646 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7647 return;
7650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7653 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7654 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7656 memset(&rect, 0, sizeof(rect));
7657 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7658 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7659 for(y = 0; y < 10; y++) {
7660 for(x = 0; x < 10; x++) {
7661 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7662 if(x == 0 || x == 9 || y == 0 || y == 9) {
7663 *dst = 0x00ff0000;
7664 } else {
7665 *dst = 0x000000ff;
7669 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7670 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7672 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7674 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7675 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7676 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7677 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7678 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7679 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7681 hr = IDirect3DDevice9_BeginScene(device);
7682 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7683 if(SUCCEEDED(hr)) {
7684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7685 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7687 hr = IDirect3DDevice9_EndScene(device);
7688 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7691 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7693 color = getPixelColor(device, 1, 1);
7694 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7695 color = getPixelColor(device, 639, 479);
7696 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7698 color = getPixelColor(device, 135, 101);
7699 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7700 color = getPixelColor(device, 140, 101);
7701 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7702 color = getPixelColor(device, 135, 105);
7703 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7704 color = getPixelColor(device, 140, 105);
7705 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7707 color = getPixelColor(device, 135, 376);
7708 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7709 color = getPixelColor(device, 140, 376);
7710 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7711 color = getPixelColor(device, 135, 379);
7712 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7713 color = getPixelColor(device, 140, 379);
7714 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7716 color = getPixelColor(device, 500, 101);
7717 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7718 color = getPixelColor(device, 504, 101);
7719 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7720 color = getPixelColor(device, 500, 105);
7721 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7722 color = getPixelColor(device, 504, 105);
7723 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7725 color = getPixelColor(device, 500, 376);
7726 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7727 color = getPixelColor(device, 504, 376);
7728 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7729 color = getPixelColor(device, 500, 380);
7730 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7731 color = getPixelColor(device, 504, 380);
7732 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7734 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7735 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7736 IDirect3DTexture9_Release(texture);
7739 static void vFace_register_test(IDirect3DDevice9 *device)
7741 HRESULT hr;
7742 DWORD color;
7743 const DWORD shader_code[] = {
7744 0xffff0300, /* ps_3_0 */
7745 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7746 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7747 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7748 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7749 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7750 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7751 0x0000ffff /* END */
7753 IDirect3DPixelShader9 *shader;
7754 IDirect3DTexture9 *texture;
7755 IDirect3DSurface9 *surface, *backbuffer;
7756 const float quad[] = {
7757 -1.0, -1.0, 0.1,
7758 1.0, -1.0, 0.1,
7759 -1.0, 0.0, 0.1,
7761 1.0, -1.0, 0.1,
7762 1.0, 0.0, 0.1,
7763 -1.0, 0.0, 0.1,
7765 -1.0, 0.0, 0.1,
7766 -1.0, 1.0, 0.1,
7767 1.0, 0.0, 0.1,
7769 1.0, 0.0, 0.1,
7770 -1.0, 1.0, 0.1,
7771 1.0, 1.0, 0.1,
7773 const float blit[] = {
7774 0.0, -1.0, 0.1, 0.0, 0.0,
7775 1.0, -1.0, 0.1, 1.0, 0.0,
7776 0.0, 1.0, 0.1, 0.0, 1.0,
7777 1.0, 1.0, 0.1, 1.0, 1.0,
7780 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7781 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7782 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7783 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7784 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7785 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7786 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7787 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7789 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7790 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7791 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7793 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7794 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7796 hr = IDirect3DDevice9_BeginScene(device);
7797 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7798 if(SUCCEEDED(hr)) {
7799 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7800 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7801 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7802 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7803 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7805 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7806 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7807 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7809 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7811 /* Blit the texture onto the back buffer to make it visible */
7812 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7813 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7814 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7815 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7816 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7817 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7818 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7819 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7820 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7821 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7824 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7826 hr = IDirect3DDevice9_EndScene(device);
7827 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7830 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7831 color = getPixelColor(device, 160, 360);
7832 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7833 color = getPixelColor(device, 160, 120);
7834 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7835 color = getPixelColor(device, 480, 360);
7836 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7837 color = getPixelColor(device, 480, 120);
7838 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7840 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7841 IDirect3DDevice9_SetTexture(device, 0, NULL);
7842 IDirect3DPixelShader9_Release(shader);
7843 IDirect3DSurface9_Release(surface);
7844 IDirect3DSurface9_Release(backbuffer);
7845 IDirect3DTexture9_Release(texture);
7848 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7850 HRESULT hr;
7851 DWORD color;
7852 int i;
7853 D3DCAPS9 caps;
7854 BOOL L6V5U5_supported = FALSE;
7855 IDirect3DTexture9 *tex1, *tex2;
7856 D3DLOCKED_RECT locked_rect;
7858 static const float quad[][7] = {
7859 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7860 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7861 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7862 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7865 static const D3DVERTEXELEMENT9 decl_elements[] = {
7866 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7867 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7868 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7869 D3DDECL_END()
7872 /* use asymmetric matrix to test loading */
7873 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7874 float scale, offset;
7876 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7877 IDirect3DTexture9 *texture = NULL;
7879 memset(&caps, 0, sizeof(caps));
7880 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7882 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7883 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7884 return;
7885 } else {
7886 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7887 * They report that it is not supported, but after that bump mapping works properly. So just test
7888 * if the format is generally supported, and check the BUMPENVMAP flag
7890 IDirect3D9 *d3d9;
7892 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7893 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7894 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7895 L6V5U5_supported = SUCCEEDED(hr);
7896 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7897 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7898 IDirect3D9_Release(d3d9);
7899 if(FAILED(hr)) {
7900 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7901 return;
7905 /* Generate the textures */
7906 generate_bumpmap_textures(device);
7908 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7909 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7910 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7911 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7912 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7913 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7914 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7915 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7917 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7918 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7919 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7920 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7922 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7924 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7925 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7927 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7928 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7929 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7931 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7932 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7934 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7935 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7938 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7941 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7942 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7943 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7944 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7946 hr = IDirect3DDevice9_BeginScene(device);
7947 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7949 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7950 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7952 hr = IDirect3DDevice9_EndScene(device);
7953 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7955 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7958 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7959 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7960 * But since testing the color match is not the purpose of the test don't be too picky
7962 color = getPixelColor(device, 320-32, 240);
7963 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7964 color = getPixelColor(device, 320+32, 240);
7965 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7966 color = getPixelColor(device, 320, 240-32);
7967 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7968 color = getPixelColor(device, 320, 240+32);
7969 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7970 color = getPixelColor(device, 320, 240);
7971 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7972 color = getPixelColor(device, 320+32, 240+32);
7973 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7974 color = getPixelColor(device, 320-32, 240+32);
7975 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7976 color = getPixelColor(device, 320+32, 240-32);
7977 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7978 color = getPixelColor(device, 320-32, 240-32);
7979 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7981 for(i = 0; i < 2; i++) {
7982 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7983 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7984 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7985 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7986 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7987 IDirect3DTexture9_Release(texture); /* To destroy it */
7990 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7991 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7992 goto cleanup;
7994 if(L6V5U5_supported == FALSE) {
7995 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7996 goto cleanup;
7999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8001 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8002 * would only make this test more complicated
8004 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8005 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8006 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8007 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8009 memset(&locked_rect, 0, sizeof(locked_rect));
8010 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8011 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8012 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8013 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8014 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8016 memset(&locked_rect, 0, sizeof(locked_rect));
8017 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8018 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8019 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8020 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8021 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8023 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8025 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8026 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8028 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8029 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8030 scale = 2.0;
8031 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8032 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8033 offset = 0.1;
8034 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8035 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8037 hr = IDirect3DDevice9_BeginScene(device);
8038 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8039 if(SUCCEEDED(hr)) {
8040 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8041 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8042 hr = IDirect3DDevice9_EndScene(device);
8043 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8046 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8047 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8048 color = getPixelColor(device, 320, 240);
8049 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8050 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8051 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8053 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8055 /* Check a result scale factor > 1.0 */
8056 scale = 10;
8057 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8058 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8059 offset = 10;
8060 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8061 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8063 hr = IDirect3DDevice9_BeginScene(device);
8064 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8065 if(SUCCEEDED(hr)) {
8066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8068 hr = IDirect3DDevice9_EndScene(device);
8069 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8072 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8073 color = getPixelColor(device, 320, 240);
8074 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8076 /* Check clamping in the scale factor calculation */
8077 scale = 1000;
8078 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8079 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8080 offset = -1;
8081 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8082 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8084 hr = IDirect3DDevice9_BeginScene(device);
8085 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8086 if(SUCCEEDED(hr)) {
8087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8088 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8089 hr = IDirect3DDevice9_EndScene(device);
8090 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8092 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8093 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8094 color = getPixelColor(device, 320, 240);
8095 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8097 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8098 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8099 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8100 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8102 IDirect3DTexture9_Release(tex1);
8103 IDirect3DTexture9_Release(tex2);
8105 cleanup:
8106 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8107 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8108 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8109 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8111 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8112 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8113 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8116 static void stencil_cull_test(IDirect3DDevice9 *device) {
8117 HRESULT hr;
8118 IDirect3DSurface9 *depthstencil = NULL;
8119 D3DSURFACE_DESC desc;
8120 float quad1[] = {
8121 -1.0, -1.0, 0.1,
8122 0.0, -1.0, 0.1,
8123 -1.0, 0.0, 0.1,
8124 0.0, 0.0, 0.1,
8126 float quad2[] = {
8127 0.0, -1.0, 0.1,
8128 1.0, -1.0, 0.1,
8129 0.0, 0.0, 0.1,
8130 1.0, 0.0, 0.1,
8132 float quad3[] = {
8133 0.0, 0.0, 0.1,
8134 1.0, 0.0, 0.1,
8135 0.0, 1.0, 0.1,
8136 1.0, 1.0, 0.1,
8138 float quad4[] = {
8139 -1.0, 0.0, 0.1,
8140 0.0, 0.0, 0.1,
8141 -1.0, 1.0, 0.1,
8142 0.0, 1.0, 0.1,
8144 struct vertex painter[] = {
8145 {-1.0, -1.0, 0.0, 0x00000000},
8146 { 1.0, -1.0, 0.0, 0x00000000},
8147 {-1.0, 1.0, 0.0, 0x00000000},
8148 { 1.0, 1.0, 0.0, 0x00000000},
8150 WORD indices_cw[] = {0, 1, 3};
8151 WORD indices_ccw[] = {0, 2, 3};
8152 unsigned int i;
8153 DWORD color;
8155 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8156 if(depthstencil == NULL) {
8157 skip("No depth stencil buffer\n");
8158 return;
8160 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8161 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8162 IDirect3DSurface9_Release(depthstencil);
8163 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8164 skip("No 4 or 8 bit stencil surface\n");
8165 return;
8168 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8169 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8170 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8173 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8175 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8177 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8179 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8182 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8183 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8184 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8186 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8189 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8190 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8191 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8193 /* First pass: Fill the stencil buffer with some values... */
8194 hr = IDirect3DDevice9_BeginScene(device);
8195 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8196 if(SUCCEEDED(hr))
8198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8199 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8200 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8201 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8202 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8203 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8209 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8210 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8211 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8212 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8215 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8216 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8217 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8218 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8219 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8222 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8223 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8224 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8225 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8226 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8228 hr = IDirect3DDevice9_EndScene(device);
8229 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8235 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8236 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8238 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8239 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8240 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8242 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8244 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8246 /* 2nd pass: Make the stencil values visible */
8247 hr = IDirect3DDevice9_BeginScene(device);
8248 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8249 if(SUCCEEDED(hr))
8251 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8252 for(i = 0; i < 16; i++) {
8253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8256 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8257 painter[1].diffuse = (i * 16);
8258 painter[2].diffuse = (i * 16);
8259 painter[3].diffuse = (i * 16);
8260 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8261 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8263 hr = IDirect3DDevice9_EndScene(device);
8264 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8267 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8268 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8273 color = getPixelColor(device, 160, 420);
8274 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8275 color = getPixelColor(device, 160, 300);
8276 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8278 color = getPixelColor(device, 480, 420);
8279 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8280 color = getPixelColor(device, 480, 300);
8281 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8283 color = getPixelColor(device, 160, 180);
8284 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8285 color = getPixelColor(device, 160, 60);
8286 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8288 color = getPixelColor(device, 480, 180);
8289 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8290 color = getPixelColor(device, 480, 60);
8291 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8294 static void vpos_register_test(IDirect3DDevice9 *device)
8296 HRESULT hr;
8297 DWORD color;
8298 const DWORD shader_code[] = {
8299 0xffff0300, /* ps_3_0 */
8300 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8301 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8302 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8303 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8304 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8305 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8306 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8307 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8308 0x0000ffff /* end */
8310 const DWORD shader_frac_code[] = {
8311 0xffff0300, /* ps_3_0 */
8312 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8313 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8314 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8315 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8316 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8317 0x0000ffff /* end */
8319 IDirect3DPixelShader9 *shader, *shader_frac;
8320 IDirect3DSurface9 *surface = NULL, *backbuffer;
8321 const float quad[] = {
8322 -1.0, -1.0, 0.1, 0.0, 0.0,
8323 1.0, -1.0, 0.1, 1.0, 0.0,
8324 -1.0, 1.0, 0.1, 0.0, 1.0,
8325 1.0, 1.0, 0.1, 1.0, 1.0,
8327 D3DLOCKED_RECT lr;
8328 float constant[4] = {1.0, 0.0, 320, 240};
8329 DWORD *pos;
8331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8332 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8333 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8334 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8335 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8336 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8337 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8338 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8339 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8340 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8341 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8342 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8344 hr = IDirect3DDevice9_BeginScene(device);
8345 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8346 if(SUCCEEDED(hr)) {
8347 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8348 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8349 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8350 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8351 hr = IDirect3DDevice9_EndScene(device);
8352 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8355 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8356 /* This has to be pixel exact */
8357 color = getPixelColor(device, 319, 239);
8358 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8359 color = getPixelColor(device, 320, 239);
8360 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8361 color = getPixelColor(device, 319, 240);
8362 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8363 color = getPixelColor(device, 320, 240);
8364 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8366 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8367 &surface, NULL);
8368 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8369 hr = IDirect3DDevice9_BeginScene(device);
8370 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8371 if(SUCCEEDED(hr)) {
8372 constant[2] = 16; constant[3] = 16;
8373 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8374 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8375 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8378 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8379 hr = IDirect3DDevice9_EndScene(device);
8380 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8382 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8383 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8385 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8386 color = *pos & 0x00ffffff;
8387 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8388 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8389 color = *pos & 0x00ffffff;
8390 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8391 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8392 color = *pos & 0x00ffffff;
8393 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8394 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8395 color = *pos & 0x00ffffff;
8396 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8398 hr = IDirect3DSurface9_UnlockRect(surface);
8399 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8401 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8402 * have full control over the multisampling setting inside this test
8404 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8405 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8406 hr = IDirect3DDevice9_BeginScene(device);
8407 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8408 if(SUCCEEDED(hr)) {
8409 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8410 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8412 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8413 hr = IDirect3DDevice9_EndScene(device);
8414 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8416 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8417 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8419 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8420 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8422 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8423 color = *pos & 0x00ffffff;
8424 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8426 hr = IDirect3DSurface9_UnlockRect(surface);
8427 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8429 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8430 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8431 IDirect3DPixelShader9_Release(shader);
8432 IDirect3DPixelShader9_Release(shader_frac);
8433 if(surface) IDirect3DSurface9_Release(surface);
8434 IDirect3DSurface9_Release(backbuffer);
8437 static void pointsize_test(IDirect3DDevice9 *device)
8439 HRESULT hr;
8440 D3DCAPS9 caps;
8441 D3DMATRIX matrix;
8442 D3DMATRIX identity;
8443 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8444 DWORD color;
8445 IDirect3DTexture9 *tex1, *tex2;
8446 D3DLOCKED_RECT lr;
8447 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8448 0x00000000, 0x00000000};
8449 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8450 0x00000000, 0x0000ff00};
8452 const float vertices[] = {
8453 64, 64, 0.1,
8454 128, 64, 0.1,
8455 192, 64, 0.1,
8456 256, 64, 0.1,
8457 320, 64, 0.1,
8458 384, 64, 0.1,
8459 448, 64, 0.1,
8460 512, 64, 0.1,
8461 576, 64, 0.1,
8464 /* 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 */
8465 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;
8466 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;
8467 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;
8468 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;
8470 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;
8471 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;
8472 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;
8473 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;
8475 memset(&caps, 0, sizeof(caps));
8476 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8477 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8478 if(caps.MaxPointSize < 32.0) {
8479 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8480 return;
8483 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8484 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8485 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8486 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8487 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8488 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8489 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8490 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8492 hr = IDirect3DDevice9_BeginScene(device);
8493 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8494 if(SUCCEEDED(hr)) {
8495 ptsize = 16.0;
8496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8497 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8499 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8501 ptsize = 32.0;
8502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8505 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8507 ptsize = 31.5;
8508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8509 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8511 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8513 if(caps.MaxPointSize >= 64.0) {
8514 ptsize = 64.0;
8515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8516 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8518 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8520 ptsize = 63.75;
8521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8522 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8524 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8527 ptsize = 1.0;
8528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8531 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8533 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8534 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8535 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8536 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8538 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8539 ptsize = 16.0;
8540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8542 ptsize = 1.0;
8543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8544 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8548 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8549 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8551 ptsize = 4.0;
8552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8553 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8554 ptsize = 16.0;
8555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8556 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8558 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8561 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8563 /* pointsize < pointsize_min < pointsize_max?
8564 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8566 ptsize = 1.0;
8567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8568 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8569 ptsize = 16.0;
8570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8578 hr = IDirect3DDevice9_EndScene(device);
8579 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8581 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8582 color = getPixelColor(device, 64-9, 64-9);
8583 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8584 color = getPixelColor(device, 64-8, 64-8);
8585 ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8586 color = getPixelColor(device, 64-7, 64-7);
8587 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8588 color = getPixelColor(device, 64+7, 64+7);
8589 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8590 color = getPixelColor(device, 64+8, 64+8);
8591 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8592 color = getPixelColor(device, 64+9, 64+9);
8593 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8595 color = getPixelColor(device, 128-17, 64-17);
8596 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8597 color = getPixelColor(device, 128-16, 64-16);
8598 ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8599 color = getPixelColor(device, 128-15, 64-15);
8600 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8601 color = getPixelColor(device, 128+15, 64+15);
8602 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8603 color = getPixelColor(device, 128+16, 64+16);
8604 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8605 color = getPixelColor(device, 128+17, 64+17);
8606 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8608 color = getPixelColor(device, 192-17, 64-17);
8609 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8610 color = getPixelColor(device, 192-16, 64-16);
8611 todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8612 color = getPixelColor(device, 192-15, 64-15);
8613 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8614 color = getPixelColor(device, 192+15, 64+15);
8615 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8616 color = getPixelColor(device, 192+16, 64+16);
8617 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8618 color = getPixelColor(device, 192+17, 64+17);
8619 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8621 if(caps.MaxPointSize >= 64.0) {
8622 color = getPixelColor(device, 256-33, 64-33);
8623 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8624 color = getPixelColor(device, 256-32, 64-32);
8625 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8626 color = getPixelColor(device, 256-31, 64-31);
8627 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8628 color = getPixelColor(device, 256+31, 64+31);
8629 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8630 color = getPixelColor(device, 256+32, 64+32);
8631 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8632 color = getPixelColor(device, 256+33, 64+33);
8633 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8635 color = getPixelColor(device, 384-33, 64-33);
8636 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8637 color = getPixelColor(device, 384-32, 64-32);
8638 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8639 color = getPixelColor(device, 384-31, 64-31);
8640 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8641 color = getPixelColor(device, 384+31, 64+31);
8642 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8643 color = getPixelColor(device, 384+32, 64+32);
8644 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8645 color = getPixelColor(device, 384+33, 64+33);
8646 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8649 color = getPixelColor(device, 320-1, 64-1);
8650 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8651 color = getPixelColor(device, 320-0, 64-0);
8652 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8653 color = getPixelColor(device, 320+1, 64+1);
8654 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8656 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8657 color = getPixelColor(device, 448-4, 64-4);
8658 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8659 color = getPixelColor(device, 448+4, 64+4);
8660 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8662 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8663 color = getPixelColor(device, 512-4, 64-4);
8664 ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8665 color = getPixelColor(device, 512+4, 64+4);
8666 ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8668 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8669 * Don't be overly picky - just show that the point is bigger than 1 pixel
8671 color = getPixelColor(device, 576-4, 64-4);
8672 ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8673 color = getPixelColor(device, 576+4, 64+4);
8674 ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8676 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8677 * generates texture coordinates for the point(result: Yes, it does)
8679 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8680 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8681 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8684 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8686 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8687 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8688 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8689 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8690 memset(&lr, 0, sizeof(lr));
8691 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8692 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8693 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8694 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8695 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8696 memset(&lr, 0, sizeof(lr));
8697 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8698 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8699 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8700 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8701 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8702 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8703 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8704 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8705 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8706 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8707 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8708 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8709 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8710 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8711 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8712 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8714 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8715 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8718 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8719 ptsize = 32.0;
8720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8721 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8723 hr = IDirect3DDevice9_BeginScene(device);
8724 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8725 if(SUCCEEDED(hr))
8727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8728 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8729 hr = IDirect3DDevice9_EndScene(device);
8730 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8733 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8734 color = getPixelColor(device, 64-4, 64-4);
8735 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8736 color = getPixelColor(device, 64-4, 64+4);
8737 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8738 color = getPixelColor(device, 64+4, 64+4);
8739 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8740 color = getPixelColor(device, 64+4, 64-4);
8741 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8743 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8744 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8745 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8746 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8747 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8748 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8749 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8750 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8751 IDirect3DTexture9_Release(tex1);
8752 IDirect3DTexture9_Release(tex2);
8754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8755 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8757 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8758 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8759 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8762 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8764 HRESULT hr;
8765 IDirect3DPixelShader9 *ps;
8766 IDirect3DTexture9 *tex1, *tex2;
8767 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8768 D3DCAPS9 caps;
8769 DWORD color;
8770 DWORD shader_code[] = {
8771 0xffff0300, /* ps_3_0 */
8772 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8773 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8774 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8775 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8776 0x0000ffff /* END */
8778 float quad[] = {
8779 -1.0, -1.0, 0.1,
8780 1.0, -1.0, 0.1,
8781 -1.0, 1.0, 0.1,
8782 1.0, 1.0, 0.1,
8784 float texquad[] = {
8785 -1.0, -1.0, 0.1, 0.0, 0.0,
8786 0.0, -1.0, 0.1, 1.0, 0.0,
8787 -1.0, 1.0, 0.1, 0.0, 1.0,
8788 0.0, 1.0, 0.1, 1.0, 1.0,
8790 0.0, -1.0, 0.1, 0.0, 0.0,
8791 1.0, -1.0, 0.1, 1.0, 0.0,
8792 0.0, 1.0, 0.1, 0.0, 1.0,
8793 1.0, 1.0, 0.1, 1.0, 1.0,
8796 memset(&caps, 0, sizeof(caps));
8797 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8798 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8799 if(caps.NumSimultaneousRTs < 2) {
8800 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8801 return;
8804 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8805 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8807 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8808 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8809 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8810 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8811 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8812 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8814 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8816 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8817 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8818 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8819 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8821 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8822 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8823 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8825 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8826 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8827 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8828 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8830 hr = IDirect3DDevice9_BeginScene(device);
8831 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8832 if(SUCCEEDED(hr)) {
8833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8834 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8836 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8837 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8838 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8840 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8841 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8842 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8843 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8845 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8846 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8848 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8850 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8851 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8853 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8855 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8856 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8858 hr = IDirect3DDevice9_EndScene(device);
8859 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8862 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8863 color = getPixelColor(device, 160, 240);
8864 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8865 color = getPixelColor(device, 480, 240);
8866 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8868 IDirect3DPixelShader9_Release(ps);
8869 IDirect3DTexture9_Release(tex1);
8870 IDirect3DTexture9_Release(tex2);
8871 IDirect3DSurface9_Release(surf1);
8872 IDirect3DSurface9_Release(surf2);
8873 IDirect3DSurface9_Release(backbuf);
8876 struct formats {
8877 const char *fmtName;
8878 D3DFORMAT textureFormat;
8879 DWORD resultColorBlending;
8880 DWORD resultColorNoBlending;
8883 const struct formats test_formats[] = {
8884 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8885 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8886 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8887 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8888 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8889 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8890 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8891 { NULL, 0 }
8894 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8896 HRESULT hr;
8897 IDirect3DTexture9 *offscreenTexture = NULL;
8898 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8899 IDirect3D9 *d3d = NULL;
8900 DWORD color;
8901 DWORD r0, g0, b0, r1, g1, b1;
8902 int fmt_index;
8904 static const float quad[][5] = {
8905 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8906 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8907 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8908 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8911 /* Quad with R=0x10, G=0x20 */
8912 static const struct vertex quad1[] = {
8913 {-1.0f, -1.0f, 0.1f, 0x80102000},
8914 {-1.0f, 1.0f, 0.1f, 0x80102000},
8915 { 1.0f, -1.0f, 0.1f, 0x80102000},
8916 { 1.0f, 1.0f, 0.1f, 0x80102000},
8919 /* Quad with R=0x20, G=0x10 */
8920 static const struct vertex quad2[] = {
8921 {-1.0f, -1.0f, 0.1f, 0x80201000},
8922 {-1.0f, 1.0f, 0.1f, 0x80201000},
8923 { 1.0f, -1.0f, 0.1f, 0x80201000},
8924 { 1.0f, 1.0f, 0.1f, 0x80201000},
8927 IDirect3DDevice9_GetDirect3D(device, &d3d);
8929 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8930 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8931 if(!backbuffer) {
8932 goto out;
8935 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8937 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8938 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8939 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8940 continue;
8943 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8944 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8946 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8947 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8948 if(!offscreenTexture) {
8949 continue;
8952 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8953 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8954 if(!offscreen) {
8955 continue;
8958 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8959 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8961 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8962 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8963 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8964 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8965 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8966 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8967 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8968 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8970 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8972 /* Below we will draw two quads with different colors and try to blend them together.
8973 * The result color is compared with the expected outcome.
8975 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8976 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8977 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8979 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8982 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8984 /* Draw a quad using color 0x0010200 */
8985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8986 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8988 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8990 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8992 /* Draw a quad using color 0x0020100 */
8993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8994 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8998 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9000 /* We don't want to blend the result on the backbuffer */
9001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9002 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9004 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9005 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9006 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9007 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9008 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9010 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9011 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9013 /* This time with the texture */
9014 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9015 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9017 IDirect3DDevice9_EndScene(device);
9019 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9022 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9023 /* Compare the color of the center quad with our expectation */
9024 color = getPixelColor(device, 320, 240);
9025 r0 = (color & 0x00ff0000) >> 16;
9026 g0 = (color & 0x0000ff00) >> 8;
9027 b0 = (color & 0x000000ff) >> 0;
9029 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9030 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9031 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9033 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9034 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9035 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9036 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9037 } else {
9038 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9039 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9040 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9041 color = getPixelColor(device, 320, 240);
9042 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);
9045 IDirect3DDevice9_SetTexture(device, 0, NULL);
9046 if(offscreenTexture) {
9047 IDirect3DTexture9_Release(offscreenTexture);
9049 if(offscreen) {
9050 IDirect3DSurface9_Release(offscreen);
9054 out:
9055 /* restore things */
9056 if(backbuffer) {
9057 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9058 IDirect3DSurface9_Release(backbuffer);
9062 static void tssargtemp_test(IDirect3DDevice9 *device)
9064 HRESULT hr;
9065 DWORD color;
9066 static const struct vertex quad[] = {
9067 {-1.0, -1.0, 0.1, 0x00ff0000},
9068 { 1.0, -1.0, 0.1, 0x00ff0000},
9069 {-1.0, 1.0, 0.1, 0x00ff0000},
9070 { 1.0, 1.0, 0.1, 0x00ff0000}
9072 D3DCAPS9 caps;
9074 memset(&caps, 0, sizeof(caps));
9075 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9076 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9077 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9078 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9079 return;
9082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9083 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9085 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9086 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9087 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9088 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9090 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9091 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9092 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9093 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9094 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9095 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9097 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9098 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9099 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9100 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9101 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9102 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9104 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9105 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9108 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9109 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9110 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9112 hr = IDirect3DDevice9_BeginScene(device);
9113 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9114 if(SUCCEEDED(hr)) {
9116 hr = IDirect3DDevice9_EndScene(device);
9117 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9119 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9121 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9122 color = getPixelColor(device, 320, 240);
9123 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9125 /* Set stage 1 back to default */
9126 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9127 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9128 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9129 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9130 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9131 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9132 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9133 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9134 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9135 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9138 struct testdata
9140 DWORD idxVertex; /* number of instances in the first stream */
9141 DWORD idxColor; /* number of instances in the second stream */
9142 DWORD idxInstance; /* should be 1 ?? */
9143 DWORD color1; /* color 1 instance */
9144 DWORD color2; /* color 2 instance */
9145 DWORD color3; /* color 3 instance */
9146 DWORD color4; /* color 4 instance */
9147 WORD strVertex; /* specify which stream to use 0-2*/
9148 WORD strColor;
9149 WORD strInstance;
9152 static const struct testdata testcases[]=
9154 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9155 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9156 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9157 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9158 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9159 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9160 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9161 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9162 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9163 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9164 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9165 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9166 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9167 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9168 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9170 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9171 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9175 /* Drawing Indexed Geometry with instances*/
9176 static void stream_test(IDirect3DDevice9 *device)
9178 IDirect3DVertexBuffer9 *vb = NULL;
9179 IDirect3DVertexBuffer9 *vb2 = NULL;
9180 IDirect3DVertexBuffer9 *vb3 = NULL;
9181 IDirect3DIndexBuffer9 *ib = NULL;
9182 IDirect3DVertexDeclaration9 *pDecl = NULL;
9183 IDirect3DVertexShader9 *shader = NULL;
9184 HRESULT hr;
9185 BYTE *data;
9186 DWORD color;
9187 DWORD ind;
9188 unsigned i;
9190 const DWORD shader_code[] =
9192 0xfffe0101, /* vs_1_1 */
9193 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9194 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9195 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9196 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9197 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9198 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9199 0x0000ffff
9202 const float quad[][3] =
9204 {-0.5f, -0.5f, 1.1f}, /*0 */
9205 {-0.5f, 0.5f, 1.1f}, /*1 */
9206 { 0.5f, -0.5f, 1.1f}, /*2 */
9207 { 0.5f, 0.5f, 1.1f}, /*3 */
9210 const float vertcolor[][4] =
9212 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9213 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9214 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9215 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9218 /* 4 position for 4 instances */
9219 const float instancepos[][3] =
9221 {-0.6f,-0.6f, 0.0f},
9222 { 0.6f,-0.6f, 0.0f},
9223 { 0.6f, 0.6f, 0.0f},
9224 {-0.6f, 0.6f, 0.0f},
9227 short indices[] = {0, 1, 2, 1, 2, 3};
9229 D3DVERTEXELEMENT9 decl[] =
9231 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9232 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9233 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9234 D3DDECL_END()
9237 /* set the default value because it isn't done in wine? */
9238 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9239 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9241 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9242 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9243 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9245 /* check wrong cases */
9246 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9247 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9248 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9249 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9250 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9251 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9252 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9253 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9254 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9255 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9256 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9257 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9258 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9259 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9260 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9261 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9262 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9263 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9264 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9265 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9267 /* set the default value back */
9268 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9269 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9271 /* create all VertexBuffers*/
9272 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9273 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9274 if(!vb) {
9275 skip("Failed to create a vertex buffer\n");
9276 return;
9278 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9279 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9280 if(!vb2) {
9281 skip("Failed to create a vertex buffer\n");
9282 goto out;
9284 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9285 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9286 if(!vb3) {
9287 skip("Failed to create a vertex buffer\n");
9288 goto out;
9291 /* create IndexBuffer*/
9292 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9293 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9294 if(!ib) {
9295 skip("Failed to create a index buffer\n");
9296 goto out;
9299 /* copy all Buffers (Vertex + Index)*/
9300 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9301 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9302 memcpy(data, quad, sizeof(quad));
9303 hr = IDirect3DVertexBuffer9_Unlock(vb);
9304 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9305 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9306 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9307 memcpy(data, vertcolor, sizeof(vertcolor));
9308 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9309 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9310 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9311 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9312 memcpy(data, instancepos, sizeof(instancepos));
9313 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9314 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9315 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9316 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9317 memcpy(data, indices, sizeof(indices));
9318 hr = IDirect3DIndexBuffer9_Unlock(ib);
9319 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9321 /* create VertexShader */
9322 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9323 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9324 if(!shader) {
9325 skip("Failed to create a vetex shader\n");
9326 goto out;
9329 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9330 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9332 hr = IDirect3DDevice9_SetIndices(device, ib);
9333 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9335 /* run all tests */
9336 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9338 struct testdata act = testcases[i];
9339 decl[0].Stream = act.strVertex;
9340 decl[1].Stream = act.strColor;
9341 decl[2].Stream = act.strInstance;
9342 /* create VertexDeclarations */
9343 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9344 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9346 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9347 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9349 hr = IDirect3DDevice9_BeginScene(device);
9350 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9351 if(SUCCEEDED(hr))
9353 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9354 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9356 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9357 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9358 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9359 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9361 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9362 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9363 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9364 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9366 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9367 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9368 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9369 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9371 /* don't know if this is right (1*3 and 4*1)*/
9372 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9373 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9374 hr = IDirect3DDevice9_EndScene(device);
9375 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9377 /* set all StreamSource && StreamSourceFreq back to default */
9378 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9379 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9380 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9381 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9382 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9383 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9384 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9385 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9386 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9387 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9388 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9389 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9393 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9395 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9396 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9398 color = getPixelColor(device, 160, 360);
9399 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9400 color = getPixelColor(device, 480, 360);
9401 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9402 color = getPixelColor(device, 480, 120);
9403 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9404 color = getPixelColor(device, 160, 120);
9405 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9408 hr = IDirect3DDevice9_SetIndices(device, NULL);
9409 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9411 out:
9412 if(vb) IDirect3DVertexBuffer9_Release(vb);
9413 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9414 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9415 if(ib)IDirect3DIndexBuffer9_Release(ib);
9416 if(shader)IDirect3DVertexShader9_Release(shader);
9419 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9420 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9421 IDirect3DTexture9 *dsttex = NULL;
9422 HRESULT hr;
9423 DWORD color;
9424 D3DRECT r1 = {0, 0, 50, 50 };
9425 D3DRECT r2 = {50, 0, 100, 50 };
9426 D3DRECT r3 = {50, 50, 100, 100};
9427 D3DRECT r4 = {0, 50, 50, 100};
9428 const float quad[] = {
9429 -1.0, -1.0, 0.1, 0.0, 0.0,
9430 1.0, -1.0, 0.1, 1.0, 0.0,
9431 -1.0, 1.0, 0.1, 0.0, 1.0,
9432 1.0, 1.0, 0.1, 1.0, 1.0,
9435 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9436 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9438 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9439 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9440 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9441 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9443 if(!src || !dsttex) {
9444 skip("One or more test resources could not be created\n");
9445 goto cleanup;
9448 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9449 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9451 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9452 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9454 /* Clear the StretchRect destination for debugging */
9455 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9456 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9457 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9458 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9460 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9461 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9463 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9465 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9466 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9467 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9468 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9469 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9470 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9472 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9473 * the target -> texture GL blit path
9475 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9476 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9477 IDirect3DSurface9_Release(dst);
9479 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9482 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9483 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9484 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9485 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9486 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9487 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9488 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9489 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9491 hr = IDirect3DDevice9_BeginScene(device);
9492 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9493 if(SUCCEEDED(hr)) {
9494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9495 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9496 hr = IDirect3DDevice9_EndScene(device);
9497 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9500 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9501 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9502 color = getPixelColor(device, 160, 360);
9503 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9504 color = getPixelColor(device, 480, 360);
9505 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9506 color = getPixelColor(device, 480, 120);
9507 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9508 color = getPixelColor(device, 160, 120);
9509 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9511 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9512 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9513 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9514 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9516 cleanup:
9517 if(src) IDirect3DSurface9_Release(src);
9518 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9519 if(dsttex) IDirect3DTexture9_Release(dsttex);
9522 static void texop_test(IDirect3DDevice9 *device)
9524 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9525 IDirect3DTexture9 *texture = NULL;
9526 D3DLOCKED_RECT locked_rect;
9527 D3DCOLOR color;
9528 D3DCAPS9 caps;
9529 HRESULT hr;
9530 unsigned i;
9532 static const struct {
9533 float x, y, z;
9534 float s, t;
9535 D3DCOLOR diffuse;
9536 } quad[] = {
9537 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9538 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9539 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9540 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9543 static const D3DVERTEXELEMENT9 decl_elements[] = {
9544 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9545 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9546 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9547 D3DDECL_END()
9550 static const struct {
9551 D3DTEXTUREOP op;
9552 const char *name;
9553 DWORD caps_flag;
9554 D3DCOLOR result;
9555 } test_data[] = {
9556 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9557 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9558 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9559 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9560 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9561 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9562 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9563 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9564 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9565 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9566 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9567 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9568 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9569 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9570 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9571 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9572 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9573 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9574 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9575 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9576 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9577 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9578 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9581 memset(&caps, 0, sizeof(caps));
9582 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9583 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9585 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9586 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9587 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9588 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9590 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9591 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9592 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9593 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9594 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9595 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9596 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9597 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9598 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9600 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9601 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9602 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9603 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9604 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9605 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9607 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9608 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9611 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9613 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9615 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9618 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9620 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9622 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9624 skip("tex operation %s not supported\n", test_data[i].name);
9625 continue;
9628 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9629 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9631 hr = IDirect3DDevice9_BeginScene(device);
9632 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9635 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9637 hr = IDirect3DDevice9_EndScene(device);
9638 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9640 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9641 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9643 color = getPixelColor(device, 320, 240);
9644 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9645 test_data[i].name, color, test_data[i].result);
9648 if (texture) IDirect3DTexture9_Release(texture);
9649 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9652 static void yuv_color_test(IDirect3DDevice9 *device) {
9653 HRESULT hr;
9654 IDirect3DSurface9 *surface = NULL, *target = NULL;
9655 unsigned int fmt, i;
9656 D3DFORMAT format;
9657 const char *fmt_string;
9658 D3DLOCKED_RECT lr;
9659 IDirect3D9 *d3d;
9660 HRESULT color;
9661 DWORD ref_color_left, ref_color_right;
9663 struct {
9664 DWORD in; /* The input color */
9665 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9666 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9667 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9668 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9669 } test_data[] = {
9670 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9671 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9672 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9673 * that
9675 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9676 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9677 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9678 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9679 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9680 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9681 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9682 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9683 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9684 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9685 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9686 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9687 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9688 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9690 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9691 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9692 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9693 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9696 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9697 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9698 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9701 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9702 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9704 for(fmt = 0; fmt < 2; fmt++) {
9705 if(fmt == 0) {
9706 format = D3DFMT_UYVY;
9707 fmt_string = "D3DFMT_UYVY";
9708 } else {
9709 format = D3DFMT_YUY2;
9710 fmt_string = "D3DFMT_YUY2";
9713 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9714 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9716 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9717 D3DRTYPE_SURFACE, format) != D3D_OK) {
9718 skip("%s is not supported\n", fmt_string);
9719 continue;
9722 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9723 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9724 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9726 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9727 if(fmt == 0) {
9728 ref_color_left = test_data[i].uyvy_left;
9729 ref_color_right = test_data[i].uyvy_right;
9730 } else {
9731 ref_color_left = test_data[i].yuy2_left;
9732 ref_color_right = test_data[i].yuy2_right;
9735 memset(&lr, 0, sizeof(lr));
9736 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9737 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9738 *((DWORD *) lr.pBits) = test_data[i].in;
9739 hr = IDirect3DSurface9_UnlockRect(surface);
9740 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9742 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9743 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9744 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9745 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9746 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9747 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9749 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9750 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9751 * want to add tests for the filtered pixels as well.
9753 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9754 * differently, so we need a max diff of 16
9756 color = getPixelColor(device, 40, 240);
9757 ok(color_match(color, ref_color_left, 16),
9758 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9759 test_data[i].in, color, ref_color_left, fmt_string);
9760 color = getPixelColor(device, 600, 240);
9761 ok(color_match(color, ref_color_right, 16),
9762 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9763 test_data[i].in, color, ref_color_right, fmt_string);
9765 IDirect3DSurface9_Release(surface);
9767 IDirect3DSurface9_Release(target);
9768 IDirect3D9_Release(d3d);
9771 static void texop_range_test(IDirect3DDevice9 *device)
9773 static const struct {
9774 float x, y, z;
9775 D3DCOLOR diffuse;
9776 } quad[] = {
9777 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9778 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9779 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9780 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9782 HRESULT hr;
9783 IDirect3DTexture9 *texture;
9784 D3DLOCKED_RECT locked_rect;
9785 D3DCAPS9 caps;
9786 DWORD color;
9788 /* We need ADD and SUBTRACT operations */
9789 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9790 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9791 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9792 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9793 return;
9795 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9796 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9797 return;
9800 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9801 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9802 /* Stage 1: result = diffuse(=1.0) + diffuse
9803 * stage 2: result = result - tfactor(= 0.5)
9805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9806 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9808 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9809 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9810 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9811 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9812 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9814 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9815 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9816 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9817 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9818 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9820 hr = IDirect3DDevice9_BeginScene(device);
9821 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9823 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9824 hr = IDirect3DDevice9_EndScene(device);
9825 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9827 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9829 color = getPixelColor(device, 320, 240);
9830 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9831 color);
9833 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9834 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9835 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9836 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9837 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9838 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9839 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9840 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9841 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9843 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9844 * stage 2: result = result + diffuse(1.0)
9846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9847 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9848 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9849 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9850 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9851 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9852 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9853 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9854 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9855 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9856 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9857 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9858 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9859 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9861 hr = IDirect3DDevice9_BeginScene(device);
9862 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9864 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9865 hr = IDirect3DDevice9_EndScene(device);
9866 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9867 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9868 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9870 color = getPixelColor(device, 320, 240);
9871 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9872 color);
9874 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9875 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9876 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9877 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9878 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9879 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9880 IDirect3DTexture9_Release(texture);
9883 static void alphareplicate_test(IDirect3DDevice9 *device) {
9884 struct vertex quad[] = {
9885 { -1.0, -1.0, 0.1, 0x80ff00ff },
9886 { 1.0, -1.0, 0.1, 0x80ff00ff },
9887 { -1.0, 1.0, 0.1, 0x80ff00ff },
9888 { 1.0, 1.0, 0.1, 0x80ff00ff },
9890 HRESULT hr;
9891 DWORD color;
9893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9896 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9897 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9899 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9900 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9901 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9902 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904 hr = IDirect3DDevice9_BeginScene(device);
9905 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9906 if(SUCCEEDED(hr)) {
9907 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9908 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9909 hr = IDirect3DDevice9_EndScene(device);
9910 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9913 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9914 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9916 color = getPixelColor(device, 320, 240);
9917 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9918 color);
9920 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9921 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9925 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9926 HRESULT hr;
9927 D3DCAPS9 caps;
9928 DWORD color;
9929 struct vertex quad[] = {
9930 { -1.0, -1.0, 0.1, 0x408080c0 },
9931 { 1.0, -1.0, 0.1, 0x408080c0 },
9932 { -1.0, 1.0, 0.1, 0x408080c0 },
9933 { 1.0, 1.0, 0.1, 0x408080c0 },
9936 memset(&caps, 0, sizeof(caps));
9937 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9938 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9939 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9940 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9941 return;
9944 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9945 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9948 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9950 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9951 * mov r0.a, diffuse.a
9952 * mov r0, r0.a
9954 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9955 * 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
9956 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9958 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9959 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9960 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9961 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9962 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9963 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9964 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9965 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9966 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9967 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9968 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9969 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9970 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9971 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9972 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9973 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9974 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9975 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9977 hr = IDirect3DDevice9_BeginScene(device);
9978 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9979 if(SUCCEEDED(hr)) {
9980 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9981 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9982 hr = IDirect3DDevice9_EndScene(device);
9983 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9987 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9989 color = getPixelColor(device, 320, 240);
9990 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9991 color);
9993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9994 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9996 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9997 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9998 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10001 static void zwriteenable_test(IDirect3DDevice9 *device) {
10002 HRESULT hr;
10003 DWORD color;
10004 struct vertex quad1[] = {
10005 { -1.0, -1.0, 0.1, 0x00ff0000},
10006 { -1.0, 1.0, 0.1, 0x00ff0000},
10007 { 1.0, -1.0, 0.1, 0x00ff0000},
10008 { 1.0, 1.0, 0.1, 0x00ff0000},
10010 struct vertex quad2[] = {
10011 { -1.0, -1.0, 0.9, 0x0000ff00},
10012 { -1.0, 1.0, 0.9, 0x0000ff00},
10013 { 1.0, -1.0, 0.9, 0x0000ff00},
10014 { 1.0, 1.0, 0.9, 0x0000ff00},
10017 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10018 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10020 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10021 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10023 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10025 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10027 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10029 hr = IDirect3DDevice9_BeginScene(device);
10030 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10031 if(SUCCEEDED(hr)) {
10032 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10033 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10034 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10035 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10036 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10037 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10040 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10042 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10043 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10044 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10046 hr = IDirect3DDevice9_EndScene(device);
10047 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10050 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10051 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10052 color = getPixelColor(device, 320, 240);
10053 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10054 color);
10056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10057 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10060 static void alphatest_test(IDirect3DDevice9 *device) {
10061 #define ALPHATEST_PASSED 0x0000ff00
10062 #define ALPHATEST_FAILED 0x00ff0000
10063 struct {
10064 D3DCMPFUNC func;
10065 DWORD color_less;
10066 DWORD color_equal;
10067 DWORD color_greater;
10068 } testdata[] = {
10069 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10070 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10071 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10072 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10073 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10074 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10075 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10076 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10078 unsigned int i, j;
10079 HRESULT hr;
10080 DWORD color;
10081 struct vertex quad[] = {
10082 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10083 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10084 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10085 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10087 D3DCAPS9 caps;
10089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10090 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10092 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10094 for(j = 0; j < 2; j++) {
10095 if(j == 1) {
10096 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10097 * the alpha test either for performance reasons(floating point RTs) or to work
10098 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10099 * codepath for ffp and shader in this case, and the test should cover both
10101 IDirect3DPixelShader9 *ps;
10102 DWORD shader_code[] = {
10103 0xffff0101, /* ps_1_1 */
10104 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10105 0x0000ffff /* end */
10107 memset(&caps, 0, sizeof(caps));
10108 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10109 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10110 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10111 break;
10114 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10115 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10116 IDirect3DDevice9_SetPixelShader(device, ps);
10117 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10118 IDirect3DPixelShader9_Release(ps);
10121 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10123 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10126 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10128 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10129 hr = IDirect3DDevice9_BeginScene(device);
10130 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10131 if(SUCCEEDED(hr)) {
10132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10134 hr = IDirect3DDevice9_EndScene(device);
10135 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10138 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10139 color = getPixelColor(device, 320, 240);
10140 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10141 color, testdata[i].color_less, testdata[i].func);
10143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10144 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10147 hr = IDirect3DDevice9_BeginScene(device);
10148 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10149 if(SUCCEEDED(hr)) {
10150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10151 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10152 hr = IDirect3DDevice9_EndScene(device);
10153 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10156 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10157 color = getPixelColor(device, 320, 240);
10158 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10159 color, testdata[i].color_equal, testdata[i].func);
10161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10162 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10164 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10165 hr = IDirect3DDevice9_BeginScene(device);
10166 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10167 if(SUCCEEDED(hr)) {
10168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10169 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10170 hr = IDirect3DDevice9_EndScene(device);
10171 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10174 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10175 color = getPixelColor(device, 320, 240);
10176 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10177 color, testdata[i].color_greater, testdata[i].func);
10181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10182 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10183 IDirect3DDevice9_SetPixelShader(device, NULL);
10184 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10187 static void sincos_test(IDirect3DDevice9 *device) {
10188 const DWORD sin_shader_code[] = {
10189 0xfffe0200, /* vs_2_0 */
10190 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10191 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10192 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10193 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10194 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10195 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10196 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10197 0x0000ffff /* end */
10199 const DWORD cos_shader_code[] = {
10200 0xfffe0200, /* vs_2_0 */
10201 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10202 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10203 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10204 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10205 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10206 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10207 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10208 0x0000ffff /* end */
10210 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10211 HRESULT hr;
10212 struct {
10213 float x, y, z;
10214 } data[1280];
10215 unsigned int i;
10216 float sincosc1[4] = {D3DSINCOSCONST1};
10217 float sincosc2[4] = {D3DSINCOSCONST2};
10219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10222 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10223 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10224 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10225 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10226 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10227 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10228 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10230 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10233 /* Generate a point from -1 to 1 every 0.5 pixels */
10234 for(i = 0; i < 1280; i++) {
10235 data[i].x = (-640.0 + i) / 640.0;
10236 data[i].y = 0.0;
10237 data[i].z = 0.1;
10240 hr = IDirect3DDevice9_BeginScene(device);
10241 if(SUCCEEDED(hr)) {
10242 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10243 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10245 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10247 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10248 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10250 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10252 hr = IDirect3DDevice9_EndScene(device);
10253 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10255 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10256 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10258 IDirect3DDevice9_SetVertexShader(device, NULL);
10259 IDirect3DVertexShader9_Release(sin_shader);
10260 IDirect3DVertexShader9_Release(cos_shader);
10263 static void loop_index_test(IDirect3DDevice9 *device) {
10264 const DWORD shader_code[] = {
10265 0xfffe0200, /* vs_2_0 */
10266 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10267 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10268 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10269 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10270 0x0000001d, /* endloop */
10271 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10272 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10273 0x0000ffff /* END */
10275 IDirect3DVertexShader9 *shader;
10276 HRESULT hr;
10277 DWORD color;
10278 const float quad[] = {
10279 -1.0, -1.0, 0.1,
10280 1.0, -1.0, 0.1,
10281 -1.0, 1.0, 0.1,
10282 1.0, 1.0, 0.1
10284 const float zero[4] = {0, 0, 0, 0};
10285 const float one[4] = {1, 1, 1, 1};
10286 int i0[4] = {2, 10, -3, 0};
10287 float values[4];
10289 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10290 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10291 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10292 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10293 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10294 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10295 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10296 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10298 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10299 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10300 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10301 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10302 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10303 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10304 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10305 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10306 values[0] = 1.0;
10307 values[1] = 1.0;
10308 values[2] = 0.0;
10309 values[3] = 0.0;
10310 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10311 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10312 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10313 values[0] = -1.0;
10314 values[1] = 0.0;
10315 values[2] = 0.0;
10316 values[3] = 0.0;
10317 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10318 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10319 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10320 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10321 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10323 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10325 hr = IDirect3DDevice9_BeginScene(device);
10326 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10327 if(SUCCEEDED(hr))
10329 trace("going to draw index\n");
10330 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10331 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10332 hr = IDirect3DDevice9_EndScene(device);
10333 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10336 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10338 color = getPixelColor(device, 320, 240);
10339 ok(color_match(color, 0x0000ff00, 1),
10340 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10342 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10343 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10344 IDirect3DVertexShader9_Release(shader);
10347 static void sgn_test(IDirect3DDevice9 *device) {
10348 const DWORD shader_code[] = {
10349 0xfffe0200, /* vs_2_0 */
10350 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10351 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10352 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10353 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10354 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10355 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10356 0x0000ffff /* end */
10358 IDirect3DVertexShader9 *shader;
10359 HRESULT hr;
10360 DWORD color;
10361 const float quad[] = {
10362 -1.0, -1.0, 0.1,
10363 1.0, -1.0, 0.1,
10364 -1.0, 1.0, 0.1,
10365 1.0, 1.0, 0.1
10368 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10369 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10370 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10371 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10372 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10373 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10374 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10375 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10377 hr = IDirect3DDevice9_BeginScene(device);
10378 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10379 if(SUCCEEDED(hr))
10381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10382 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10383 hr = IDirect3DDevice9_EndScene(device);
10384 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10386 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10387 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10389 color = getPixelColor(device, 320, 240);
10390 ok(color_match(color, 0x008000ff, 1),
10391 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10393 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10394 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10395 IDirect3DVertexShader9_Release(shader);
10398 static void viewport_test(IDirect3DDevice9 *device) {
10399 HRESULT hr;
10400 DWORD color;
10401 D3DVIEWPORT9 vp, old_vp;
10402 const float quad[] =
10404 -0.5, -0.5, 0.1,
10405 0.5, -0.5, 0.1,
10406 -0.5, 0.5, 0.1,
10407 0.5, 0.5, 0.1
10410 memset(&old_vp, 0, sizeof(old_vp));
10411 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10412 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10414 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10415 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10417 /* Test a viewport with Width and Height bigger than the surface dimensions
10419 * TODO: Test Width < surface.width, but X + Width > surface.width
10420 * TODO: Test Width < surface.width, what happens with the height?
10422 memset(&vp, 0, sizeof(vp));
10423 vp.X = 0;
10424 vp.Y = 0;
10425 vp.Width = 10000;
10426 vp.Height = 10000;
10427 vp.MinZ = 0.0;
10428 vp.MaxZ = 0.0;
10429 hr = IDirect3DDevice9_SetViewport(device, &vp);
10430 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10433 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10434 hr = IDirect3DDevice9_BeginScene(device);
10435 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10436 if(SUCCEEDED(hr))
10438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10439 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10440 hr = IDirect3DDevice9_EndScene(device);
10441 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10443 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10445 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10446 color = getPixelColor(device, 158, 118);
10447 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10448 color = getPixelColor(device, 162, 118);
10449 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10450 color = getPixelColor(device, 158, 122);
10451 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10452 color = getPixelColor(device, 162, 122);
10453 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10455 color = getPixelColor(device, 478, 358);
10456 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10457 color = getPixelColor(device, 482, 358);
10458 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10459 color = getPixelColor(device, 478, 362);
10460 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10461 color = getPixelColor(device, 482, 362);
10462 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10464 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10465 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10468 START_TEST(visual)
10470 IDirect3DDevice9 *device_ptr;
10471 D3DCAPS9 caps;
10472 HRESULT hr;
10473 DWORD color;
10475 d3d9_handle = LoadLibraryA("d3d9.dll");
10476 if (!d3d9_handle)
10478 skip("Could not load d3d9.dll\n");
10479 return;
10482 device_ptr = init_d3d9();
10483 if (!device_ptr)
10485 skip("Creating the device failed\n");
10486 return;
10489 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10491 /* Check for the reliability of the returned data */
10492 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10493 if(FAILED(hr))
10495 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10496 goto cleanup;
10498 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10500 color = getPixelColor(device_ptr, 1, 1);
10501 if(color !=0x00ff0000)
10503 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10504 goto cleanup;
10507 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10508 if(FAILED(hr))
10510 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10511 goto cleanup;
10513 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10515 color = getPixelColor(device_ptr, 639, 479);
10516 if(color != 0x0000ddee)
10518 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10519 goto cleanup;
10522 /* Now execute the real tests */
10523 stretchrect_test(device_ptr);
10524 lighting_test(device_ptr);
10525 clear_test(device_ptr);
10526 fog_test(device_ptr);
10527 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10529 test_cube_wrap(device_ptr);
10530 } else {
10531 skip("No cube texture support\n");
10533 z_range_test(device_ptr);
10534 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10536 maxmip_test(device_ptr);
10538 else
10540 skip("No mipmap support\n");
10542 offscreen_test(device_ptr);
10543 alpha_test(device_ptr);
10544 shademode_test(device_ptr);
10545 srgbtexture_test(device_ptr);
10546 release_buffer_test(device_ptr);
10547 float_texture_test(device_ptr);
10548 g16r16_texture_test(device_ptr);
10549 pixelshader_blending_test(device_ptr);
10550 texture_transform_flags_test(device_ptr);
10551 autogen_mipmap_test(device_ptr);
10552 fixed_function_decl_test(device_ptr);
10553 conditional_np2_repeat_test(device_ptr);
10554 fixed_function_bumpmap_test(device_ptr);
10555 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10556 stencil_cull_test(device_ptr);
10557 } else {
10558 skip("No two sided stencil support\n");
10560 pointsize_test(device_ptr);
10561 tssargtemp_test(device_ptr);
10562 np2_stretch_rect_test(device_ptr);
10563 yuv_color_test(device_ptr);
10564 zwriteenable_test(device_ptr);
10565 alphatest_test(device_ptr);
10566 viewport_test(device_ptr);
10568 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10570 test_constant_clamp_vs(device_ptr);
10571 test_compare_instructions(device_ptr);
10573 else skip("No vs_1_1 support\n");
10575 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10577 test_mova(device_ptr);
10578 loop_index_test(device_ptr);
10579 sincos_test(device_ptr);
10580 sgn_test(device_ptr);
10581 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10582 test_vshader_input(device_ptr);
10583 test_vshader_float16(device_ptr);
10584 stream_test(device_ptr);
10585 } else {
10586 skip("No vs_3_0 support\n");
10589 else skip("No vs_2_0 support\n");
10591 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10593 fog_with_shader_test(device_ptr);
10594 fog_srgbwrite_test(device_ptr);
10596 else skip("No vs_1_1 and ps_1_1 support\n");
10598 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10600 texbem_test(device_ptr);
10601 texdepth_test(device_ptr);
10602 texkill_test(device_ptr);
10603 x8l8v8u8_test(device_ptr);
10604 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10605 constant_clamp_ps_test(device_ptr);
10606 cnd_test(device_ptr);
10607 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10608 dp2add_ps_test(device_ptr);
10609 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10610 nested_loop_test(device_ptr);
10611 fixed_function_varying_test(device_ptr);
10612 vFace_register_test(device_ptr);
10613 vpos_register_test(device_ptr);
10614 multiple_rendertargets_test(device_ptr);
10615 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10616 vshader_version_varying_test(device_ptr);
10617 pshader_version_varying_test(device_ptr);
10618 } else {
10619 skip("No vs_3_0 support\n");
10621 } else {
10622 skip("No ps_3_0 support\n");
10624 } else {
10625 skip("No ps_2_0 support\n");
10629 else skip("No ps_1_1 support\n");
10631 texop_test(device_ptr);
10632 texop_range_test(device_ptr);
10633 alphareplicate_test(device_ptr);
10634 dp3_alpha_test(device_ptr);
10636 cleanup:
10637 if(device_ptr) {
10638 D3DPRESENT_PARAMETERS present_parameters;
10639 IDirect3DSwapChain9 *swapchain;
10640 ULONG ref;
10642 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10643 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10644 DestroyWindow(present_parameters.hDeviceWindow);
10645 IDirect3DSwapChain9_Release(swapchain);
10646 ref = IDirect3DDevice9_Release(device_ptr);
10647 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);