push bae61e3002acd849d282a00366b18661e823097b
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blobb871ad74d3d23658be127950bf2d876876de0aee
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_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114 if(FAILED(hr) || !surf ) /* This is not a test */
116 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117 return 0xdeadbeef;
120 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121 if(FAILED(hr))
123 trace("Can't get the render target, hr=%08x\n", hr);
124 ret = 0xdeadbeed;
125 goto out;
128 hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129 if(FAILED(hr))
131 trace("Can't read the render target data, hr=%08x\n", hr);
132 ret = 0xdeadbeec;
133 goto out;
136 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137 if(FAILED(hr))
139 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140 ret = 0xdeadbeeb;
141 goto out;
144 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145 * really important for these tests
147 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148 hr = IDirect3DSurface9_UnlockRect(surf);
149 if(FAILED(hr))
151 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
154 out:
155 if(target) IDirect3DSurface9_Release(target);
156 if(surf) IDirect3DSurface9_Release(surf);
157 return ret;
160 static IDirect3DDevice9 *init_d3d9(void)
162 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163 IDirect3D9 *d3d9_ptr = 0;
164 IDirect3DDevice9 *device_ptr = 0;
165 D3DPRESENT_PARAMETERS present_parameters;
166 HRESULT hr;
167 D3DADAPTER_IDENTIFIER9 identifier;
169 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171 if (!d3d9_create) return NULL;
173 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174 if (!d3d9_ptr)
176 skip("could not create D3D9\n");
177 return NULL;
180 ZeroMemory(&present_parameters, sizeof(present_parameters));
181 present_parameters.Windowed = TRUE;
182 present_parameters.hDeviceWindow = create_window();
183 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184 present_parameters.BackBufferWidth = 640;
185 present_parameters.BackBufferHeight = 480;
186 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187 present_parameters.EnableAutoDepthStencil = TRUE;
188 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190 memset(&identifier, 0, sizeof(identifier));
191 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193 trace("Driver string: \"%s\"\n", identifier.Driver);
194 trace("Description string: \"%s\"\n", identifier.Description);
195 ok(identifier.Description[0] != '\0', "Empty driver description\n");
196 trace("Device name string: \"%s\"\n", identifier.DeviceName);
197 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
198 trace("Driver version %d.%d.%d.%d\n",
199 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203 if(FAILED(hr)) {
204 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206 if(FAILED(hr)) {
207 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
210 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
212 return device_ptr;
215 struct vertex
217 float x, y, z;
218 DWORD diffuse;
221 struct tvertex
223 float x, y, z, rhw;
224 DWORD diffuse;
227 struct nvertex
229 float x, y, z;
230 float nx, ny, nz;
231 DWORD diffuse;
234 static void lighting_test(IDirect3DDevice9 *device)
236 HRESULT hr;
237 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239 DWORD color;
240 D3DMATERIAL9 material, old_material;
241 DWORD cop, carg;
243 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244 0.0f, 1.0f, 0.0f, 0.0f,
245 0.0f, 0.0f, 1.0f, 0.0f,
246 0.0f, 0.0f, 0.0f, 1.0f };
248 struct vertex unlitquad[] =
250 {-1.0f, -1.0f, 0.1f, 0xffff0000},
251 {-1.0f, 0.0f, 0.1f, 0xffff0000},
252 { 0.0f, 0.0f, 0.1f, 0xffff0000},
253 { 0.0f, -1.0f, 0.1f, 0xffff0000},
255 struct vertex litquad[] =
257 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
258 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
259 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
260 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
262 struct nvertex unlitnquad[] =
264 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
265 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
267 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
269 struct nvertex litnquad[] =
271 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
272 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
274 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
276 WORD Indices[] = {0, 1, 2, 2, 3, 0};
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
281 /* Setup some states that may cause issues */
282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
307 hr = IDirect3DDevice9_SetFVF(device, 0);
308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetFVF(device, fvf);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
313 hr = IDirect3DDevice9_BeginScene(device);
314 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315 if(hr == D3D_OK)
317 /* No lights are defined... That means, lit vertices should be entirely black */
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330 hr = IDirect3DDevice9_SetFVF(device, nfvf);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345 IDirect3DDevice9_EndScene(device);
346 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
349 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
358 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
360 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362 memset(&material, 0, sizeof(material));
363 material.Diffuse.r = 0.0;
364 material.Diffuse.g = 0.0;
365 material.Diffuse.b = 0.0;
366 material.Diffuse.a = 1.0;
367 material.Ambient.r = 0.0;
368 material.Ambient.g = 0.0;
369 material.Ambient.b = 0.0;
370 material.Ambient.a = 0.0;
371 material.Specular.r = 0.0;
372 material.Specular.g = 0.0;
373 material.Specular.b = 0.0;
374 material.Specular.a = 0.0;
375 material.Emissive.r = 0.0;
376 material.Emissive.g = 0.0;
377 material.Emissive.b = 0.0;
378 material.Emissive.a = 0.0;
379 material.Power = 0.0;
380 IDirect3DDevice9_SetMaterial(device, &material);
381 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
388 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
397 hr = IDirect3DDevice9_BeginScene(device);
398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399 if(SUCCEEDED(hr)) {
400 struct vertex lighting_test[] = {
401 {-1.0, -1.0, 0.1, 0x8000ff00},
402 { 1.0, -1.0, 0.1, 0x80000000},
403 {-1.0, 1.0, 0.1, 0x8000ff00},
404 { 1.0, 1.0, 0.1, 0x80000000}
406 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
411 hr = IDirect3DDevice9_EndScene(device);
412 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
415 color = getPixelColor(device, 320, 240);
416 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
433 static void clear_test(IDirect3DDevice9 *device)
435 /* Tests the correctness of clearing parameters */
436 HRESULT hr;
437 D3DRECT rect[2];
438 D3DRECT rect_negneg;
439 DWORD color;
440 D3DVIEWPORT9 old_vp, vp;
441 RECT scissor;
442 DWORD oldColorWrite;
443 BOOL invalid_clear_failed = FALSE;
445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448 /* Positive x, negative y */
449 rect[0].x1 = 0;
450 rect[0].y1 = 480;
451 rect[0].x2 = 320;
452 rect[0].y2 = 240;
454 /* Positive x, positive y */
455 rect[1].x1 = 0;
456 rect[1].y1 = 0;
457 rect[1].x2 = 320;
458 rect[1].y2 = 240;
459 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460 * returns D3D_OK, but ignores the rectangle silently
462 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466 /* negative x, negative y */
467 rect_negneg.x1 = 640;
468 rect_negneg.y1 = 240;
469 rect_negneg.x2 = 320;
470 rect_negneg.y2 = 0;
471 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475 color = getPixelColor(device, 160, 360); /* lower left quad */
476 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477 color = getPixelColor(device, 160, 120); /* upper left quad */
478 if(invalid_clear_failed) {
479 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481 } else {
482 /* If the negative rectangle was dropped silently, the correct ones are cleared */
483 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485 color = getPixelColor(device, 480, 360); /* lower right quad */
486 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487 color = getPixelColor(device, 480, 120); /* upper right quad */
488 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492 /* Test how the viewport affects clears */
493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
498 vp.X = 160;
499 vp.Y = 120;
500 vp.Width = 160;
501 vp.Height = 120;
502 vp.MinZ = 0.0;
503 vp.MaxZ = 1.0;
504 hr = IDirect3DDevice9_SetViewport(device, &vp);
505 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509 vp.X = 320;
510 vp.Y = 240;
511 vp.Width = 320;
512 vp.Height = 240;
513 vp.MinZ = 0.0;
514 vp.MaxZ = 1.0;
515 hr = IDirect3DDevice9_SetViewport(device, &vp);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 rect[0].x1 = 160;
518 rect[0].y1 = 120;
519 rect[0].x2 = 480;
520 rect[0].y2 = 360;
521 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
524 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
527 color = getPixelColor(device, 158, 118);
528 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529 color = getPixelColor(device, 162, 118);
530 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531 color = getPixelColor(device, 158, 122);
532 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533 color = getPixelColor(device, 162, 122);
534 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
536 color = getPixelColor(device, 318, 238);
537 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538 color = getPixelColor(device, 322, 238);
539 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540 color = getPixelColor(device, 318, 242);
541 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542 color = getPixelColor(device, 322, 242);
543 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
545 color = getPixelColor(device, 478, 358);
546 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547 color = getPixelColor(device, 482, 358);
548 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549 color = getPixelColor(device, 478, 362);
550 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551 color = getPixelColor(device, 482, 362);
552 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
554 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 scissor.left = 160;
560 scissor.right = 480;
561 scissor.top = 120;
562 scissor.bottom = 360;
563 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576 color = getPixelColor(device, 158, 118);
577 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578 color = getPixelColor(device, 162, 118);
579 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580 color = getPixelColor(device, 158, 122);
581 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582 color = getPixelColor(device, 162, 122);
583 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
585 color = getPixelColor(device, 158, 358);
586 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587 color = getPixelColor(device, 162, 358);
588 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589 color = getPixelColor(device, 158, 358);
590 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591 color = getPixelColor(device, 162, 362);
592 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
594 color = getPixelColor(device, 478, 118);
595 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596 color = getPixelColor(device, 478, 122);
597 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598 color = getPixelColor(device, 482, 122);
599 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600 color = getPixelColor(device, 482, 358);
601 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
603 color = getPixelColor(device, 478, 358);
604 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605 color = getPixelColor(device, 478, 362);
606 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607 color = getPixelColor(device, 482, 358);
608 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609 color = getPixelColor(device, 482, 362);
610 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612 color = getPixelColor(device, 318, 238);
613 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614 color = getPixelColor(device, 318, 242);
615 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616 color = getPixelColor(device, 322, 238);
617 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618 color = getPixelColor(device, 322, 242);
619 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
621 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
634 /* Colorwriteenable does not affect the clear */
635 color = getPixelColor(device, 320, 240);
636 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
638 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
641 typedef struct {
642 float in[4];
643 DWORD out;
644 } test_data_t;
647 * c7 mova ARGB mov ARGB
648 * -2.4 -2 0x00ffff00 -3 0x00ff0000
649 * -1.6 -2 0x00ffff00 -2 0x00ffff00
650 * -0.4 0 0x0000ffff -1 0x0000ff00
651 * 0.4 0 0x0000ffff 0 0x0000ffff
652 * 1.6 2 0x00ff00ff 1 0x000000ff
653 * 2.4 2 0x00ff00ff 2 0x00ff00ff
655 static void test_mova(IDirect3DDevice9 *device)
657 static const DWORD mova_test[] = {
658 0xfffe0200, /* vs_2_0 */
659 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
660 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
661 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
662 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
663 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
664 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
665 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
666 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
667 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
668 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
669 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
670 0x0000ffff /* END */
672 static const DWORD mov_test[] = {
673 0xfffe0101, /* vs_1_1 */
674 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
675 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
676 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
677 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
678 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
679 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
680 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
681 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
682 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
683 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
684 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
685 0x0000ffff /* END */
688 static const test_data_t test_data[2][6] = {
690 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
691 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
692 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
693 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
694 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
695 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
698 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
699 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
700 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
701 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
702 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
703 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
707 static const float quad[][3] = {
708 {-1.0f, -1.0f, 0.0f},
709 {-1.0f, 1.0f, 0.0f},
710 { 1.0f, -1.0f, 0.0f},
711 { 1.0f, 1.0f, 0.0f},
714 static const D3DVERTEXELEMENT9 decl_elements[] = {
715 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
716 D3DDECL_END()
719 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
720 IDirect3DVertexShader9 *mova_shader = NULL;
721 IDirect3DVertexShader9 *mov_shader = NULL;
722 HRESULT hr;
723 UINT i, j;
725 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
726 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
727 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
728 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
729 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
730 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
731 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
732 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
734 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
735 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
736 for(j = 0; j < 2; ++j)
738 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
740 DWORD color;
742 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
743 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
745 hr = IDirect3DDevice9_BeginScene(device);
746 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
749 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
751 hr = IDirect3DDevice9_EndScene(device);
752 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
754 color = getPixelColor(device, 320, 240);
755 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
756 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
758 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
759 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
762 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
764 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
765 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
768 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
769 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
771 IDirect3DVertexDeclaration9_Release(vertex_declaration);
772 IDirect3DVertexShader9_Release(mova_shader);
773 IDirect3DVertexShader9_Release(mov_shader);
776 struct sVertex {
777 float x, y, z;
778 DWORD diffuse;
779 DWORD specular;
782 struct sVertexT {
783 float x, y, z, rhw;
784 DWORD diffuse;
785 DWORD specular;
788 static void fog_test(IDirect3DDevice9 *device)
790 HRESULT hr;
791 D3DCOLOR color;
792 float start = 0.0f, end = 1.0f;
793 D3DCAPS9 caps;
794 int i;
796 /* Gets full z based fog with linear fog, no fog with specular color */
797 struct sVertex unstransformed_1[] = {
798 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
799 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
800 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
801 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
803 /* Ok, I am too lazy to deal with transform matrices */
804 struct sVertex unstransformed_2[] = {
805 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
806 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
807 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
808 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
810 /* Untransformed ones. Give them a different diffuse color to make the test look
811 * nicer. It also makes making sure that they are drawn correctly easier.
813 struct sVertexT transformed_1[] = {
814 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
815 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
816 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
817 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
819 struct sVertexT transformed_2[] = {
820 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
821 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
822 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
823 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
825 struct vertex rev_fog_quads[] = {
826 {-1.0, -1.0, 0.1, 0x000000ff},
827 {-1.0, 0.0, 0.1, 0x000000ff},
828 { 0.0, 0.0, 0.1, 0x000000ff},
829 { 0.0, -1.0, 0.1, 0x000000ff},
831 { 0.0, -1.0, 0.9, 0x000000ff},
832 { 0.0, 0.0, 0.9, 0x000000ff},
833 { 1.0, 0.0, 0.9, 0x000000ff},
834 { 1.0, -1.0, 0.9, 0x000000ff},
836 { 0.0, 0.0, 0.4, 0x000000ff},
837 { 0.0, 1.0, 0.4, 0x000000ff},
838 { 1.0, 1.0, 0.4, 0x000000ff},
839 { 1.0, 0.0, 0.4, 0x000000ff},
841 {-1.0, 0.0, 0.7, 0x000000ff},
842 {-1.0, 1.0, 0.7, 0x000000ff},
843 { 0.0, 1.0, 0.7, 0x000000ff},
844 { 0.0, 0.0, 0.7, 0x000000ff},
846 WORD Indices[] = {0, 1, 2, 2, 3, 0};
848 memset(&caps, 0, sizeof(caps));
849 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
850 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
854 /* Setup initial states: No lighting, fog on, fog color */
855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
856 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
858 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
860 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
862 /* First test: Both table fog and vertex fog off */
863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
864 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
866 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
868 /* Start = 0, end = 1. Should be default, but set them */
869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
870 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
872 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
874 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
876 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
877 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
878 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
879 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
880 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
881 sizeof(unstransformed_1[0]));
882 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
884 /* That makes it use the Z value */
885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
886 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
887 /* Untransformed, vertex fog != none (or table fog != none):
888 * Use the Z value as input into the equation
890 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
891 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
892 sizeof(unstransformed_1[0]));
893 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
895 /* transformed verts */
896 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
897 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
898 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
899 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
900 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
901 sizeof(transformed_1[0]));
902 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
905 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
906 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
907 * equation
909 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
910 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
911 sizeof(transformed_2[0]));
912 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
914 hr = IDirect3DDevice9_EndScene(device);
915 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
917 else
919 ok(FALSE, "BeginScene failed\n");
922 color = getPixelColor(device, 160, 360);
923 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
924 color = getPixelColor(device, 160, 120);
925 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
926 color = getPixelColor(device, 480, 120);
927 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
928 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
930 color = getPixelColor(device, 480, 360);
931 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
933 else
935 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
936 * The settings above result in no fogging with vertex fog
938 color = getPixelColor(device, 480, 120);
939 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
940 trace("Info: Table fog not supported by this device\n");
942 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
944 /* Now test the special case fogstart == fogend */
945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
946 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
948 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
950 start = 512;
951 end = 512;
952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
953 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
955 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
957 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
958 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
960 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
962 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
964 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
965 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
966 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
967 * The third transformed quad remains unfogged because the fogcoords are read from the specular
968 * color and has fixed fogstart and fogend.
970 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
971 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
972 sizeof(unstransformed_1[0]));
973 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
974 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
976 sizeof(unstransformed_1[0]));
977 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
980 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
981 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
982 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
983 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
984 sizeof(transformed_1[0]));
985 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
987 hr = IDirect3DDevice9_EndScene(device);
988 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
990 else
992 ok(FALSE, "BeginScene failed\n");
994 color = getPixelColor(device, 160, 360);
995 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
996 color = getPixelColor(device, 160, 120);
997 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
998 color = getPixelColor(device, 480, 120);
999 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1000 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1002 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1003 * but without shaders it seems to work everywhere
1005 end = 0.2;
1006 start = 0.8;
1007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1008 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1010 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1011 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1012 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1014 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1015 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1016 * so skip this for now
1018 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1019 const char *mode = (i ? "table" : "vertex");
1020 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1021 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1023 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1025 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1026 hr = IDirect3DDevice9_BeginScene(device);
1027 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1028 if(SUCCEEDED(hr)) {
1029 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1030 4, 5, 6, 6, 7, 4,
1031 8, 9, 10, 10, 11, 8,
1032 12, 13, 14, 14, 15, 12};
1034 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1035 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1036 sizeof(rev_fog_quads[0]));
1037 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1039 hr = IDirect3DDevice9_EndScene(device);
1040 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1042 color = getPixelColor(device, 160, 360);
1043 ok(color_match(color, 0x0000ff00, 1),
1044 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1046 color = getPixelColor(device, 160, 120);
1047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1048 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1050 color = getPixelColor(device, 480, 120);
1051 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1052 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1054 color = getPixelColor(device, 480, 360);
1055 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1057 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1059 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1060 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1061 break;
1064 /* Turn off the fog master switch to avoid confusing other tests */
1065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1066 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1067 start = 0.0;
1068 end = 1.0;
1069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1070 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1072 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1074 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1076 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1079 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1080 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1081 * regardless of the actual addressing mode set. */
1082 static void test_cube_wrap(IDirect3DDevice9 *device)
1084 static const float quad[][6] = {
1085 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1086 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1087 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1088 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1091 static const D3DVERTEXELEMENT9 decl_elements[] = {
1092 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1093 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1094 D3DDECL_END()
1097 static const struct {
1098 D3DTEXTUREADDRESS mode;
1099 const char *name;
1100 } address_modes[] = {
1101 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1102 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1103 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1104 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1105 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1108 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1109 IDirect3DCubeTexture9 *texture = NULL;
1110 IDirect3DSurface9 *surface = NULL;
1111 D3DLOCKED_RECT locked_rect;
1112 HRESULT hr;
1113 UINT x;
1114 INT y, face;
1116 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1117 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1118 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1119 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1121 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1122 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1123 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1125 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1126 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1128 for (y = 0; y < 128; ++y)
1130 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1131 for (x = 0; x < 64; ++x)
1133 *ptr++ = 0xffff0000;
1135 for (x = 64; x < 128; ++x)
1137 *ptr++ = 0xff0000ff;
1141 hr = IDirect3DSurface9_UnlockRect(surface);
1142 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1144 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1145 D3DPOOL_DEFAULT, &texture, NULL);
1146 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1148 /* Create cube faces */
1149 for (face = 0; face < 6; ++face)
1151 IDirect3DSurface9 *face_surface = NULL;
1153 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1154 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1156 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1157 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1159 IDirect3DSurface9_Release(face_surface);
1162 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1163 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1165 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1166 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1168 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1169 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1170 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1173 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1175 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1177 DWORD color;
1179 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1180 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1181 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1182 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1184 hr = IDirect3DDevice9_BeginScene(device);
1185 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1188 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1190 hr = IDirect3DDevice9_EndScene(device);
1191 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1193 /* Due to the nature of this test, we sample essentially at the edge
1194 * between two faces. Because of this it's undefined from which face
1195 * the driver will sample. Fortunately that's not important for this
1196 * test, since all we care about is that it doesn't sample from the
1197 * other side of the surface or from the border. */
1198 color = getPixelColor(device, 320, 240);
1199 ok(color == 0x00ff0000 || color == 0x000000ff,
1200 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1201 color, address_modes[x].name);
1203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1204 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1206 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1207 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1210 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1211 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1213 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1214 IDirect3DCubeTexture9_Release(texture);
1215 IDirect3DSurface9_Release(surface);
1218 static void offscreen_test(IDirect3DDevice9 *device)
1220 HRESULT hr;
1221 IDirect3DTexture9 *offscreenTexture = NULL;
1222 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1223 DWORD color;
1225 static const float quad[][5] = {
1226 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1227 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1228 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1229 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1232 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1233 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1235 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1236 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1237 if(!offscreenTexture) {
1238 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1239 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1240 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1241 if(!offscreenTexture) {
1242 skip("Cannot create an offscreen render target\n");
1243 goto out;
1247 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1248 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1249 if(!backbuffer) {
1250 goto out;
1253 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1254 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1255 if(!offscreen) {
1256 goto out;
1259 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1260 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1262 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1263 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1264 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1265 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1266 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1267 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1268 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1269 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1273 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1274 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1275 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1277 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1279 /* Draw without textures - Should result in a white quad */
1280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1281 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1283 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1284 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1285 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1286 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1288 /* This time with the texture */
1289 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1290 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1292 IDirect3DDevice9_EndScene(device);
1295 /* Center quad - should be white */
1296 color = getPixelColor(device, 320, 240);
1297 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1298 /* Some quad in the cleared part of the texture */
1299 color = getPixelColor(device, 170, 240);
1300 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1301 /* Part of the originally cleared back buffer */
1302 color = getPixelColor(device, 10, 10);
1303 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1304 if(0) {
1305 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1306 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1307 * the offscreen rendering mode this test would succeed or fail
1309 color = getPixelColor(device, 10, 470);
1310 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1313 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315 out:
1316 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1317 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1319 /* restore things */
1320 if(backbuffer) {
1321 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1322 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1323 IDirect3DSurface9_Release(backbuffer);
1325 if(offscreenTexture) {
1326 IDirect3DTexture9_Release(offscreenTexture);
1328 if(offscreen) {
1329 IDirect3DSurface9_Release(offscreen);
1333 /* This test tests fog in combination with shaders.
1334 * What's tested: linear fog (vertex and table) with pixel shader
1335 * linear table fog with non foggy vertex shader
1336 * vertex fog with foggy vertex shader, non-linear
1337 * fog with shader, non-linear fog with foggy shader,
1338 * linear table fog with foggy shader
1340 static void fog_with_shader_test(IDirect3DDevice9 *device)
1342 HRESULT hr;
1343 DWORD color;
1344 union {
1345 float f;
1346 DWORD i;
1347 } start, end;
1348 unsigned int i, j;
1350 /* basic vertex shader without fog computation ("non foggy") */
1351 static const DWORD vertex_shader_code1[] = {
1352 0xfffe0101, /* vs_1_1 */
1353 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1354 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1355 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1356 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1357 0x0000ffff
1359 /* basic vertex shader with reversed fog computation ("foggy") */
1360 static const DWORD vertex_shader_code2[] = {
1361 0xfffe0101, /* vs_1_1 */
1362 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1363 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1364 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1365 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1366 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1367 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1368 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1369 0x0000ffff
1371 /* basic pixel shader */
1372 static const DWORD pixel_shader_code[] = {
1373 0xffff0101, /* ps_1_1 */
1374 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1375 0x0000ffff
1378 static struct vertex quad[] = {
1379 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1380 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1381 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1382 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1385 static const D3DVERTEXELEMENT9 decl_elements[] = {
1386 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1387 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1388 D3DDECL_END()
1391 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1392 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1393 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1395 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1396 static const struct test_data_t {
1397 int vshader;
1398 int pshader;
1399 D3DFOGMODE vfog;
1400 D3DFOGMODE tfog;
1401 unsigned int color[11];
1402 } test_data[] = {
1403 /* only pixel shader: */
1404 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1405 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1406 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1408 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1411 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1413 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1414 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1415 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1416 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1417 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1418 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1420 /* vertex shader */
1421 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1422 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1423 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1424 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1425 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1426 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1427 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1428 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1429 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1431 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1432 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1433 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1434 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1435 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1436 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1438 /* vertex shader and pixel shader */
1439 /* The next 4 tests would read the fog coord output, but it isn't available.
1440 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1441 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1442 * These tests should be disabled if some other hardware behaves differently
1444 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1445 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1446 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1447 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1448 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1449 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1450 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1451 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1452 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1453 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1454 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1455 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1457 /* These use the Z coordinate with linear table fog */
1458 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1459 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1460 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1461 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1462 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1463 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1464 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1465 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1467 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1468 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1469 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1471 /* Non-linear table fog without fog coord */
1472 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1473 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1474 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1475 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1476 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1477 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1479 #if 0 /* FIXME: these fail on GeForce 8500 */
1480 /* foggy vertex shader */
1481 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1482 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1483 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1484 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1485 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1488 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1491 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493 #endif
1495 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1496 * all using the fixed fog-coord linear fog
1498 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1499 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1500 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1501 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1502 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1503 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1504 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1505 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1506 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1507 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1508 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1509 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1511 /* These use table fog. Here the shader-provided fog coordinate is
1512 * ignored and the z coordinate used instead
1514 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1515 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1516 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1517 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1518 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1519 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1520 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1521 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1525 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1526 start.f=0.1f;
1527 end.f=0.9f;
1529 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1530 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1531 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1532 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1533 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1534 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1535 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1536 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1538 /* Setup initial states: No lighting, fog on, fog color */
1539 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1540 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1542 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1544 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1545 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1546 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1549 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1551 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1553 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1555 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1557 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1559 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1561 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1562 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1563 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1564 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1566 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1568 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1570 for(j=0; j < 11; j++)
1572 /* Don't use the whole zrange to prevent rounding errors */
1573 quad[0].z = 0.001f + (float)j / 10.02f;
1574 quad[1].z = 0.001f + (float)j / 10.02f;
1575 quad[2].z = 0.001f + (float)j / 10.02f;
1576 quad[3].z = 0.001f + (float)j / 10.02f;
1578 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1579 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1581 hr = IDirect3DDevice9_BeginScene(device);
1582 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1585 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1587 hr = IDirect3DDevice9_EndScene(device);
1588 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1590 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1591 color = getPixelColor(device, 128, 240);
1592 ok(color_match(color, test_data[i].color[j], 13),
1593 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1594 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1596 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1600 /* reset states */
1601 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1602 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1603 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1604 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1605 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1606 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1608 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1610 IDirect3DVertexShader9_Release(vertex_shader[1]);
1611 IDirect3DVertexShader9_Release(vertex_shader[2]);
1612 IDirect3DPixelShader9_Release(pixel_shader[1]);
1613 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1616 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1617 unsigned int i, x, y;
1618 HRESULT hr;
1619 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1620 D3DLOCKED_RECT locked_rect;
1622 /* Generate the textures */
1623 for(i=0; i<2; i++)
1625 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1626 D3DPOOL_MANAGED, &texture[i], NULL);
1627 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1629 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1630 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1631 for (y = 0; y < 128; ++y)
1633 if(i)
1634 { /* Set up black texture with 2x2 texel white spot in the middle */
1635 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1636 for (x = 0; x < 128; ++x)
1638 if(y>62 && y<66 && x>62 && x<66)
1639 *ptr++ = 0xffffffff;
1640 else
1641 *ptr++ = 0xff000000;
1644 else
1645 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1646 * (if multiplied with bumpenvmat)
1648 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1649 for (x = 0; x < 128; ++x)
1651 if(abs(x-64)>abs(y-64))
1653 if(x < 64)
1654 *ptr++ = 0xc000;
1655 else
1656 *ptr++ = 0x4000;
1658 else
1660 if(y < 64)
1661 *ptr++ = 0x0040;
1662 else
1663 *ptr++ = 0x00c0;
1668 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1669 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1671 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1672 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1674 /* Disable texture filtering */
1675 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1676 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1677 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1678 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1680 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1681 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1682 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1683 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1687 /* test the behavior of the texbem instruction
1688 * with normal 2D and projective 2D textures
1690 static void texbem_test(IDirect3DDevice9 *device)
1692 HRESULT hr;
1693 DWORD color;
1694 int i;
1696 static const DWORD pixel_shader_code[] = {
1697 0xffff0101, /* ps_1_1*/
1698 0x00000042, 0xb00f0000, /* tex t0*/
1699 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1700 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1701 0x0000ffff
1703 static const DWORD double_texbem_code[] = {
1704 0xffff0103, /* ps_1_3 */
1705 0x00000042, 0xb00f0000, /* tex t0 */
1706 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1707 0x00000042, 0xb00f0002, /* tex t2 */
1708 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1709 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1710 0x0000ffff /* end */
1714 static const float quad[][7] = {
1715 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1716 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1717 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1718 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1720 static const float quad_proj[][9] = {
1721 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1722 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1723 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1724 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1727 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1728 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1729 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1730 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1731 D3DDECL_END()
1733 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1734 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1735 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1736 D3DDECL_END()
1737 } };
1739 /* use asymmetric matrix to test loading */
1740 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1742 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1743 IDirect3DPixelShader9 *pixel_shader = NULL;
1744 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1745 D3DLOCKED_RECT locked_rect;
1747 generate_bumpmap_textures(device);
1749 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1750 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1751 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1752 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1753 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1755 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1756 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1759 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1761 for(i=0; i<2; i++)
1763 if(i)
1765 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1766 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1769 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1770 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1771 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1772 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1774 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1775 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1776 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1777 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1779 hr = IDirect3DDevice9_BeginScene(device);
1780 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1782 if(!i)
1783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1784 else
1785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1786 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1788 hr = IDirect3DDevice9_EndScene(device);
1789 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1791 color = getPixelColor(device, 320-32, 240);
1792 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1793 color = getPixelColor(device, 320+32, 240);
1794 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1795 color = getPixelColor(device, 320, 240-32);
1796 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1797 color = getPixelColor(device, 320, 240+32);
1798 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1800 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1801 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1803 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1804 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1805 IDirect3DPixelShader9_Release(pixel_shader);
1807 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1808 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1809 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1812 /* clean up */
1813 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1814 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1816 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1817 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1819 for(i=0; i<2; i++)
1821 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1822 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1823 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1824 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1825 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1826 IDirect3DTexture9_Release(texture);
1829 /* Test double texbem */
1830 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1831 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1832 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1833 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1834 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1835 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1836 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1837 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1839 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1840 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1841 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1842 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1844 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1845 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1847 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1848 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1849 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1850 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1851 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1852 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1855 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1856 #define tex 0x00ff0000
1857 #define tex1 0x0000ff00
1858 #define origin 0x000000ff
1859 static const DWORD pixel_data[] = {
1860 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1861 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1862 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1863 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1864 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1865 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1866 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1867 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1869 #undef tex1
1870 #undef tex2
1871 #undef origin
1873 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1874 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1875 for(i = 0; i < 8; i++) {
1876 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1878 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1879 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1882 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1883 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1884 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1885 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1886 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1887 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1888 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1889 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1890 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1891 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1892 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1893 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1895 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1896 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1897 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1898 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1899 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1900 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1901 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1902 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1903 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1904 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1906 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1907 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1908 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1909 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1910 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1912 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1914 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1915 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1917 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1918 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1919 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1920 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1921 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1922 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1923 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1924 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1925 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1927 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1929 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1930 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1931 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1932 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1934 hr = IDirect3DDevice9_BeginScene(device);
1935 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1936 if(SUCCEEDED(hr)) {
1937 static const float double_quad[] = {
1938 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1939 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1940 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1941 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1946 hr = IDirect3DDevice9_EndScene(device);
1947 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1949 color = getPixelColor(device, 320, 240);
1950 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1952 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1953 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1954 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1955 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1956 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1957 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1958 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1959 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1960 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1961 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1963 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1964 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1966 IDirect3DPixelShader9_Release(pixel_shader);
1967 IDirect3DTexture9_Release(texture);
1968 IDirect3DTexture9_Release(texture1);
1969 IDirect3DTexture9_Release(texture2);
1972 static void z_range_test(IDirect3DDevice9 *device)
1974 const struct vertex quad[] =
1976 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1977 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1978 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1979 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1981 const struct vertex quad2[] =
1983 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1984 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1985 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1986 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1989 const struct tvertex quad3[] =
1991 { 0, 240, 1.1f, 1.0, 0xffffff00},
1992 { 0, 480, 1.1f, 1.0, 0xffffff00},
1993 { 640, 240, -1.1f, 1.0, 0xffffff00},
1994 { 640, 480, -1.1f, 1.0, 0xffffff00},
1996 const struct tvertex quad4[] =
1998 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1999 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2000 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2001 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2003 HRESULT hr;
2004 DWORD color;
2005 IDirect3DVertexShader9 *shader;
2006 IDirect3DVertexDeclaration9 *decl;
2007 D3DCAPS9 caps;
2008 const DWORD shader_code[] = {
2009 0xfffe0101, /* vs_1_1 */
2010 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2011 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2012 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2013 0x0000ffff /* end */
2015 static const D3DVERTEXELEMENT9 decl_elements[] = {
2016 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2017 D3DDECL_END()
2019 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2020 * then call Present. Then clear the color buffer to make sure it has some defined content
2021 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2022 * by the depth value.
2024 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2025 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2026 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2027 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2029 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2033 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2034 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2036 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2038 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2039 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2040 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2042 hr = IDirect3DDevice9_BeginScene(device);
2043 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2044 if(hr == D3D_OK)
2046 /* Test the untransformed vertex path */
2047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2048 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2050 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2051 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2052 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2054 /* Test the transformed vertex path */
2055 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2056 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2059 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2061 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2063 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2065 hr = IDirect3DDevice9_EndScene(device);
2066 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2069 /* Do not test the exact corner pixels, but go pretty close to them */
2071 /* Clipped because z > 1.0 */
2072 color = getPixelColor(device, 28, 238);
2073 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2074 color = getPixelColor(device, 28, 241);
2075 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2077 /* Not clipped, > z buffer clear value(0.75) */
2078 color = getPixelColor(device, 31, 238);
2079 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2080 color = getPixelColor(device, 31, 241);
2081 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2082 color = getPixelColor(device, 100, 238);
2083 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2084 color = getPixelColor(device, 100, 241);
2085 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2087 /* Not clipped, < z buffer clear value */
2088 color = getPixelColor(device, 104, 238);
2089 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2090 color = getPixelColor(device, 104, 241);
2091 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2092 color = getPixelColor(device, 318, 238);
2093 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2094 color = getPixelColor(device, 318, 241);
2095 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2097 /* Clipped because z < 0.0 */
2098 color = getPixelColor(device, 321, 238);
2099 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2100 color = getPixelColor(device, 321, 241);
2101 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2103 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2104 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2106 /* Test the shader path */
2107 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2108 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2109 skip("Vertex shaders not supported\n");
2110 goto out;
2112 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2113 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2114 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2115 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2119 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2120 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2121 IDirect3DDevice9_SetVertexShader(device, shader);
2122 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2124 hr = IDirect3DDevice9_BeginScene(device);
2125 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2126 if(hr == D3D_OK)
2128 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2129 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2130 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2132 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2135 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2137 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2139 hr = IDirect3DDevice9_EndScene(device);
2140 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2143 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2144 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2145 IDirect3DDevice9_SetVertexShader(device, NULL);
2146 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2148 IDirect3DVertexDeclaration9_Release(decl);
2149 IDirect3DVertexShader9_Release(shader);
2151 /* Z < 1.0 */
2152 color = getPixelColor(device, 28, 238);
2153 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2155 /* 1.0 < z < 0.75 */
2156 color = getPixelColor(device, 31, 238);
2157 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2158 color = getPixelColor(device, 100, 238);
2159 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2161 /* 0.75 < z < 0.0 */
2162 color = getPixelColor(device, 104, 238);
2163 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2164 color = getPixelColor(device, 318, 238);
2165 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2167 /* 0.0 < z */
2168 color = getPixelColor(device, 321, 238);
2169 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2171 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2172 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2174 out:
2175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2176 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2178 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2180 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2183 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2185 D3DSURFACE_DESC desc;
2186 D3DLOCKED_RECT l;
2187 HRESULT hr;
2188 unsigned int x, y;
2189 DWORD *mem;
2191 memset(&desc, 0, sizeof(desc));
2192 memset(&l, 0, sizeof(l));
2193 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2194 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2195 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2196 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2197 if(FAILED(hr)) return;
2199 for(y = 0; y < desc.Height; y++)
2201 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2202 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2204 mem[x] = color;
2207 hr = IDirect3DSurface9_UnlockRect(surface);
2208 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2211 /* This tests a variety of possible StretchRect() situations */
2212 static void stretchrect_test(IDirect3DDevice9 *device)
2214 HRESULT hr;
2215 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2216 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2217 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2218 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2219 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2220 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2221 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2222 IDirect3DSurface9 *orig_rt = NULL;
2223 DWORD color;
2225 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2226 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2227 if(!orig_rt) {
2228 goto out;
2231 /* Create our temporary surfaces in system memory */
2232 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2233 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2234 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2235 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2237 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2238 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2239 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2240 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2241 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2242 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2243 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2245 /* Create render target surfaces */
2246 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2247 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2248 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2249 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2250 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2251 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2253 /* Create render target textures */
2254 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2255 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2256 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2257 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2258 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2259 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2260 if (tex_rt32) {
2261 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2262 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2264 if (tex_rt64) {
2265 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2266 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2268 if (tex_rt_dest64) {
2269 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2270 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2273 /* Create regular textures in D3DPOOL_DEFAULT */
2274 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2275 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2276 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2277 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2278 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2279 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2280 if (tex32) {
2281 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2282 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2284 if (tex64) {
2285 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2286 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2288 if (tex_dest64) {
2289 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2290 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2293 /*********************************************************************
2294 * Tests for when the source parameter is an offscreen plain surface *
2295 *********************************************************************/
2297 /* Fill the offscreen 64x64 surface with green */
2298 if (surf_offscreen64)
2299 fill_surface(surf_offscreen64, 0xff00ff00);
2301 /* offscreenplain ==> offscreenplain, same size */
2302 if(surf_offscreen64 && surf_offscreen_dest64) {
2303 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2304 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2306 if (hr == D3D_OK) {
2307 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2308 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2312 /* offscreenplain ==> rendertarget texture, same size */
2313 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2314 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2315 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2317 /* We can't lock rendertarget textures, so copy to our temp surface first */
2318 if (hr == D3D_OK) {
2319 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2320 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2323 if (hr == D3D_OK) {
2324 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2325 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2329 /* offscreenplain ==> rendertarget surface, same size */
2330 if(surf_offscreen64 && surf_rt_dest64) {
2331 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2332 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2334 if (hr == D3D_OK) {
2335 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2336 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2340 /* offscreenplain ==> texture, same size (should fail) */
2341 if(surf_offscreen64 && surf_tex_dest64) {
2342 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2343 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2346 /* Fill the smaller offscreen surface with red */
2347 fill_surface(surf_offscreen32, 0xffff0000);
2349 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2350 if(surf_offscreen32 && surf_offscreen64) {
2351 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2352 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2355 /* offscreenplain ==> rendertarget texture, scaling */
2356 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2357 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2358 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2360 /* We can't lock rendertarget textures, so copy to our temp surface first */
2361 if (hr == D3D_OK) {
2362 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2363 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2366 if (hr == D3D_OK) {
2367 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2368 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2372 /* offscreenplain ==> rendertarget surface, scaling */
2373 if(surf_offscreen32 && surf_rt_dest64) {
2374 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2375 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2377 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2378 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2381 /* offscreenplain ==> texture, scaling (should fail) */
2382 if(surf_offscreen32 && surf_tex_dest64) {
2383 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2384 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2387 /************************************************************
2388 * Tests for when the source parameter is a regular texture *
2389 ************************************************************/
2391 /* Fill the surface of the regular texture with blue */
2392 if (surf_tex64 && surf_temp64) {
2393 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2394 fill_surface(surf_temp64, 0xff0000ff);
2395 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2396 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2399 /* texture ==> offscreenplain, same size */
2400 if(surf_tex64 && surf_offscreen64) {
2401 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2402 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2405 /* texture ==> rendertarget texture, same size */
2406 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2407 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2408 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2410 /* We can't lock rendertarget textures, so copy to our temp surface first */
2411 if (hr == D3D_OK) {
2412 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2413 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2416 if (hr == D3D_OK) {
2417 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2418 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2422 /* texture ==> rendertarget surface, same size */
2423 if(surf_tex64 && surf_rt_dest64) {
2424 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2425 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2427 if (hr == D3D_OK) {
2428 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2429 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2433 /* texture ==> texture, same size (should fail) */
2434 if(surf_tex64 && surf_tex_dest64) {
2435 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2436 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2439 /* Fill the surface of the smaller regular texture with red */
2440 if (surf_tex32 && surf_temp32) {
2441 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2442 fill_surface(surf_temp32, 0xffff0000);
2443 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2444 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2447 /* texture ==> offscreenplain, scaling (should fail) */
2448 if(surf_tex32 && surf_offscreen64) {
2449 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2450 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2453 /* texture ==> rendertarget texture, scaling */
2454 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2455 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2456 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458 /* We can't lock rendertarget textures, so copy to our temp surface first */
2459 if (hr == D3D_OK) {
2460 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2461 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2464 if (hr == D3D_OK) {
2465 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2466 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2470 /* texture ==> rendertarget surface, scaling */
2471 if(surf_tex32 && surf_rt_dest64) {
2472 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2473 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2475 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2476 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2479 /* texture ==> texture, scaling (should fail) */
2480 if(surf_tex32 && surf_tex_dest64) {
2481 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2482 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2485 /*****************************************************************
2486 * Tests for when the source parameter is a rendertarget texture *
2487 *****************************************************************/
2489 /* Fill the surface of the rendertarget texture with white */
2490 if (surf_tex_rt64 && surf_temp64) {
2491 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2492 fill_surface(surf_temp64, 0xffffffff);
2493 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2494 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2497 /* rendertarget texture ==> offscreenplain, same size */
2498 if(surf_tex_rt64 && surf_offscreen64) {
2499 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2500 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2503 /* rendertarget texture ==> rendertarget texture, same size */
2504 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2505 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2506 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2508 /* We can't lock rendertarget textures, so copy to our temp surface first */
2509 if (hr == D3D_OK) {
2510 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2511 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2514 if (hr == D3D_OK) {
2515 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2516 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2520 /* rendertarget texture ==> rendertarget surface, same size */
2521 if(surf_tex_rt64 && surf_rt_dest64) {
2522 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2523 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2525 if (hr == D3D_OK) {
2526 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2527 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2531 /* rendertarget texture ==> texture, same size (should fail) */
2532 if(surf_tex_rt64 && surf_tex_dest64) {
2533 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2534 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2537 /* Fill the surface of the smaller rendertarget texture with red */
2538 if (surf_tex_rt32 && surf_temp32) {
2539 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2540 fill_surface(surf_temp32, 0xffff0000);
2541 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2542 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2545 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2546 if(surf_tex_rt32 && surf_offscreen64) {
2547 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2548 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2551 /* rendertarget texture ==> rendertarget texture, scaling */
2552 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2553 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2554 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2556 /* We can't lock rendertarget textures, so copy to our temp surface first */
2557 if (hr == D3D_OK) {
2558 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2559 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2562 if (hr == D3D_OK) {
2563 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2564 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2568 /* rendertarget texture ==> rendertarget surface, scaling */
2569 if(surf_tex_rt32 && surf_rt_dest64) {
2570 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2571 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2573 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2574 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2577 /* rendertarget texture ==> texture, scaling (should fail) */
2578 if(surf_tex_rt32 && surf_tex_dest64) {
2579 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2580 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2583 /*****************************************************************
2584 * Tests for when the source parameter is a rendertarget surface *
2585 *****************************************************************/
2587 /* Fill the surface of the rendertarget surface with black */
2588 if (surf_rt64)
2589 fill_surface(surf_rt64, 0xff000000);
2591 /* rendertarget texture ==> offscreenplain, same size */
2592 if(surf_rt64 && surf_offscreen64) {
2593 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2594 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2597 /* rendertarget surface ==> rendertarget texture, same size */
2598 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2599 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2600 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2602 /* We can't lock rendertarget textures, so copy to our temp surface first */
2603 if (hr == D3D_OK) {
2604 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2605 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2608 if (hr == D3D_OK) {
2609 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2610 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2614 /* rendertarget surface ==> rendertarget surface, same size */
2615 if(surf_rt64 && surf_rt_dest64) {
2616 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2617 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2619 if (hr == D3D_OK) {
2620 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2621 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2625 /* rendertarget surface ==> texture, same size (should fail) */
2626 if(surf_rt64 && surf_tex_dest64) {
2627 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2628 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2631 /* Fill the surface of the smaller rendertarget texture with red */
2632 if (surf_rt32)
2633 fill_surface(surf_rt32, 0xffff0000);
2635 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2636 if(surf_rt32 && surf_offscreen64) {
2637 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2638 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2641 /* rendertarget surface ==> rendertarget texture, scaling */
2642 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2643 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2644 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2646 /* We can't lock rendertarget textures, so copy to our temp surface first */
2647 if (hr == D3D_OK) {
2648 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2649 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2652 if (hr == D3D_OK) {
2653 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2654 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2658 /* rendertarget surface ==> rendertarget surface, scaling */
2659 if(surf_rt32 && surf_rt_dest64) {
2660 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2661 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2663 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2664 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2667 /* rendertarget surface ==> texture, scaling (should fail) */
2668 if(surf_rt32 && surf_tex_dest64) {
2669 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2670 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2673 /* TODO: Test when source and destination RECT parameters are given... */
2674 /* TODO: Test format conversions */
2677 out:
2678 /* Clean up */
2679 if (surf_rt32)
2680 IDirect3DSurface9_Release(surf_rt32);
2681 if (surf_rt64)
2682 IDirect3DSurface9_Release(surf_rt64);
2683 if (surf_rt_dest64)
2684 IDirect3DSurface9_Release(surf_rt_dest64);
2685 if (surf_temp32)
2686 IDirect3DSurface9_Release(surf_temp32);
2687 if (surf_temp64)
2688 IDirect3DSurface9_Release(surf_temp64);
2689 if (surf_offscreen32)
2690 IDirect3DSurface9_Release(surf_offscreen32);
2691 if (surf_offscreen64)
2692 IDirect3DSurface9_Release(surf_offscreen64);
2693 if (surf_offscreen_dest64)
2694 IDirect3DSurface9_Release(surf_offscreen_dest64);
2696 if (tex_rt32) {
2697 if (surf_tex_rt32)
2698 IDirect3DSurface9_Release(surf_tex_rt32);
2699 IDirect3DTexture9_Release(tex_rt32);
2701 if (tex_rt64) {
2702 if (surf_tex_rt64)
2703 IDirect3DSurface9_Release(surf_tex_rt64);
2704 IDirect3DTexture9_Release(tex_rt64);
2706 if (tex_rt_dest64) {
2707 if (surf_tex_rt_dest64)
2708 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2709 IDirect3DTexture9_Release(tex_rt_dest64);
2711 if (tex32) {
2712 if (surf_tex32)
2713 IDirect3DSurface9_Release(surf_tex32);
2714 IDirect3DTexture9_Release(tex32);
2716 if (tex64) {
2717 if (surf_tex64)
2718 IDirect3DSurface9_Release(surf_tex64);
2719 IDirect3DTexture9_Release(tex64);
2721 if (tex_dest64) {
2722 if (surf_tex_dest64)
2723 IDirect3DSurface9_Release(surf_tex_dest64);
2724 IDirect3DTexture9_Release(tex_dest64);
2727 if (orig_rt) {
2728 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2729 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2730 IDirect3DSurface9_Release(orig_rt);
2734 static void maxmip_test(IDirect3DDevice9 *device)
2736 IDirect3DTexture9 *texture = NULL;
2737 IDirect3DSurface9 *surface = NULL;
2738 HRESULT hr;
2739 DWORD color;
2740 const float quads[] = {
2741 -1.0, -1.0, 0.0, 0.0, 0.0,
2742 -1.0, 0.0, 0.0, 0.0, 1.0,
2743 0.0, -1.0, 0.0, 1.0, 0.0,
2744 0.0, 0.0, 0.0, 1.0, 1.0,
2746 0.0, -1.0, 0.0, 0.0, 0.0,
2747 0.0, 0.0, 0.0, 0.0, 1.0,
2748 1.0, -1.0, 0.0, 1.0, 0.0,
2749 1.0, 0.0, 0.0, 1.0, 1.0,
2751 0.0, 0.0, 0.0, 0.0, 0.0,
2752 0.0, 1.0, 0.0, 0.0, 1.0,
2753 1.0, 0.0, 0.0, 1.0, 0.0,
2754 1.0, 1.0, 0.0, 1.0, 1.0,
2756 -1.0, 0.0, 0.0, 0.0, 0.0,
2757 -1.0, 1.0, 0.0, 0.0, 1.0,
2758 0.0, 0.0, 0.0, 1.0, 0.0,
2759 0.0, 1.0, 0.0, 1.0, 1.0,
2762 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2763 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2765 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2766 &texture, NULL);
2767 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2768 if(!texture)
2770 skip("Failed to create test texture\n");
2771 return;
2774 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2775 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2776 fill_surface(surface, 0xffff0000);
2777 IDirect3DSurface9_Release(surface);
2778 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2779 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2780 fill_surface(surface, 0xff00ff00);
2781 IDirect3DSurface9_Release(surface);
2782 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2783 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2784 fill_surface(surface, 0xff0000ff);
2785 IDirect3DSurface9_Release(surface);
2787 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2788 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2789 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2790 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2792 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2793 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2795 hr = IDirect3DDevice9_BeginScene(device);
2796 if(SUCCEEDED(hr))
2798 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2799 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2801 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2803 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2804 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2806 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2808 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2809 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2810 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2811 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2813 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2814 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2816 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2817 hr = IDirect3DDevice9_EndScene(device);
2818 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
2821 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2822 color = getPixelColor(device, 160, 360);
2823 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2824 color = getPixelColor(device, 160, 120);
2825 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2826 color = getPixelColor(device, 480, 120);
2827 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2828 color = getPixelColor(device, 480, 360);
2829 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2831 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2834 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2836 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2837 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2839 hr = IDirect3DDevice9_BeginScene(device);
2840 if(SUCCEEDED(hr))
2842 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2843 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2845 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2847 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2848 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2849 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2850 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2852 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2853 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2855 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2857 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2858 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2860 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2861 hr = IDirect3DDevice9_EndScene(device);
2862 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
2865 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2866 * samples from the highest level in the texture(level 2)
2868 color = getPixelColor(device, 160, 360);
2869 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2870 color = getPixelColor(device, 160, 120);
2871 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2872 color = getPixelColor(device, 480, 120);
2873 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2874 color = getPixelColor(device, 480, 360);
2875 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2876 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2877 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2879 hr = IDirect3DDevice9_BeginScene(device);
2880 if(SUCCEEDED(hr))
2882 DWORD ret;
2884 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2885 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2886 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2887 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2888 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2889 ret = IDirect3DTexture9_SetLOD(texture, 1);
2890 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2892 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2894 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2895 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2896 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2897 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2898 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2899 ret = IDirect3DTexture9_SetLOD(texture, 2);
2900 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2902 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2904 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2905 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2906 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2907 ret = IDirect3DTexture9_SetLOD(texture, 1);
2908 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2910 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2912 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2913 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2914 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2915 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2916 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2917 ret = IDirect3DTexture9_SetLOD(texture, 1);
2918 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2920 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2921 hr = IDirect3DDevice9_EndScene(device);
2924 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2925 * samples from the highest level in the texture(level 2)
2927 color = getPixelColor(device, 160, 360);
2928 ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2929 color = getPixelColor(device, 160, 120);
2930 ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2931 color = getPixelColor(device, 480, 120);
2932 ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2933 color = getPixelColor(device, 480, 360);
2934 ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2935 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2936 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2938 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2939 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2940 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2941 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2942 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2943 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2944 IDirect3DTexture9_Release(texture);
2947 static void release_buffer_test(IDirect3DDevice9 *device)
2949 IDirect3DVertexBuffer9 *vb = NULL;
2950 IDirect3DIndexBuffer9 *ib = NULL;
2951 HRESULT hr;
2952 BYTE *data;
2953 LONG ref;
2955 static const struct vertex quad[] = {
2956 {-1.0, -1.0, 0.1, 0xffff0000},
2957 {-1.0, 1.0, 0.1, 0xffff0000},
2958 { 1.0, 1.0, 0.1, 0xffff0000},
2960 {-1.0, -1.0, 0.1, 0xff00ff00},
2961 {-1.0, 1.0, 0.1, 0xff00ff00},
2962 { 1.0, 1.0, 0.1, 0xff00ff00}
2964 short indices[] = {3, 4, 5};
2966 /* Index and vertex buffers should always be creatable */
2967 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2968 D3DPOOL_MANAGED, &vb, NULL);
2969 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2970 if(!vb) {
2971 skip("Failed to create a vertex buffer\n");
2972 return;
2974 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2975 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2976 if(!ib) {
2977 skip("Failed to create an index buffer\n");
2978 return;
2981 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2982 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2983 memcpy(data, quad, sizeof(quad));
2984 hr = IDirect3DVertexBuffer9_Unlock(vb);
2985 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2987 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2988 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2989 memcpy(data, indices, sizeof(indices));
2990 hr = IDirect3DIndexBuffer9_Unlock(ib);
2991 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2993 hr = IDirect3DDevice9_SetIndices(device, ib);
2994 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2995 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2996 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2997 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2998 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3000 /* Now destroy the bound index buffer and draw again */
3001 ref = IDirect3DIndexBuffer9_Release(ib);
3002 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3004 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3005 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3007 hr = IDirect3DDevice9_BeginScene(device);
3008 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3009 if(SUCCEEDED(hr))
3011 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3012 * making assumptions about the indices or vertices
3014 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3015 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3016 hr = IDirect3DDevice9_EndScene(device);
3017 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3021 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3023 hr = IDirect3DDevice9_SetIndices(device, NULL);
3024 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3025 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3026 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3028 /* Index buffer was already destroyed as part of the test */
3029 IDirect3DVertexBuffer9_Release(vb);
3032 static void float_texture_test(IDirect3DDevice9 *device)
3034 IDirect3D9 *d3d = NULL;
3035 HRESULT hr;
3036 IDirect3DTexture9 *texture = NULL;
3037 D3DLOCKED_RECT lr;
3038 float *data;
3039 DWORD color;
3040 float quad[] = {
3041 -1.0, -1.0, 0.1, 0.0, 0.0,
3042 -1.0, 1.0, 0.1, 0.0, 1.0,
3043 1.0, -1.0, 0.1, 1.0, 0.0,
3044 1.0, 1.0, 0.1, 1.0, 1.0,
3047 memset(&lr, 0, sizeof(lr));
3048 IDirect3DDevice9_GetDirect3D(device, &d3d);
3049 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3050 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3051 skip("D3DFMT_R32F textures not supported\n");
3052 goto out;
3055 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3056 D3DPOOL_MANAGED, &texture, NULL);
3057 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3058 if(!texture) {
3059 skip("Failed to create R32F texture\n");
3060 goto out;
3063 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3064 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3065 data = lr.pBits;
3066 *data = 0.0;
3067 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3068 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3070 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3071 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3073 hr = IDirect3DDevice9_BeginScene(device);
3074 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3075 if(SUCCEEDED(hr))
3077 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3078 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3081 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3083 hr = IDirect3DDevice9_EndScene(device);
3084 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3086 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3087 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3089 color = getPixelColor(device, 240, 320);
3090 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3092 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3093 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3095 out:
3096 if(texture) IDirect3DTexture9_Release(texture);
3097 IDirect3D9_Release(d3d);
3100 static void g16r16_texture_test(IDirect3DDevice9 *device)
3102 IDirect3D9 *d3d = NULL;
3103 HRESULT hr;
3104 IDirect3DTexture9 *texture = NULL;
3105 D3DLOCKED_RECT lr;
3106 DWORD *data;
3107 DWORD color;
3108 float quad[] = {
3109 -1.0, -1.0, 0.1, 0.0, 0.0,
3110 -1.0, 1.0, 0.1, 0.0, 1.0,
3111 1.0, -1.0, 0.1, 1.0, 0.0,
3112 1.0, 1.0, 0.1, 1.0, 1.0,
3115 memset(&lr, 0, sizeof(lr));
3116 IDirect3DDevice9_GetDirect3D(device, &d3d);
3117 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3118 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3119 skip("D3DFMT_G16R16 textures not supported\n");
3120 goto out;
3123 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3124 D3DPOOL_MANAGED, &texture, NULL);
3125 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3126 if(!texture) {
3127 skip("Failed to create D3DFMT_G16R16 texture\n");
3128 goto out;
3131 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3132 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3133 data = lr.pBits;
3134 *data = 0x0f00f000;
3135 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3136 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3138 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3139 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3141 hr = IDirect3DDevice9_BeginScene(device);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3143 if(SUCCEEDED(hr))
3145 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3146 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3149 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3151 hr = IDirect3DDevice9_EndScene(device);
3152 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3154 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3155 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3157 color = getPixelColor(device, 240, 320);
3158 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3159 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3161 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3162 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3164 out:
3165 if(texture) IDirect3DTexture9_Release(texture);
3166 IDirect3D9_Release(d3d);
3169 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3171 HRESULT hr;
3172 IDirect3D9 *d3d;
3173 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3174 D3DCAPS9 caps;
3175 IDirect3DTexture9 *texture = NULL;
3176 IDirect3DVolumeTexture9 *volume = NULL;
3177 unsigned int x, y, z;
3178 D3DLOCKED_RECT lr;
3179 D3DLOCKED_BOX lb;
3180 DWORD color;
3181 UINT w, h;
3182 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3183 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3184 0.0, 1.0, 0.0, 0.0,
3185 0.0, 0.0, 1.0, 0.0,
3186 0.0, 0.0, 0.0, 1.0};
3187 static const D3DVERTEXELEMENT9 decl_elements[] = {
3188 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3189 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3190 D3DDECL_END()
3192 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3193 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3194 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3195 D3DDECL_END()
3197 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3198 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3199 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3200 D3DDECL_END()
3202 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3203 0x00, 0xff, 0x00, 0x00,
3204 0x00, 0x00, 0x00, 0x00,
3205 0x00, 0x00, 0x00, 0x00};
3207 memset(&lr, 0, sizeof(lr));
3208 memset(&lb, 0, sizeof(lb));
3209 IDirect3DDevice9_GetDirect3D(device, &d3d);
3210 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3211 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3212 fmt = D3DFMT_A16B16G16R16;
3214 IDirect3D9_Release(d3d);
3216 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3217 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3218 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3219 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3220 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3221 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3222 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3223 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3224 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3225 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3226 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3227 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3228 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3229 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3231 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3232 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3233 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3234 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3235 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3237 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3238 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3239 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3241 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3242 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3243 w = min(1024, caps.MaxTextureWidth);
3244 h = min(1024, caps.MaxTextureHeight);
3245 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3246 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3247 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3248 if(!texture) {
3249 skip("Failed to create the test texture\n");
3250 return;
3253 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3254 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3255 * 1.0 in red and green for the x and y coords
3257 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3258 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3259 for(y = 0; y < h; y++) {
3260 for(x = 0; x < w; x++) {
3261 double r_f = (double) y / (double) h;
3262 double g_f = (double) x / (double) w;
3263 if(fmt == D3DFMT_A16B16G16R16) {
3264 unsigned short r, g;
3265 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3266 r = (unsigned short) (r_f * 65536.0);
3267 g = (unsigned short) (g_f * 65536.0);
3268 dst[0] = r;
3269 dst[1] = g;
3270 dst[2] = 0;
3271 dst[3] = 65535;
3272 } else {
3273 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3274 unsigned char r = (unsigned char) (r_f * 255.0);
3275 unsigned char g = (unsigned char) (g_f * 255.0);
3276 dst[0] = 0;
3277 dst[1] = g;
3278 dst[2] = r;
3279 dst[3] = 255;
3283 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3284 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3285 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3286 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3288 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3289 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3290 hr = IDirect3DDevice9_BeginScene(device);
3291 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3292 if(SUCCEEDED(hr))
3294 float quad1[] = {
3295 -1.0, -1.0, 0.1, 1.0, 1.0,
3296 -1.0, 0.0, 0.1, 1.0, 1.0,
3297 0.0, -1.0, 0.1, 1.0, 1.0,
3298 0.0, 0.0, 0.1, 1.0, 1.0,
3300 float quad2[] = {
3301 -1.0, 0.0, 0.1, 1.0, 1.0,
3302 -1.0, 1.0, 0.1, 1.0, 1.0,
3303 0.0, 0.0, 0.1, 1.0, 1.0,
3304 0.0, 1.0, 0.1, 1.0, 1.0,
3306 float quad3[] = {
3307 0.0, 0.0, 0.1, 0.5, 0.5,
3308 0.0, 1.0, 0.1, 0.5, 0.5,
3309 1.0, 0.0, 0.1, 0.5, 0.5,
3310 1.0, 1.0, 0.1, 0.5, 0.5,
3312 float quad4[] = {
3313 320, 480, 0.1, 1.0, 0.0, 1.0,
3314 320, 240, 0.1, 1.0, 0.0, 1.0,
3315 640, 480, 0.1, 1.0, 0.0, 1.0,
3316 640, 240, 0.1, 1.0, 0.0, 1.0,
3318 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3319 0.0, 0.0, 0.0, 0.0,
3320 0.0, 0.0, 0.0, 0.0,
3321 0.0, 0.0, 0.0, 0.0};
3323 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3324 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3325 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3329 /* What happens with transforms enabled? */
3330 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3331 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3333 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3335 /* What happens if 4 coords are used, but only 2 given ?*/
3336 mat[8] = 1.0;
3337 mat[13] = 1.0;
3338 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3339 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3340 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3341 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3342 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3343 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3345 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3346 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3347 * due to the coords in the vertices. (turns out red, indeed)
3349 memset(mat, 0, sizeof(mat));
3350 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3351 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3353 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3355 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3356 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3357 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3359 hr = IDirect3DDevice9_EndScene(device);
3360 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3362 color = getPixelColor(device, 160, 360);
3363 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3364 color = getPixelColor(device, 160, 120);
3365 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3366 color = getPixelColor(device, 480, 120);
3367 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3368 color = getPixelColor(device, 480, 360);
3369 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3370 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3374 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3376 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3377 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3378 hr = IDirect3DDevice9_BeginScene(device);
3379 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3380 if(SUCCEEDED(hr))
3382 float quad1[] = {
3383 -1.0, -1.0, 0.1, 0.8, 0.2,
3384 -1.0, 0.0, 0.1, 0.8, 0.2,
3385 0.0, -1.0, 0.1, 0.8, 0.2,
3386 0.0, 0.0, 0.1, 0.8, 0.2,
3388 float quad2[] = {
3389 -1.0, 0.0, 0.1, 0.5, 1.0,
3390 -1.0, 1.0, 0.1, 0.5, 1.0,
3391 0.0, 0.0, 0.1, 0.5, 1.0,
3392 0.0, 1.0, 0.1, 0.5, 1.0,
3394 float quad3[] = {
3395 0.0, 0.0, 0.1, 0.5, 1.0,
3396 0.0, 1.0, 0.1, 0.5, 1.0,
3397 1.0, 0.0, 0.1, 0.5, 1.0,
3398 1.0, 1.0, 0.1, 0.5, 1.0,
3400 float quad4[] = {
3401 0.0, -1.0, 0.1, 0.8, 0.2,
3402 0.0, 0.0, 0.1, 0.8, 0.2,
3403 1.0, -1.0, 0.1, 0.8, 0.2,
3404 1.0, 0.0, 0.1, 0.8, 0.2,
3406 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3407 0.0, 0.0, 0.0, 0.0,
3408 0.0, 1.0, 0.0, 0.0,
3409 0.0, 0.0, 0.0, 0.0};
3411 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3413 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3414 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3415 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3416 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3419 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3421 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3422 * it behaves like COUNT2 because normal textures require 2 coords
3424 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3425 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3427 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3429 /* Just to be sure, the same as quad2 above */
3430 memset(mat, 0, sizeof(mat));
3431 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3432 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3433 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3434 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3436 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3438 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3439 * used? And what happens to the first?
3441 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3442 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3444 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3446 hr = IDirect3DDevice9_EndScene(device);
3447 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3449 color = getPixelColor(device, 160, 360);
3450 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3451 color = getPixelColor(device, 160, 120);
3452 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3453 color = getPixelColor(device, 480, 120);
3454 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3455 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3456 color = getPixelColor(device, 480, 360);
3457 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3458 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3459 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3460 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3462 IDirect3DTexture9_Release(texture);
3464 /* Test projected textures, without any fancy matrices */
3465 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3466 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3467 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3468 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3469 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3470 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3471 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3472 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3474 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3475 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3476 for(x = 0; x < 4; x++) {
3477 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3479 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3480 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3481 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3482 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3484 hr = IDirect3DDevice9_BeginScene(device);
3485 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3486 if(SUCCEEDED(hr))
3488 const float proj_quads[] = {
3489 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3490 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3491 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3492 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3493 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3494 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3495 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3496 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3499 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3500 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3501 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3502 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3504 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3505 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3507 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3509 hr = IDirect3DDevice9_EndScene(device);
3510 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3513 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3514 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3515 IDirect3DTexture9_Release(texture);
3517 color = getPixelColor(device, 158, 118);
3518 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3519 color = getPixelColor(device, 162, 118);
3520 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3521 color = getPixelColor(device, 158, 122);
3522 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3523 color = getPixelColor(device, 162, 122);
3524 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3526 color = getPixelColor(device, 158, 178);
3527 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3528 color = getPixelColor(device, 162, 178);
3529 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3530 color = getPixelColor(device, 158, 182);
3531 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3532 color = getPixelColor(device, 162, 182);
3533 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3535 color = getPixelColor(device, 318, 118);
3536 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3537 color = getPixelColor(device, 322, 118);
3538 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3539 color = getPixelColor(device, 318, 122);
3540 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3541 color = getPixelColor(device, 322, 122);
3542 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3544 color = getPixelColor(device, 318, 178);
3545 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3546 color = getPixelColor(device, 322, 178);
3547 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3548 color = getPixelColor(device, 318, 182);
3549 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3550 color = getPixelColor(device, 322, 182);
3551 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3553 color = getPixelColor(device, 238, 298);
3554 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3555 color = getPixelColor(device, 242, 298);
3556 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3557 color = getPixelColor(device, 238, 302);
3558 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3559 color = getPixelColor(device, 242, 302);
3560 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3562 color = getPixelColor(device, 238, 388);
3563 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3564 color = getPixelColor(device, 242, 388);
3565 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3566 color = getPixelColor(device, 238, 392);
3567 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3568 color = getPixelColor(device, 242, 392);
3569 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3571 color = getPixelColor(device, 478, 298);
3572 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3573 color = getPixelColor(device, 482, 298);
3574 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3575 color = getPixelColor(device, 478, 302);
3576 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3577 color = getPixelColor(device, 482, 302);
3578 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3580 color = getPixelColor(device, 478, 388);
3581 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3582 color = getPixelColor(device, 482, 388);
3583 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3584 color = getPixelColor(device, 478, 392);
3585 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3586 color = getPixelColor(device, 482, 392);
3587 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3589 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3590 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3592 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3593 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3594 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3595 * Thus watch out if sampling from texels between 0 and 1.
3597 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3598 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3599 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3600 if(!volume) {
3601 skip("Failed to create a volume texture\n");
3602 goto out;
3605 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3606 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3607 for(z = 0; z < 32; z++) {
3608 for(y = 0; y < 32; y++) {
3609 for(x = 0; x < 32; x++) {
3610 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3611 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3612 float r_f = (float) x / 31.0;
3613 float g_f = (float) y / 31.0;
3614 float b_f = (float) z / 31.0;
3616 if(fmt == D3DFMT_A16B16G16R16) {
3617 unsigned short *mem_s = mem;
3618 mem_s[0] = r_f * 65535.0;
3619 mem_s[1] = g_f * 65535.0;
3620 mem_s[2] = b_f * 65535.0;
3621 mem_s[3] = 65535;
3622 } else {
3623 unsigned char *mem_c = mem;
3624 mem_c[0] = b_f * 255.0;
3625 mem_c[1] = g_f * 255.0;
3626 mem_c[2] = r_f * 255.0;
3627 mem_c[3] = 255;
3632 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3633 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3635 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3636 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3638 hr = IDirect3DDevice9_BeginScene(device);
3639 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3640 if(SUCCEEDED(hr))
3642 float quad1[] = {
3643 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3644 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3645 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3646 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3648 float quad2[] = {
3649 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3650 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3651 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3652 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3654 float quad3[] = {
3655 0.0, 0.0, 0.1, 0.0, 0.0,
3656 0.0, 1.0, 0.1, 0.0, 0.0,
3657 1.0, 0.0, 0.1, 0.0, 0.0,
3658 1.0, 1.0, 0.1, 0.0, 0.0
3660 float quad4[] = {
3661 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3662 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3663 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3664 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3666 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3667 0.0, 0.0, 1.0, 0.0,
3668 0.0, 1.0, 0.0, 0.0,
3669 0.0, 0.0, 0.0, 1.0};
3670 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3671 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3673 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3674 * values
3676 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3677 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3678 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3679 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3681 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3683 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3684 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3685 * otherwise the w will be missing(blue).
3686 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3687 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3689 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3690 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3692 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3694 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3695 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3696 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3697 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3699 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3700 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3701 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3702 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3704 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3705 * disable. ATI extends it up to the amount of values needed for the volume texture
3707 memset(mat, 0, sizeof(mat));
3708 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3709 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3710 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3711 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3712 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3713 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3715 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3717 hr = IDirect3DDevice9_EndScene(device);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3721 color = getPixelColor(device, 160, 360);
3722 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3723 color = getPixelColor(device, 160, 120);
3724 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3725 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3726 color = getPixelColor(device, 480, 120);
3727 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3728 color = getPixelColor(device, 480, 360);
3729 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3731 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3732 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3734 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3735 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3736 hr = IDirect3DDevice9_BeginScene(device);
3737 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3738 if(SUCCEEDED(hr))
3740 float quad1[] = {
3741 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3742 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3743 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3744 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3746 float quad2[] = {
3747 -1.0, 0.0, 0.1,
3748 -1.0, 1.0, 0.1,
3749 0.0, 0.0, 0.1,
3750 0.0, 1.0, 0.1,
3752 float quad3[] = {
3753 0.0, 0.0, 0.1, 1.0,
3754 0.0, 1.0, 0.1, 1.0,
3755 1.0, 0.0, 0.1, 1.0,
3756 1.0, 1.0, 0.1, 1.0
3758 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3759 0.0, 0.0, 0.0, 0.0,
3760 0.0, 0.0, 0.0, 0.0,
3761 0.0, 1.0, 0.0, 0.0};
3762 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3763 1.0, 0.0, 0.0, 0.0,
3764 0.0, 1.0, 0.0, 0.0,
3765 0.0, 0.0, 1.0, 0.0};
3766 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3769 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3771 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3773 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3774 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3776 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3778 /* None passed */
3779 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3781 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3784 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3786 /* 4 used, 1 passed */
3787 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3788 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3789 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3790 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3792 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3794 hr = IDirect3DDevice9_EndScene(device);
3795 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3797 color = getPixelColor(device, 160, 360);
3798 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3799 color = getPixelColor(device, 160, 120);
3800 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3801 color = getPixelColor(device, 480, 120);
3802 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3803 /* Quad4: unused */
3805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3806 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3808 IDirect3DVolumeTexture9_Release(volume);
3810 out:
3811 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3812 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3813 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3814 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3815 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3816 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3817 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3818 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3819 IDirect3DVertexDeclaration9_Release(decl);
3820 IDirect3DVertexDeclaration9_Release(decl2);
3821 IDirect3DVertexDeclaration9_Release(decl3);
3824 static void texdepth_test(IDirect3DDevice9 *device)
3826 IDirect3DPixelShader9 *shader;
3827 HRESULT hr;
3828 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3829 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3830 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3831 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3832 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3833 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3834 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3835 DWORD shader_code[] = {
3836 0xffff0104, /* ps_1_4 */
3837 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3838 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3839 0x0000fffd, /* phase */
3840 0x00000057, 0x800f0005, /* texdepth r5 */
3841 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3842 0x0000ffff /* end */
3844 DWORD color;
3845 float vertex[] = {
3846 -1.0, -1.0, 0.0,
3847 1.0, -1.0, 1.0,
3848 -1.0, 1.0, 0.0,
3849 1.0, 1.0, 1.0
3852 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3853 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3856 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3858 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3860 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3862 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3863 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3864 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
3866 /* Fill the depth buffer with a gradient */
3867 hr = IDirect3DDevice9_BeginScene(device);
3868 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3869 if(SUCCEEDED(hr))
3871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3872 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3873 hr = IDirect3DDevice9_EndScene(device);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3877 /* Now perform the actual tests. Same geometry, but with the shader */
3878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3881 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3882 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3885 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3886 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3887 hr = IDirect3DDevice9_BeginScene(device);
3888 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3889 if(SUCCEEDED(hr))
3891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3892 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3894 hr = IDirect3DDevice9_EndScene(device);
3895 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3898 color = getPixelColor(device, 158, 240);
3899 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3900 color = getPixelColor(device, 162, 240);
3901 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3903 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3907 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3909 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3910 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3911 hr = IDirect3DDevice9_BeginScene(device);
3912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3913 if(SUCCEEDED(hr))
3915 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3916 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3918 hr = IDirect3DDevice9_EndScene(device);
3919 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3922 color = getPixelColor(device, 318, 240);
3923 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3924 color = getPixelColor(device, 322, 240);
3925 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3927 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3928 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3930 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3931 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3933 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3934 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3935 hr = IDirect3DDevice9_BeginScene(device);
3936 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3937 if(SUCCEEDED(hr))
3939 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3940 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3942 hr = IDirect3DDevice9_EndScene(device);
3943 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3946 color = getPixelColor(device, 1, 240);
3947 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3949 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3950 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3953 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3955 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3956 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3957 hr = IDirect3DDevice9_BeginScene(device);
3958 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3959 if(SUCCEEDED(hr))
3961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3962 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3964 hr = IDirect3DDevice9_EndScene(device);
3965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3967 color = getPixelColor(device, 318, 240);
3968 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3969 color = getPixelColor(device, 322, 240);
3970 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3972 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3973 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3976 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3978 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3979 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3980 hr = IDirect3DDevice9_BeginScene(device);
3981 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3982 if(SUCCEEDED(hr))
3984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3985 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3987 hr = IDirect3DDevice9_EndScene(device);
3988 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3991 color = getPixelColor(device, 1, 240);
3992 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3994 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3995 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3998 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4000 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4001 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4002 hr = IDirect3DDevice9_BeginScene(device);
4003 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4004 if(SUCCEEDED(hr))
4006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4007 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4009 hr = IDirect3DDevice9_EndScene(device);
4010 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4013 color = getPixelColor(device, 638, 240);
4014 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4016 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4017 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4020 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4022 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4023 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4024 hr = IDirect3DDevice9_BeginScene(device);
4025 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4026 if(SUCCEEDED(hr))
4028 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4029 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4031 hr = IDirect3DDevice9_EndScene(device);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4035 color = getPixelColor(device, 638, 240);
4036 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4038 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4041 /* Cleanup */
4042 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4043 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4044 IDirect3DPixelShader9_Release(shader);
4046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4047 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4049 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4052 static void texkill_test(IDirect3DDevice9 *device)
4054 IDirect3DPixelShader9 *shader;
4055 HRESULT hr;
4056 DWORD color;
4058 const float vertex[] = {
4059 /* bottom top right left */
4060 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4061 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4062 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4063 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4066 DWORD shader_code_11[] = {
4067 0xffff0101, /* ps_1_1 */
4068 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4069 0x00000041, 0xb00f0000, /* texkill t0 */
4070 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4071 0x0000ffff /* end */
4073 DWORD shader_code_20[] = {
4074 0xffff0200, /* ps_2_0 */
4075 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4076 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4077 0x01000041, 0xb00f0000, /* texkill t0 */
4078 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4079 0x0000ffff /* end */
4082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4083 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4084 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4085 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4087 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4088 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4089 hr = IDirect3DDevice9_BeginScene(device);
4090 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4091 if(SUCCEEDED(hr))
4093 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4094 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4096 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4097 hr = IDirect3DDevice9_EndScene(device);
4098 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4100 color = getPixelColor(device, 63, 46);
4101 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4102 color = getPixelColor(device, 66, 46);
4103 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4104 color = getPixelColor(device, 63, 49);
4105 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4106 color = getPixelColor(device, 66, 49);
4107 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4109 color = getPixelColor(device, 578, 46);
4110 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4111 color = getPixelColor(device, 575, 46);
4112 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4113 color = getPixelColor(device, 578, 49);
4114 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4115 color = getPixelColor(device, 575, 49);
4116 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4118 color = getPixelColor(device, 63, 430);
4119 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4120 color = getPixelColor(device, 63, 433);
4121 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4122 color = getPixelColor(device, 66, 433);
4123 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4124 color = getPixelColor(device, 66, 430);
4125 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4127 color = getPixelColor(device, 578, 430);
4128 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4129 color = getPixelColor(device, 578, 433);
4130 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4131 color = getPixelColor(device, 575, 433);
4132 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4133 color = getPixelColor(device, 575, 430);
4134 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4136 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4139 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4140 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4141 IDirect3DPixelShader9_Release(shader);
4143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4145 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4146 if(FAILED(hr)) {
4147 skip("Failed to create 2.0 test shader, most likely not supported\n");
4148 return;
4151 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4153 hr = IDirect3DDevice9_BeginScene(device);
4154 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4155 if(SUCCEEDED(hr))
4157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4158 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4159 hr = IDirect3DDevice9_EndScene(device);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4163 color = getPixelColor(device, 63, 46);
4164 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4165 color = getPixelColor(device, 66, 46);
4166 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4167 color = getPixelColor(device, 63, 49);
4168 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4169 color = getPixelColor(device, 66, 49);
4170 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4172 color = getPixelColor(device, 578, 46);
4173 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4174 color = getPixelColor(device, 575, 46);
4175 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4176 color = getPixelColor(device, 578, 49);
4177 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4178 color = getPixelColor(device, 575, 49);
4179 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4181 color = getPixelColor(device, 63, 430);
4182 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4183 color = getPixelColor(device, 63, 433);
4184 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4185 color = getPixelColor(device, 66, 433);
4186 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4187 color = getPixelColor(device, 66, 430);
4188 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4190 color = getPixelColor(device, 578, 430);
4191 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4192 color = getPixelColor(device, 578, 433);
4193 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4194 color = getPixelColor(device, 575, 433);
4195 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4196 color = getPixelColor(device, 575, 430);
4197 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4199 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4200 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4202 /* Cleanup */
4203 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4204 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4205 IDirect3DPixelShader9_Release(shader);
4208 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4210 IDirect3D9 *d3d9;
4211 HRESULT hr;
4212 IDirect3DTexture9 *texture;
4213 IDirect3DPixelShader9 *shader;
4214 IDirect3DPixelShader9 *shader2;
4215 D3DLOCKED_RECT lr;
4216 DWORD color;
4217 DWORD shader_code[] = {
4218 0xffff0101, /* ps_1_1 */
4219 0x00000042, 0xb00f0000, /* tex t0 */
4220 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4221 0x0000ffff /* end */
4223 DWORD shader_code2[] = {
4224 0xffff0101, /* ps_1_1 */
4225 0x00000042, 0xb00f0000, /* tex t0 */
4226 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4227 0x0000ffff /* end */
4230 float quad[] = {
4231 -1.0, -1.0, 0.1, 0.5, 0.5,
4232 1.0, -1.0, 0.1, 0.5, 0.5,
4233 -1.0, 1.0, 0.1, 0.5, 0.5,
4234 1.0, 1.0, 0.1, 0.5, 0.5,
4237 memset(&lr, 0, sizeof(lr));
4238 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4239 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4240 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4241 IDirect3D9_Release(d3d9);
4242 if(FAILED(hr)) {
4243 skip("No D3DFMT_X8L8V8U8 support\n");
4244 return;
4247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4248 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4250 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4251 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4252 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4253 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4254 *((DWORD *) lr.pBits) = 0x11ca3141;
4255 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4256 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4258 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4259 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4260 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4263 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4264 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4265 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4266 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4267 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4270 hr = IDirect3DDevice9_BeginScene(device);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4272 if(SUCCEEDED(hr))
4274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4275 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4277 hr = IDirect3DDevice9_EndScene(device);
4278 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4280 color = getPixelColor(device, 578, 430);
4281 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4282 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4284 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4286 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4287 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4288 hr = IDirect3DDevice9_BeginScene(device);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4290 if(SUCCEEDED(hr))
4292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4293 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4295 hr = IDirect3DDevice9_EndScene(device);
4296 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4298 color = getPixelColor(device, 578, 430);
4299 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4300 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4301 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4303 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4304 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4305 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4306 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4307 IDirect3DPixelShader9_Release(shader);
4308 IDirect3DPixelShader9_Release(shader2);
4309 IDirect3DTexture9_Release(texture);
4312 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4314 HRESULT hr;
4315 IDirect3D9 *d3d;
4316 IDirect3DTexture9 *texture = NULL;
4317 IDirect3DSurface9 *surface;
4318 DWORD color;
4319 const RECT r1 = {256, 256, 512, 512};
4320 const RECT r2 = {512, 256, 768, 512};
4321 const RECT r3 = {256, 512, 512, 768};
4322 const RECT r4 = {512, 512, 768, 768};
4323 unsigned int x, y;
4324 D3DLOCKED_RECT lr;
4325 memset(&lr, 0, sizeof(lr));
4327 IDirect3DDevice9_GetDirect3D(device, &d3d);
4328 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4329 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4330 skip("No autogenmipmap support\n");
4331 IDirect3D9_Release(d3d);
4332 return;
4334 IDirect3D9_Release(d3d);
4336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4337 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4339 /* Make the mipmap big, so that a smaller mipmap is used
4341 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4342 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4343 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4345 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4346 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4347 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4348 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4349 for(y = 0; y < 1024; y++) {
4350 for(x = 0; x < 1024; x++) {
4351 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4352 POINT pt;
4354 pt.x = x;
4355 pt.y = y;
4356 if(PtInRect(&r1, pt)) {
4357 *dst = 0xffff0000;
4358 } else if(PtInRect(&r2, pt)) {
4359 *dst = 0xff00ff00;
4360 } else if(PtInRect(&r3, pt)) {
4361 *dst = 0xff0000ff;
4362 } else if(PtInRect(&r4, pt)) {
4363 *dst = 0xff000000;
4364 } else {
4365 *dst = 0xffffffff;
4369 hr = IDirect3DSurface9_UnlockRect(surface);
4370 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4371 IDirect3DSurface9_Release(surface);
4373 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4374 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4376 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4378 hr = IDirect3DDevice9_BeginScene(device);
4379 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4380 if(SUCCEEDED(hr)) {
4381 const float quad[] = {
4382 -0.5, -0.5, 0.1, 0.0, 0.0,
4383 -0.5, 0.5, 0.1, 0.0, 1.0,
4384 0.5, -0.5, 0.1, 1.0, 0.0,
4385 0.5, 0.5, 0.1, 1.0, 1.0
4388 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4391 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4392 hr = IDirect3DDevice9_EndScene(device);
4393 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4395 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4396 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4397 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4398 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4399 IDirect3DTexture9_Release(texture);
4401 color = getPixelColor(device, 200, 200);
4402 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4403 color = getPixelColor(device, 280, 200);
4404 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4405 color = getPixelColor(device, 360, 200);
4406 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4407 color = getPixelColor(device, 440, 200);
4408 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4409 color = getPixelColor(device, 200, 270);
4410 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4411 color = getPixelColor(device, 280, 270);
4412 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4413 color = getPixelColor(device, 360, 270);
4414 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4415 color = getPixelColor(device, 440, 270);
4416 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4417 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4418 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4421 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4423 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4424 IDirect3DVertexDeclaration9 *decl;
4425 HRESULT hr;
4426 DWORD color;
4427 DWORD shader_code_11[] = {
4428 0xfffe0101, /* vs_1_1 */
4429 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4430 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4431 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4432 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4433 0x0000ffff /* end */
4435 DWORD shader_code_11_2[] = {
4436 0xfffe0101, /* vs_1_1 */
4437 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4438 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4439 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4440 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4441 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4442 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4443 0x0000ffff /* end */
4445 DWORD shader_code_20[] = {
4446 0xfffe0200, /* vs_2_0 */
4447 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4448 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4449 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4450 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4451 0x0000ffff /* end */
4453 DWORD shader_code_20_2[] = {
4454 0xfffe0200, /* vs_2_0 */
4455 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4456 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4457 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4458 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4459 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4460 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4461 0x0000ffff /* end */
4463 static const D3DVERTEXELEMENT9 decl_elements[] = {
4464 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4465 D3DDECL_END()
4467 float quad1[] = {
4468 -1.0, -1.0, 0.1,
4469 0.0, -1.0, 0.1,
4470 -1.0, 0.0, 0.1,
4471 0.0, 0.0, 0.1
4473 float quad2[] = {
4474 0.0, -1.0, 0.1,
4475 1.0, -1.0, 0.1,
4476 0.0, 0.0, 0.1,
4477 1.0, 0.0, 0.1
4479 float quad3[] = {
4480 0.0, 0.0, 0.1,
4481 1.0, 0.0, 0.1,
4482 0.0, 1.0, 0.1,
4483 1.0, 1.0, 0.1
4485 float quad4[] = {
4486 -1.0, 0.0, 0.1,
4487 0.0, 0.0, 0.1,
4488 -1.0, 1.0, 0.1,
4489 0.0, 1.0, 0.1
4491 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4492 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4495 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4497 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4498 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4499 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4500 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4501 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4502 if(FAILED(hr)) shader_20 = NULL;
4503 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4504 if(FAILED(hr)) shader_20_2 = NULL;
4505 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4506 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4508 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4509 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4510 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4511 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4512 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4513 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4515 hr = IDirect3DDevice9_BeginScene(device);
4516 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4517 if(SUCCEEDED(hr))
4519 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4520 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4522 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4524 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4525 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4526 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4527 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4529 if(shader_20) {
4530 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4531 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4532 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4533 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4536 if(shader_20_2) {
4537 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4538 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4540 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4543 hr = IDirect3DDevice9_EndScene(device);
4544 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4547 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4548 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4549 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4550 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4552 color = getPixelColor(device, 160, 360);
4553 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4554 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4555 color = getPixelColor(device, 480, 360);
4556 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4557 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4558 if(shader_20) {
4559 color = getPixelColor(device, 160, 120);
4560 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4561 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4563 if(shader_20_2) {
4564 color = getPixelColor(device, 480, 120);
4565 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4566 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4569 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4571 IDirect3DVertexDeclaration9_Release(decl);
4572 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4573 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4574 IDirect3DVertexShader9_Release(shader_11_2);
4575 IDirect3DVertexShader9_Release(shader_11);
4578 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4580 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4581 HRESULT hr;
4582 DWORD color;
4583 DWORD shader_code_11[] = {
4584 0xffff0101, /* ps_1_1 */
4585 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4586 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4587 0x0000ffff /* end */
4589 DWORD shader_code_12[] = {
4590 0xffff0102, /* ps_1_2 */
4591 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4592 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4593 0x0000ffff /* end */
4595 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4596 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4597 * During development of this test, 1.3 shaders were verified too
4599 DWORD shader_code_14[] = {
4600 0xffff0104, /* ps_1_4 */
4601 /* Try to make one constant local. It gets clamped too, although the binary contains
4602 * the bigger numbers
4604 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4605 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4606 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4607 0x0000ffff /* end */
4609 DWORD shader_code_20[] = {
4610 0xffff0200, /* ps_2_0 */
4611 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4612 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4613 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4614 0x0000ffff /* end */
4616 float quad1[] = {
4617 -1.0, -1.0, 0.1,
4618 0.0, -1.0, 0.1,
4619 -1.0, 0.0, 0.1,
4620 0.0, 0.0, 0.1
4622 float quad2[] = {
4623 0.0, -1.0, 0.1,
4624 1.0, -1.0, 0.1,
4625 0.0, 0.0, 0.1,
4626 1.0, 0.0, 0.1
4628 float quad3[] = {
4629 0.0, 0.0, 0.1,
4630 1.0, 0.0, 0.1,
4631 0.0, 1.0, 0.1,
4632 1.0, 1.0, 0.1
4634 float quad4[] = {
4635 -1.0, 0.0, 0.1,
4636 0.0, 0.0, 0.1,
4637 -1.0, 1.0, 0.1,
4638 0.0, 1.0, 0.1
4640 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4641 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4644 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4646 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4647 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4648 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4649 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4650 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4651 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4652 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4653 if(FAILED(hr)) shader_20 = NULL;
4655 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4656 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4657 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4658 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4659 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4660 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4662 hr = IDirect3DDevice9_BeginScene(device);
4663 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4664 if(SUCCEEDED(hr))
4666 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4668 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4669 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4671 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4672 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4674 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4676 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4679 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4681 if(shader_20) {
4682 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4683 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4685 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4688 hr = IDirect3DDevice9_EndScene(device);
4689 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4691 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4692 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4694 color = getPixelColor(device, 160, 360);
4695 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4696 "quad 1 has color %08x, expected 0x00808000\n", color);
4697 color = getPixelColor(device, 480, 360);
4698 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4699 "quad 2 has color %08x, expected 0x00808000\n", color);
4700 color = getPixelColor(device, 480, 120);
4701 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4702 "quad 3 has color %08x, expected 0x00808000\n", color);
4703 if(shader_20) {
4704 color = getPixelColor(device, 160, 120);
4705 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4706 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4708 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4709 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4711 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4712 IDirect3DPixelShader9_Release(shader_14);
4713 IDirect3DPixelShader9_Release(shader_12);
4714 IDirect3DPixelShader9_Release(shader_11);
4717 static void dp2add_ps_test(IDirect3DDevice9 *device)
4719 IDirect3DPixelShader9 *shader_dp2add = NULL;
4720 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4721 HRESULT hr;
4722 DWORD color;
4724 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4725 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4726 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4727 * r0 first.
4728 * The result here for the r,g,b components should be roughly 0.5:
4729 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4730 static const DWORD shader_code_dp2add[] = {
4731 0xffff0200, /* ps_2_0 */
4732 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4734 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4735 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4737 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4738 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4739 0x0000ffff /* end */
4742 /* Test the _sat modifier, too. Result here should be:
4743 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4744 * _SAT: ==> 1.0
4745 * ADD: (1.0 + -0.5) = 0.5
4747 static const DWORD shader_code_dp2add_sat[] = {
4748 0xffff0200, /* ps_2_0 */
4749 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4751 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4752 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4753 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4755 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4756 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4757 0x0000ffff /* end */
4760 const float quad[] = {
4761 -1.0, -1.0, 0.1,
4762 1.0, -1.0, 0.1,
4763 -1.0, 1.0, 0.1,
4764 1.0, 1.0, 0.1
4768 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4771 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4772 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4774 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4775 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4777 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4780 if (shader_dp2add) {
4782 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4783 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4785 hr = IDirect3DDevice9_BeginScene(device);
4786 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4787 if(SUCCEEDED(hr))
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792 hr = IDirect3DDevice9_EndScene(device);
4793 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4796 color = getPixelColor(device, 360, 240);
4797 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4798 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4800 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4803 IDirect3DPixelShader9_Release(shader_dp2add);
4804 } else {
4805 skip("dp2add shader creation failed\n");
4808 if (shader_dp2add_sat) {
4810 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4811 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4813 hr = IDirect3DDevice9_BeginScene(device);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4815 if(SUCCEEDED(hr))
4817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4818 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4820 hr = IDirect3DDevice9_EndScene(device);
4821 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4824 color = getPixelColor(device, 360, 240);
4825 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4826 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4828 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4829 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4831 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4832 } else {
4833 skip("dp2add shader creation failed\n");
4836 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4840 static void cnd_test(IDirect3DDevice9 *device)
4842 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4843 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4844 HRESULT hr;
4845 DWORD color;
4846 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4847 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4848 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4850 DWORD shader_code_11[] = {
4851 0xffff0101, /* ps_1_1 */
4852 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4853 0x00000040, 0xb00f0000, /* texcoord t0 */
4854 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4855 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4856 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4857 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4858 0x0000ffff /* end */
4860 DWORD shader_code_12[] = {
4861 0xffff0102, /* ps_1_2 */
4862 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4863 0x00000040, 0xb00f0000, /* texcoord t0 */
4864 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4865 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4866 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4867 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4868 0x0000ffff /* end */
4870 DWORD shader_code_13[] = {
4871 0xffff0103, /* ps_1_3 */
4872 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4873 0x00000040, 0xb00f0000, /* texcoord t0 */
4874 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4875 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4876 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4877 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4878 0x0000ffff /* end */
4880 DWORD shader_code_14[] = {
4881 0xffff0104, /* ps_1_3 */
4882 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4883 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4884 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4885 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4886 0x0000ffff /* end */
4889 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4890 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4891 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4892 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4893 * native CreatePixelShader returns an error.
4895 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4896 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4897 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4898 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4900 DWORD shader_code_11_coissue[] = {
4901 0xffff0101, /* ps_1_1 */
4902 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4903 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4904 0x00000040, 0xb00f0000, /* texcoord t0 */
4905 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4906 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4907 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4908 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4909 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4910 /* 0x40000000 = D3DSI_COISSUE */
4911 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4912 0x0000ffff /* end */
4914 DWORD shader_code_12_coissue[] = {
4915 0xffff0102, /* ps_1_2 */
4916 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4917 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4918 0x00000040, 0xb00f0000, /* texcoord t0 */
4919 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4920 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4921 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4922 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4923 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4924 /* 0x40000000 = D3DSI_COISSUE */
4925 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4926 0x0000ffff /* end */
4928 DWORD shader_code_13_coissue[] = {
4929 0xffff0103, /* ps_1_3 */
4930 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4931 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4932 0x00000040, 0xb00f0000, /* texcoord t0 */
4933 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4934 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4935 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4936 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4937 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4938 /* 0x40000000 = D3DSI_COISSUE */
4939 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4940 0x0000ffff /* end */
4942 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4943 * compare against 0.5
4945 DWORD shader_code_14_coissue[] = {
4946 0xffff0104, /* ps_1_4 */
4947 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4948 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4949 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4950 /* 0x40000000 = D3DSI_COISSUE */
4951 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4952 0x0000ffff /* end */
4954 float quad1[] = {
4955 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4956 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4957 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4958 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4960 float quad2[] = {
4961 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4962 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4963 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4964 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4966 float quad3[] = {
4967 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4968 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4969 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4970 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4972 float quad4[] = {
4973 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4974 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4975 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4976 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4978 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4979 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4980 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4981 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4983 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4984 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4986 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4987 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4988 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4989 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4990 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4992 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4993 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4994 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4995 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4996 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4998 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4999 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5000 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5001 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5003 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5005 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5006 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5007 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5008 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5010 hr = IDirect3DDevice9_BeginScene(device);
5011 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5012 if(SUCCEEDED(hr))
5014 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5015 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5016 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5017 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5019 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5020 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5021 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5022 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5024 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5025 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5027 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5029 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5030 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5032 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5034 hr = IDirect3DDevice9_EndScene(device);
5035 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5038 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5039 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5041 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5042 color = getPixelColor(device, 158, 118);
5043 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5044 color = getPixelColor(device, 162, 118);
5045 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5046 color = getPixelColor(device, 158, 122);
5047 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5048 color = getPixelColor(device, 162, 122);
5049 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5051 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5052 color = getPixelColor(device, 158, 358);
5053 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5054 color = getPixelColor(device, 162, 358);
5055 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5056 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5057 color = getPixelColor(device, 158, 362);
5058 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5059 color = getPixelColor(device, 162, 362);
5060 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5061 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5063 /* 1.2 shader */
5064 color = getPixelColor(device, 478, 358);
5065 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5066 color = getPixelColor(device, 482, 358);
5067 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5068 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5069 color = getPixelColor(device, 478, 362);
5070 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5071 color = getPixelColor(device, 482, 362);
5072 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5073 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5075 /* 1.3 shader */
5076 color = getPixelColor(device, 478, 118);
5077 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5078 color = getPixelColor(device, 482, 118);
5079 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5080 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5081 color = getPixelColor(device, 478, 122);
5082 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5083 color = getPixelColor(device, 482, 122);
5084 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5085 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5087 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5088 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5090 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5091 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5092 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5093 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5094 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5095 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5097 hr = IDirect3DDevice9_BeginScene(device);
5098 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5099 if(SUCCEEDED(hr))
5101 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5102 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5104 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5106 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5107 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5109 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5111 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5112 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5114 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5116 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5117 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5119 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5121 hr = IDirect3DDevice9_EndScene(device);
5122 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5125 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5126 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5128 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5129 * that we swapped the values in c1 and c2 to make the other tests return some color
5131 color = getPixelColor(device, 158, 118);
5132 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5133 color = getPixelColor(device, 162, 118);
5134 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5135 color = getPixelColor(device, 158, 122);
5136 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5137 color = getPixelColor(device, 162, 122);
5138 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5140 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5141 color = getPixelColor(device, 158, 358);
5142 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5143 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5144 color = getPixelColor(device, 162, 358);
5145 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5146 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5147 color = getPixelColor(device, 158, 362);
5148 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5149 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5150 color = getPixelColor(device, 162, 362);
5151 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5152 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5154 /* 1.2 shader */
5155 color = getPixelColor(device, 478, 358);
5156 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5157 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5158 color = getPixelColor(device, 482, 358);
5159 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5160 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5161 color = getPixelColor(device, 478, 362);
5162 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5163 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5164 color = getPixelColor(device, 482, 362);
5165 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5166 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5168 /* 1.3 shader */
5169 color = getPixelColor(device, 478, 118);
5170 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5171 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5172 color = getPixelColor(device, 482, 118);
5173 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5174 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5175 color = getPixelColor(device, 478, 122);
5176 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5177 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5178 color = getPixelColor(device, 482, 122);
5179 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5180 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5182 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5183 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5185 IDirect3DPixelShader9_Release(shader_14_coissue);
5186 IDirect3DPixelShader9_Release(shader_13_coissue);
5187 IDirect3DPixelShader9_Release(shader_12_coissue);
5188 IDirect3DPixelShader9_Release(shader_11_coissue);
5189 IDirect3DPixelShader9_Release(shader_14);
5190 IDirect3DPixelShader9_Release(shader_13);
5191 IDirect3DPixelShader9_Release(shader_12);
5192 IDirect3DPixelShader9_Release(shader_11);
5195 static void nested_loop_test(IDirect3DDevice9 *device) {
5196 const DWORD shader_code[] = {
5197 0xffff0300, /* ps_3_0 */
5198 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5199 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5200 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5201 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5202 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5203 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5204 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5205 0x0000001d, /* endloop */
5206 0x0000001d, /* endloop */
5207 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5208 0x0000ffff /* end */
5210 IDirect3DPixelShader9 *shader;
5211 HRESULT hr;
5212 DWORD color;
5213 const float quad[] = {
5214 -1.0, -1.0, 0.1,
5215 1.0, -1.0, 0.1,
5216 -1.0, 1.0, 0.1,
5217 1.0, 1.0, 0.1
5220 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5221 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5222 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5223 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5224 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5225 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5226 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5227 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5229 hr = IDirect3DDevice9_BeginScene(device);
5230 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5231 if(SUCCEEDED(hr))
5233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5234 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5235 hr = IDirect3DDevice9_EndScene(device);
5236 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5239 color = getPixelColor(device, 360, 240);
5240 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5241 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5243 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5244 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5246 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5248 IDirect3DPixelShader9_Release(shader);
5251 struct varying_test_struct
5253 const DWORD *shader_code;
5254 IDirect3DPixelShader9 *shader;
5255 DWORD color, color_rhw;
5256 const char *name;
5257 BOOL todo, todo_rhw;
5260 struct hugeVertex
5262 float pos_x, pos_y, pos_z, rhw;
5263 float weight_1, weight_2, weight_3, weight_4;
5264 float index_1, index_2, index_3, index_4;
5265 float normal_1, normal_2, normal_3, normal_4;
5266 float fog_1, fog_2, fog_3, fog_4;
5267 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5268 float tangent_1, tangent_2, tangent_3, tangent_4;
5269 float binormal_1, binormal_2, binormal_3, binormal_4;
5270 float depth_1, depth_2, depth_3, depth_4;
5271 DWORD diffuse, specular;
5274 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5275 /* dcl_position: fails to compile */
5276 const DWORD blendweight_code[] = {
5277 0xffff0300, /* ps_3_0 */
5278 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5279 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5280 0x0000ffff /* end */
5282 const DWORD blendindices_code[] = {
5283 0xffff0300, /* ps_3_0 */
5284 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5285 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5286 0x0000ffff /* end */
5288 const DWORD normal_code[] = {
5289 0xffff0300, /* ps_3_0 */
5290 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5291 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5292 0x0000ffff /* end */
5294 /* psize: fails? */
5295 const DWORD texcoord0_code[] = {
5296 0xffff0300, /* ps_3_0 */
5297 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5298 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5299 0x0000ffff /* end */
5301 const DWORD tangent_code[] = {
5302 0xffff0300, /* ps_3_0 */
5303 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5304 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5305 0x0000ffff /* end */
5307 const DWORD binormal_code[] = {
5308 0xffff0300, /* ps_3_0 */
5309 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5310 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5311 0x0000ffff /* end */
5313 /* tessfactor: fails */
5314 /* positiont: fails */
5315 const DWORD color_code[] = {
5316 0xffff0300, /* ps_3_0 */
5317 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5318 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5319 0x0000ffff /* end */
5321 const DWORD fog_code[] = {
5322 0xffff0300, /* ps_3_0 */
5323 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5324 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5325 0x0000ffff /* end */
5327 const DWORD depth_code[] = {
5328 0xffff0300, /* ps_3_0 */
5329 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5330 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5331 0x0000ffff /* end */
5333 const DWORD specular_code[] = {
5334 0xffff0300, /* ps_3_0 */
5335 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5336 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5337 0x0000ffff /* end */
5339 /* sample: fails */
5341 struct varying_test_struct tests[] = {
5342 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5343 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5344 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5345 /* Why does dx not forward the texcoord? */
5346 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5347 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5348 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5349 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5350 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5351 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5352 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5354 /* Declare a monster vertex type :-) */
5355 static const D3DVERTEXELEMENT9 decl_elements[] = {
5356 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5357 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5358 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5359 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5360 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5361 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5362 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5363 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5364 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5365 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5366 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5367 D3DDECL_END()
5369 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5370 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5371 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5372 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5373 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5374 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5375 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5376 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5377 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5378 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5379 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5380 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5381 D3DDECL_END()
5383 struct hugeVertex data[4] = {
5385 -1.0, -1.0, 0.1, 1.0,
5386 0.1, 0.1, 0.1, 0.1,
5387 0.2, 0.2, 0.2, 0.2,
5388 0.3, 0.3, 0.3, 0.3,
5389 0.4, 0.4, 0.4, 0.4,
5390 0.50, 0.55, 0.55, 0.55,
5391 0.6, 0.6, 0.6, 0.7,
5392 0.7, 0.7, 0.7, 0.6,
5393 0.8, 0.8, 0.8, 0.8,
5394 0xe6e6e6e6, /* 0.9 * 256 */
5395 0x224488ff /* Nothing special */
5398 1.0, -1.0, 0.1, 1.0,
5399 0.1, 0.1, 0.1, 0.1,
5400 0.2, 0.2, 0.2, 0.2,
5401 0.3, 0.3, 0.3, 0.3,
5402 0.4, 0.4, 0.4, 0.4,
5403 0.50, 0.55, 0.55, 0.55,
5404 0.6, 0.6, 0.6, 0.7,
5405 0.7, 0.7, 0.7, 0.6,
5406 0.8, 0.8, 0.8, 0.8,
5407 0xe6e6e6e6, /* 0.9 * 256 */
5408 0x224488ff /* Nothing special */
5411 -1.0, 1.0, 0.1, 1.0,
5412 0.1, 0.1, 0.1, 0.1,
5413 0.2, 0.2, 0.2, 0.2,
5414 0.3, 0.3, 0.3, 0.3,
5415 0.4, 0.4, 0.4, 0.4,
5416 0.50, 0.55, 0.55, 0.55,
5417 0.6, 0.6, 0.6, 0.7,
5418 0.7, 0.7, 0.7, 0.6,
5419 0.8, 0.8, 0.8, 0.8,
5420 0xe6e6e6e6, /* 0.9 * 256 */
5421 0x224488ff /* Nothing special */
5424 1.0, 1.0, 0.1, 1.0,
5425 0.1, 0.1, 0.1, 0.1,
5426 0.2, 0.2, 0.2, 0.2,
5427 0.3, 0.3, 0.3, 0.3,
5428 0.4, 0.4, 0.4, 0.4,
5429 0.50, 0.55, 0.55, 0.55,
5430 0.6, 0.6, 0.6, 0.7,
5431 0.7, 0.7, 0.7, 0.6,
5432 0.8, 0.8, 0.8, 0.8,
5433 0xe6e6e6e6, /* 0.9 * 256 */
5434 0x224488ff /* Nothing special */
5437 struct hugeVertex data2[4];
5438 IDirect3DVertexDeclaration9 *decl;
5439 IDirect3DVertexDeclaration9 *decl2;
5440 HRESULT hr;
5441 unsigned int i;
5442 DWORD color, r, g, b, r_e, g_e, b_e;
5443 BOOL drawok;
5445 memcpy(data2, data, sizeof(data2));
5446 data2[0].pos_x = 0; data2[0].pos_y = 0;
5447 data2[1].pos_x = 640; data2[1].pos_y = 0;
5448 data2[2].pos_x = 0; data2[2].pos_y = 480;
5449 data2[3].pos_x = 640; data2[3].pos_y = 480;
5451 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5452 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5453 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5454 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5455 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5456 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5458 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5460 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5461 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5462 tests[i].name, hr);
5465 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5468 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5470 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5471 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5473 hr = IDirect3DDevice9_BeginScene(device);
5474 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5475 drawok = FALSE;
5476 if(SUCCEEDED(hr))
5478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5479 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5480 drawok = SUCCEEDED(hr);
5481 hr = IDirect3DDevice9_EndScene(device);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5485 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5486 * the failure and do not check the color if it failed
5488 if(!drawok) {
5489 continue;
5492 color = getPixelColor(device, 360, 240);
5493 r = color & 0x00ff0000 >> 16;
5494 g = color & 0x0000ff00 >> 8;
5495 b = color & 0x000000ff;
5496 r_e = tests[i].color & 0x00ff0000 >> 16;
5497 g_e = tests[i].color & 0x0000ff00 >> 8;
5498 b_e = tests[i].color & 0x000000ff;
5500 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5501 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5503 if(tests[i].todo) {
5504 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5505 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5506 tests[i].name, color, tests[i].color);
5507 } else {
5508 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5509 "Test %s returned color 0x%08x, expected 0x%08x\n",
5510 tests[i].name, color, tests[i].color);
5514 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5515 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5516 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5518 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5519 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5521 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5524 hr = IDirect3DDevice9_BeginScene(device);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5526 if(SUCCEEDED(hr))
5528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5529 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5530 hr = IDirect3DDevice9_EndScene(device);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5534 color = getPixelColor(device, 360, 240);
5535 r = color & 0x00ff0000 >> 16;
5536 g = color & 0x0000ff00 >> 8;
5537 b = color & 0x000000ff;
5538 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5539 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5540 b_e = tests[i].color_rhw & 0x000000ff;
5542 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5543 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5545 if(tests[i].todo_rhw) {
5546 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5547 * pipeline
5549 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5550 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5551 tests[i].name, color, tests[i].color_rhw);
5552 } else {
5553 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5554 "Test %s returned color 0x%08x, expected 0x%08x\n",
5555 tests[i].name, color, tests[i].color_rhw);
5559 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5561 IDirect3DPixelShader9_Release(tests[i].shader);
5564 IDirect3DVertexDeclaration9_Release(decl2);
5565 IDirect3DVertexDeclaration9_Release(decl);
5568 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5569 static const DWORD ps_code[] = {
5570 0xffff0300, /* ps_3_0 */
5571 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5572 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5573 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5574 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5575 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5576 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5577 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5578 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5579 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5581 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5582 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5583 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5584 0x0000001d, /* endloop */
5585 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5586 0x0000ffff /* end */
5588 static const DWORD vs_1_code[] = {
5589 0xfffe0101, /* vs_1_1 */
5590 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5591 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5592 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5593 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5594 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5595 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5596 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5597 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5598 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5599 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5600 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5601 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5602 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5603 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5604 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5605 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5606 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5607 0x0000ffff
5609 DWORD vs_2_code[] = {
5610 0xfffe0200, /* vs_2_0 */
5611 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5612 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5613 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5614 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5615 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5616 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5617 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5618 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5619 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5620 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5621 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5622 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5623 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5624 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5625 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5626 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5627 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5628 0x0000ffff /* end */
5630 /* TODO: Define normal, tangent, blendweight and depth here */
5631 static const DWORD vs_3_code[] = {
5632 0xfffe0300, /* vs_3_0 */
5633 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5634 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5635 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5636 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5637 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5638 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5639 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5640 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5641 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5642 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5643 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5644 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5645 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5646 0x0000ffff /* end */
5648 float quad1[] = {
5649 -1.0, -1.0, 0.1,
5650 0.0, -1.0, 0.1,
5651 -1.0, 0.0, 0.1,
5652 0.0, 0.0, 0.1
5654 float quad2[] = {
5655 0.0, -1.0, 0.1,
5656 1.0, -1.0, 0.1,
5657 0.0, 0.0, 0.1,
5658 1.0, 0.0, 0.1
5660 float quad3[] = {
5661 -1.0, 0.0, 0.1,
5662 0.0, 0.0, 0.1,
5663 -1.0, 1.0, 0.1,
5664 0.0, 1.0, 0.1
5667 HRESULT hr;
5668 DWORD color;
5669 IDirect3DPixelShader9 *pixelshader = NULL;
5670 IDirect3DVertexShader9 *vs_1_shader = NULL;
5671 IDirect3DVertexShader9 *vs_2_shader = NULL;
5672 IDirect3DVertexShader9 *vs_3_shader = NULL;
5674 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5675 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5677 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5678 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5679 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5680 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5681 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5682 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5683 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5684 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5685 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5686 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5687 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5689 hr = IDirect3DDevice9_BeginScene(device);
5690 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5691 if(SUCCEEDED(hr))
5693 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5694 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5696 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5698 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5699 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5701 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5703 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5704 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5705 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5706 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5708 hr = IDirect3DDevice9_EndScene(device);
5709 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5712 color = getPixelColor(device, 160, 120);
5713 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5714 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5715 /* Accept two ways of oFog handling:
5717 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5718 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5720 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5721 * This happens with software vertex processing and on Intel cards
5723 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5724 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5726 color = getPixelColor(device, 160, 360);
5727 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5728 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5729 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5730 color = getPixelColor(device, 480, 360);
5731 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5732 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5733 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5735 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5736 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5738 /* cleanup */
5739 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5740 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5741 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5742 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5743 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5744 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5745 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5746 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5749 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5750 static const DWORD vs_code[] = {
5751 0xfffe0300, /* vs_3_0 */
5752 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5753 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5754 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5755 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5756 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5757 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5758 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5759 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5760 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5761 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5762 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5763 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5764 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5766 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5767 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5768 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5769 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5770 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5771 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5772 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5773 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5774 0x0000ffff /* end */
5776 static const DWORD ps_1_code[] = {
5777 0xffff0104, /* ps_1_4 */
5778 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5779 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5780 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5781 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5782 0x0000ffff /* end */
5784 static const DWORD ps_2_code[] = {
5785 0xffff0200, /* ps_2_0 */
5786 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5787 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5788 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5790 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5791 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5792 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5793 0x0000ffff /* end */
5795 static const DWORD ps_3_code[] = {
5796 0xffff0300, /* ps_3_0 */
5797 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5798 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5799 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5801 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5802 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5803 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5804 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5805 0x0000ffff /* end */
5808 float quad1[] = {
5809 -1.0, -1.0, 0.1,
5810 0.0, -1.0, 0.1,
5811 -1.0, 0.0, 0.1,
5812 0.0, 0.0, 0.1
5814 float quad2[] = {
5815 0.0, -1.0, 0.1,
5816 1.0, -1.0, 0.1,
5817 0.0, 0.0, 0.1,
5818 1.0, 0.0, 0.1
5820 float quad3[] = {
5821 -1.0, 0.0, 0.1,
5822 0.0, 0.0, 0.1,
5823 -1.0, 1.0, 0.1,
5824 0.0, 1.0, 0.1
5826 float quad4[] = {
5827 0.0, 0.0, 0.1,
5828 1.0, 0.0, 0.1,
5829 0.0, 1.0, 0.1,
5830 1.0, 1.0, 0.1
5833 HRESULT hr;
5834 DWORD color;
5835 IDirect3DVertexShader9 *vertexshader = NULL;
5836 IDirect3DPixelShader9 *ps_1_shader = NULL;
5837 IDirect3DPixelShader9 *ps_2_shader = NULL;
5838 IDirect3DPixelShader9 *ps_3_shader = NULL;
5839 IDirect3DTexture9 *texture = NULL;
5840 D3DLOCKED_RECT lr;
5841 unsigned int x, y;
5843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5844 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5846 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5847 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5848 if(FAILED(hr)) {
5849 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5850 return;
5852 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5853 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5854 for(y = 0; y < 512; y++) {
5855 for(x = 0; x < 512; x++) {
5856 double r_f = (double) x / (double) 512;
5857 double g_f = (double) y / (double) 512;
5858 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5859 unsigned short r = (unsigned short) (r_f * 65535.0);
5860 unsigned short g = (unsigned short) (g_f * 65535.0);
5861 dst[0] = r;
5862 dst[1] = g;
5863 dst[2] = 0;
5864 dst[3] = 65535;
5867 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5868 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5870 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5871 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5872 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5873 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5874 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5875 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5876 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5877 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5878 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5879 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5880 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5882 hr = IDirect3DDevice9_BeginScene(device);
5883 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5884 if(SUCCEEDED(hr))
5886 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5887 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5889 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5891 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5892 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5893 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5894 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5896 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5897 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5898 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5899 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5901 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5902 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5903 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5904 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5905 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5906 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5907 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5908 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5909 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5910 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5911 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5912 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5913 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5914 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5916 hr = IDirect3DDevice9_EndScene(device);
5917 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5920 color = getPixelColor(device, 160, 120);
5921 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5922 (color & 0x0000ff00) == 0x0000ff00 &&
5923 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5924 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5925 color = getPixelColor(device, 160, 360);
5926 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5927 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5928 (color & 0x000000ff) == 0x00000000,
5929 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5930 color = getPixelColor(device, 480, 360);
5931 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5932 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5933 (color & 0x000000ff) == 0x00000000,
5934 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5935 color = getPixelColor(device, 480, 160);
5936 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5937 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5938 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5939 (color & 0x000000ff) == 0x00000000),
5940 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5942 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5943 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5945 /* cleanup */
5946 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5947 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5948 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5949 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5950 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5951 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5952 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5953 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5954 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5955 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5956 if(texture) IDirect3DTexture9_Release(texture);
5959 static void test_compare_instructions(IDirect3DDevice9 *device)
5961 DWORD shader_sge_vec_code[] = {
5962 0xfffe0101, /* vs_1_1 */
5963 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5964 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5965 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5966 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5967 0x0000ffff /* end */
5969 DWORD shader_slt_vec_code[] = {
5970 0xfffe0101, /* vs_1_1 */
5971 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5972 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5973 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5974 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5975 0x0000ffff /* end */
5977 DWORD shader_sge_scalar_code[] = {
5978 0xfffe0101, /* vs_1_1 */
5979 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5980 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5981 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5982 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5983 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5984 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5985 0x0000ffff /* end */
5987 DWORD shader_slt_scalar_code[] = {
5988 0xfffe0101, /* vs_1_1 */
5989 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5990 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5991 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5992 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5993 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5994 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5995 0x0000ffff /* end */
5997 IDirect3DVertexShader9 *shader_sge_vec;
5998 IDirect3DVertexShader9 *shader_slt_vec;
5999 IDirect3DVertexShader9 *shader_sge_scalar;
6000 IDirect3DVertexShader9 *shader_slt_scalar;
6001 HRESULT hr, color;
6002 float quad1[] = {
6003 -1.0, -1.0, 0.1,
6004 0.0, -1.0, 0.1,
6005 -1.0, 0.0, 0.1,
6006 0.0, 0.0, 0.1
6008 float quad2[] = {
6009 0.0, -1.0, 0.1,
6010 1.0, -1.0, 0.1,
6011 0.0, 0.0, 0.1,
6012 1.0, 0.0, 0.1
6014 float quad3[] = {
6015 -1.0, 0.0, 0.1,
6016 0.0, 0.0, 0.1,
6017 -1.0, 1.0, 0.1,
6018 0.0, 1.0, 0.1
6020 float quad4[] = {
6021 0.0, 0.0, 0.1,
6022 1.0, 0.0, 0.1,
6023 0.0, 1.0, 0.1,
6024 1.0, 1.0, 0.1
6026 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6027 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6029 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6030 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6032 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6033 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6034 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6036 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6038 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6039 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6040 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6041 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6042 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6043 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6045 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6047 hr = IDirect3DDevice9_BeginScene(device);
6048 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6049 if(SUCCEEDED(hr))
6051 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6052 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6054 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6056 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6059 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6061 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6062 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6064 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6066 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6067 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6069 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6070 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6072 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6074 hr = IDirect3DDevice9_EndScene(device);
6075 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6078 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6079 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6081 color = getPixelColor(device, 160, 360);
6082 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6083 color = getPixelColor(device, 480, 360);
6084 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6085 color = getPixelColor(device, 160, 120);
6086 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6087 color = getPixelColor(device, 480, 160);
6088 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6090 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6091 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6093 IDirect3DVertexShader9_Release(shader_sge_vec);
6094 IDirect3DVertexShader9_Release(shader_slt_vec);
6095 IDirect3DVertexShader9_Release(shader_sge_scalar);
6096 IDirect3DVertexShader9_Release(shader_slt_scalar);
6099 static void test_vshader_input(IDirect3DDevice9 *device)
6101 DWORD swapped_shader_code_3[] = {
6102 0xfffe0300, /* vs_3_0 */
6103 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6104 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6105 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6106 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6107 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6108 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6109 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6110 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6111 0x0000ffff /* end */
6113 DWORD swapped_shader_code_1[] = {
6114 0xfffe0101, /* vs_1_1 */
6115 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6116 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6117 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6118 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6119 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6120 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6121 0x0000ffff /* end */
6123 DWORD swapped_shader_code_2[] = {
6124 0xfffe0200, /* vs_2_0 */
6125 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6126 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6127 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6128 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6129 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6130 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6131 0x0000ffff /* end */
6133 DWORD texcoord_color_shader_code_3[] = {
6134 0xfffe0300, /* vs_3_0 */
6135 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6136 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6137 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6138 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6139 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6140 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6141 0x0000ffff /* end */
6143 DWORD texcoord_color_shader_code_2[] = {
6144 0xfffe0200, /* vs_2_0 */
6145 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6146 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6147 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6148 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6149 0x0000ffff /* end */
6151 DWORD texcoord_color_shader_code_1[] = {
6152 0xfffe0101, /* vs_1_1 */
6153 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6154 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6155 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6156 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6157 0x0000ffff /* end */
6159 DWORD color_color_shader_code_3[] = {
6160 0xfffe0300, /* vs_3_0 */
6161 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6162 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6163 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6164 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6165 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6166 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6167 0x0000ffff /* end */
6169 DWORD color_color_shader_code_2[] = {
6170 0xfffe0200, /* vs_2_0 */
6171 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6172 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6173 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6174 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6175 0x0000ffff /* end */
6177 DWORD color_color_shader_code_1[] = {
6178 0xfffe0101, /* vs_1_1 */
6179 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6180 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6181 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6182 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6183 0x0000ffff /* end */
6185 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6186 HRESULT hr;
6187 DWORD color;
6188 float quad1[] = {
6189 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6190 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6191 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6192 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6194 float quad2[] = {
6195 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6196 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6197 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6198 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6200 float quad3[] = {
6201 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6202 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6203 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6204 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6206 float quad4[] = {
6207 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6208 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6209 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6210 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6212 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6213 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6214 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6215 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6216 D3DDECL_END()
6218 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6219 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6220 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6221 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6222 D3DDECL_END()
6224 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6225 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6226 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6227 D3DDECL_END()
6229 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6230 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6231 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6232 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6233 D3DDECL_END()
6235 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6236 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6237 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6238 D3DDECL_END()
6240 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6241 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6242 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6243 D3DDECL_END()
6245 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6246 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6247 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6248 D3DDECL_END()
6250 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6251 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6252 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6253 D3DDECL_END()
6255 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6256 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6257 unsigned int i;
6258 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6259 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6261 struct vertex quad1_color[] = {
6262 {-1.0, -1.0, 0.1, 0x00ff8040},
6263 { 0.0, -1.0, 0.1, 0x00ff8040},
6264 {-1.0, 0.0, 0.1, 0x00ff8040},
6265 { 0.0, 0.0, 0.1, 0x00ff8040}
6267 struct vertex quad2_color[] = {
6268 { 0.0, -1.0, 0.1, 0x00ff8040},
6269 { 1.0, -1.0, 0.1, 0x00ff8040},
6270 { 0.0, 0.0, 0.1, 0x00ff8040},
6271 { 1.0, 0.0, 0.1, 0x00ff8040}
6273 struct vertex quad3_color[] = {
6274 {-1.0, 0.0, 0.1, 0x00ff8040},
6275 { 0.0, 0.0, 0.1, 0x00ff8040},
6276 {-1.0, 1.0, 0.1, 0x00ff8040},
6277 { 0.0, 1.0, 0.1, 0x00ff8040}
6279 float quad4_color[] = {
6280 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6281 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6282 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6283 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6286 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6287 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6288 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6290 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6291 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6292 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6293 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6295 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6296 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6297 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6299 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6301 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6302 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6304 for(i = 1; i <= 3; i++) {
6305 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6306 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6307 if(i == 3) {
6308 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6309 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6310 } else if(i == 2){
6311 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6312 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6313 } else if(i == 1) {
6314 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6318 hr = IDirect3DDevice9_BeginScene(device);
6319 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6320 if(SUCCEEDED(hr))
6322 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6323 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6325 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6326 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6328 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6330 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6331 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6333 if(i == 3 || i == 2) {
6334 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6335 } else if(i == 1) {
6336 /* Succeeds or fails, depending on SW or HW vertex processing */
6337 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6340 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6341 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6342 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6343 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6345 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6346 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6348 if(i == 3 || i == 2) {
6349 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6350 } else if(i == 1) {
6351 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6354 hr = IDirect3DDevice9_EndScene(device);
6355 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6358 if(i == 3 || i == 2) {
6359 color = getPixelColor(device, 160, 360);
6360 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6361 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6363 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6364 color = getPixelColor(device, 480, 360);
6365 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6366 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6367 color = getPixelColor(device, 160, 120);
6368 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6369 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6370 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6372 color = getPixelColor(device, 480, 160);
6373 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6374 } else if(i == 1) {
6375 color = getPixelColor(device, 160, 360);
6376 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6377 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6378 color = getPixelColor(device, 480, 360);
6379 /* Accept the clear color as well in this case, since SW VP returns an error */
6380 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6381 color = getPixelColor(device, 160, 120);
6382 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6383 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6384 color = getPixelColor(device, 480, 160);
6385 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6389 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6391 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6392 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6394 /* Now find out if the whole streams are re-read, or just the last active value for the
6395 * vertices is used.
6397 hr = IDirect3DDevice9_BeginScene(device);
6398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6399 if(SUCCEEDED(hr))
6401 float quad1_modified[] = {
6402 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6403 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6404 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6405 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6407 float quad2_modified[] = {
6408 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6409 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6410 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6411 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6414 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6415 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6420 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6422 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6423 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6425 if(i == 3 || i == 2) {
6426 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6427 } else if(i == 1) {
6428 /* Succeeds or fails, depending on SW or HW vertex processing */
6429 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6432 hr = IDirect3DDevice9_EndScene(device);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6436 color = getPixelColor(device, 480, 350);
6437 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6438 * as well.
6440 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6441 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6442 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6443 * refrast's result.
6445 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6447 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6448 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6450 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6451 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6453 IDirect3DDevice9_SetVertexShader(device, NULL);
6454 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6456 IDirect3DVertexShader9_Release(swapped_shader);
6459 for(i = 1; i <= 3; i++) {
6460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6461 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6462 if(i == 3) {
6463 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6464 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6465 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6466 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6467 } else if(i == 2){
6468 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6469 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6470 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6471 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6472 } else if(i == 1) {
6473 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6474 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6475 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6476 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6479 hr = IDirect3DDevice9_BeginScene(device);
6480 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6481 if(SUCCEEDED(hr))
6483 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6484 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6485 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6486 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6488 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6490 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6491 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6493 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6494 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6495 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6496 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6497 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6498 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6500 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6501 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6502 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6503 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6505 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6507 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6508 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6510 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6512 hr = IDirect3DDevice9_EndScene(device);
6513 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6515 IDirect3DDevice9_SetVertexShader(device, NULL);
6516 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6518 color = getPixelColor(device, 160, 360);
6519 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6520 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6521 color = getPixelColor(device, 480, 360);
6522 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6523 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6524 color = getPixelColor(device, 160, 120);
6525 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6526 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6527 color = getPixelColor(device, 480, 160);
6528 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6529 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6531 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6532 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6534 IDirect3DVertexShader9_Release(texcoord_color_shader);
6535 IDirect3DVertexShader9_Release(color_color_shader);
6538 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6539 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6540 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6541 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6543 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6544 IDirect3DVertexDeclaration9_Release(decl_color_color);
6545 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6546 IDirect3DVertexDeclaration9_Release(decl_color_float);
6549 static void srgbtexture_test(IDirect3DDevice9 *device)
6551 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6552 * texture stage state to render a quad using that texture. The resulting
6553 * color components should be 0x36 (~ 0.21), per this formula:
6554 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6555 * This is true where srgb_color > 0.04045.
6557 IDirect3D9 *d3d = NULL;
6558 HRESULT hr;
6559 LPDIRECT3DTEXTURE9 texture = NULL;
6560 LPDIRECT3DSURFACE9 surface = NULL;
6561 D3DLOCKED_RECT lr;
6562 DWORD color;
6563 float quad[] = {
6564 -1.0, 1.0, 0.0, 0.0, 0.0,
6565 1.0, 1.0, 0.0, 1.0, 0.0,
6566 -1.0, -1.0, 0.0, 0.0, 1.0,
6567 1.0, -1.0, 0.0, 1.0, 1.0,
6571 memset(&lr, 0, sizeof(lr));
6572 IDirect3DDevice9_GetDirect3D(device, &d3d);
6573 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6574 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6575 D3DFMT_A8R8G8B8) != D3D_OK) {
6576 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6577 goto out;
6580 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6581 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6582 &texture, NULL);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6584 if(!texture) {
6585 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6586 goto out;
6588 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6589 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6591 fill_surface(surface, 0xff7f7f7f);
6592 IDirect3DSurface9_Release(surface);
6594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6595 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6596 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6597 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6599 hr = IDirect3DDevice9_BeginScene(device);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6601 if(SUCCEEDED(hr))
6603 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6604 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6606 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6610 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6611 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6613 hr = IDirect3DDevice9_EndScene(device);
6614 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6617 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6618 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6619 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6620 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6622 color = getPixelColor(device, 320, 240);
6623 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6626 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6628 out:
6629 if(texture) IDirect3DTexture9_Release(texture);
6630 IDirect3D9_Release(d3d);
6633 static void shademode_test(IDirect3DDevice9 *device)
6635 /* Render a quad and try all of the different fixed function shading models. */
6636 HRESULT hr;
6637 DWORD color0, color1;
6638 DWORD color0_gouraud = 0, color1_gouraud = 0;
6639 DWORD shademode = D3DSHADE_FLAT;
6640 DWORD primtype = D3DPT_TRIANGLESTRIP;
6641 LPVOID data = NULL;
6642 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6643 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6644 UINT i, j;
6645 struct vertex quad_strip[] =
6647 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6648 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6649 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6650 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6652 struct vertex quad_list[] =
6654 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6655 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6656 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6658 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6659 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6660 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6663 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6664 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6665 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6666 if (FAILED(hr)) goto bail;
6668 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6669 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6670 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6671 if (FAILED(hr)) goto bail;
6673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6674 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6676 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6679 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6680 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6681 memcpy(data, quad_strip, sizeof(quad_strip));
6682 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6683 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6685 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6686 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6687 memcpy(data, quad_list, sizeof(quad_list));
6688 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6689 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6691 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6692 * the color fixups we have to do for FLAT shading will be dependent on that. */
6693 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6694 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6696 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6697 for (j=0; j<2; j++) {
6699 /* Inner loop just changes the D3DRS_SHADEMODE */
6700 for (i=0; i<3; i++) {
6701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6705 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6707 hr = IDirect3DDevice9_BeginScene(device);
6708 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6709 if(SUCCEEDED(hr))
6711 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6714 hr = IDirect3DDevice9_EndScene(device);
6715 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6718 /* Sample two spots from the output */
6719 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6720 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6721 switch(shademode) {
6722 case D3DSHADE_FLAT:
6723 /* Should take the color of the first vertex of each triangle */
6724 if (0)
6726 /* This test depends on EXT_provoking_vertex being
6727 * available. This extension is currently (20090810)
6728 * not common enough to let the test fail if it isn't
6729 * present. */
6730 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6731 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6733 shademode = D3DSHADE_GOURAUD;
6734 break;
6735 case D3DSHADE_GOURAUD:
6736 /* Should be an interpolated blend */
6738 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6739 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6740 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6741 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6743 color0_gouraud = color0;
6744 color1_gouraud = color1;
6746 shademode = D3DSHADE_PHONG;
6747 break;
6748 case D3DSHADE_PHONG:
6749 /* Should be the same as GOURAUD, since no hardware implements this */
6750 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6751 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6752 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6753 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6755 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6756 color0_gouraud, color0);
6757 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6758 color1_gouraud, color1);
6759 break;
6763 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6764 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6766 /* Now, do it all over again with a TRIANGLELIST */
6767 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6768 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6769 primtype = D3DPT_TRIANGLELIST;
6770 shademode = D3DSHADE_FLAT;
6773 bail:
6774 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6775 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6777 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6779 if (vb_strip)
6780 IDirect3DVertexBuffer9_Release(vb_strip);
6781 if (vb_list)
6782 IDirect3DVertexBuffer9_Release(vb_list);
6786 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6788 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6789 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6790 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6791 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6792 * 0.73
6794 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6795 * so use shaders for this task
6797 IDirect3DPixelShader9 *pshader;
6798 IDirect3DVertexShader9 *vshader;
6799 IDirect3D9 *d3d;
6800 DWORD vshader_code[] = {
6801 0xfffe0101, /* vs_1_1 */
6802 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6803 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6804 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6805 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6806 0x0000ffff /* end */
6808 DWORD pshader_code[] = {
6809 0xffff0101, /* ps_1_1 */
6810 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6811 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6812 0x0000ffff /* end */
6814 const float quad[] = {
6815 -1.0, -1.0, 0.1,
6816 1.0, -1.0, 0.1,
6817 -1.0, 1.0, 0.1,
6818 1.0, 1.0, 0.1
6820 HRESULT hr;
6821 D3DCOLOR color;
6823 IDirect3DDevice9_GetDirect3D(device, &d3d);
6824 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6825 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6826 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6827 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6828 * works
6830 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6831 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6832 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6833 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6834 IDirect3D9_Release(d3d);
6835 return;
6837 IDirect3D9_Release(d3d);
6839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6840 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6843 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6847 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6849 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6851 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6853 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6854 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6855 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6856 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6857 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6858 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6859 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6860 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6861 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6864 hr = IDirect3DDevice9_BeginScene(device);
6865 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6866 if(SUCCEEDED(hr)) {
6867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6868 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6870 hr = IDirect3DDevice9_EndScene(device);
6871 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6874 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6875 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6876 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6877 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6878 IDirect3DPixelShader9_Release(pshader);
6879 IDirect3DVertexShader9_Release(vshader);
6881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6882 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6886 color = getPixelColor(device, 160, 360);
6887 ok(color_match(color, 0x00808080, 1),
6888 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6889 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6890 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6893 static void alpha_test(IDirect3DDevice9 *device)
6895 HRESULT hr;
6896 IDirect3DTexture9 *offscreenTexture;
6897 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6898 DWORD color;
6900 struct vertex quad1[] =
6902 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6903 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6904 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6905 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6907 struct vertex quad2[] =
6909 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6910 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6911 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6912 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6914 static const float composite_quad[][5] = {
6915 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6916 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6917 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6918 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6921 /* Clear the render target with alpha = 0.5 */
6922 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6923 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6925 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6926 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6928 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6929 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6930 if(!backbuffer) {
6931 goto out;
6934 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6935 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6936 if(!offscreen) {
6937 goto out;
6940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6941 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6943 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6944 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6945 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6946 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6947 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6948 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6949 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6950 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6952 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6955 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6956 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6958 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6962 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6964 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6966 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6967 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6970 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6971 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6973 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6974 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6975 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6976 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6977 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6979 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6982 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6983 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6984 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6986 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6989 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6991 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6993 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6995 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6996 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6998 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6999 * Disable alpha blending for the final composition
7001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7002 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7004 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7006 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7007 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7008 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7009 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7010 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7011 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7013 hr = IDirect3DDevice9_EndScene(device);
7014 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7017 color = getPixelColor(device, 160, 360);
7018 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7019 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7021 color = getPixelColor(device, 160, 120);
7022 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7023 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7025 color = getPixelColor(device, 480, 360);
7026 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7027 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7029 color = getPixelColor(device, 480, 120);
7030 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7031 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7033 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7035 out:
7036 /* restore things */
7037 if(backbuffer) {
7038 IDirect3DSurface9_Release(backbuffer);
7040 if(offscreenTexture) {
7041 IDirect3DTexture9_Release(offscreenTexture);
7043 if(offscreen) {
7044 IDirect3DSurface9_Release(offscreen);
7048 struct vertex_shortcolor {
7049 float x, y, z;
7050 unsigned short r, g, b, a;
7052 struct vertex_floatcolor {
7053 float x, y, z;
7054 float r, g, b, a;
7057 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7059 HRESULT hr;
7060 BOOL s_ok, ub_ok, f_ok;
7061 DWORD color, size, i;
7062 void *data;
7063 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7064 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7065 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7066 D3DDECL_END()
7068 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7069 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7070 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7071 D3DDECL_END()
7073 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7074 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7075 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7076 D3DDECL_END()
7078 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7079 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7080 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7081 D3DDECL_END()
7083 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7084 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7085 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7086 D3DDECL_END()
7088 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7089 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7090 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7091 D3DDECL_END()
7093 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7094 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7095 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7096 D3DDECL_END()
7098 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7099 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7100 IDirect3DVertexBuffer9 *vb, *vb2;
7101 struct vertex quad1[] = /* D3DCOLOR */
7103 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7104 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7105 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7106 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7108 struct vertex quad2[] = /* UBYTE4N */
7110 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7111 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7112 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7113 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7115 struct vertex_shortcolor quad3[] = /* short */
7117 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7118 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7119 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7120 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7122 struct vertex_floatcolor quad4[] =
7124 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7125 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7126 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7127 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7129 DWORD colors[] = {
7130 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7131 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7132 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7133 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7134 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7135 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7136 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7137 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7138 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7139 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7140 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7141 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7142 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7143 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7144 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7145 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7147 float quads[] = {
7148 -1.0, -1.0, 0.1,
7149 -1.0, 0.0, 0.1,
7150 0.0, -1.0, 0.1,
7151 0.0, 0.0, 0.1,
7153 0.0, -1.0, 0.1,
7154 0.0, 0.0, 0.1,
7155 1.0, -1.0, 0.1,
7156 1.0, 0.0, 0.1,
7158 0.0, 0.0, 0.1,
7159 0.0, 1.0, 0.1,
7160 1.0, 0.0, 0.1,
7161 1.0, 1.0, 0.1,
7163 -1.0, 0.0, 0.1,
7164 -1.0, 1.0, 0.1,
7165 0.0, 0.0, 0.1,
7166 0.0, 1.0, 0.1
7168 struct tvertex quad_transformed[] = {
7169 { 90, 110, 0.1, 2.0, 0x00ffff00},
7170 { 570, 110, 0.1, 2.0, 0x00ffff00},
7171 { 90, 300, 0.1, 2.0, 0x00ffff00},
7172 { 570, 300, 0.1, 2.0, 0x00ffff00}
7174 D3DCAPS9 caps;
7176 memset(&caps, 0, sizeof(caps));
7177 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7178 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7180 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7181 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7183 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7184 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7185 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7186 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7187 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7188 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7189 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7190 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7191 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7192 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7193 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7194 } else {
7195 trace("D3DDTCAPS_UBYTE4N not supported\n");
7196 dcl_ubyte_2 = NULL;
7197 dcl_ubyte = NULL;
7199 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7200 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7201 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7202 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7204 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7205 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7206 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7207 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7209 hr = IDirect3DDevice9_BeginScene(device);
7210 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7211 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7212 if(SUCCEEDED(hr)) {
7213 if(dcl_color) {
7214 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7217 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7220 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7221 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7222 * using software vertex processing. Doh!
7224 if(dcl_ubyte) {
7225 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7228 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7229 ub_ok = SUCCEEDED(hr);
7232 if(dcl_short) {
7233 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7236 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7237 s_ok = SUCCEEDED(hr);
7240 if(dcl_float) {
7241 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7244 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7245 f_ok = SUCCEEDED(hr);
7248 hr = IDirect3DDevice9_EndScene(device);
7249 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7252 if(dcl_short) {
7253 color = getPixelColor(device, 480, 360);
7254 ok(color == 0x000000ff || !s_ok,
7255 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7257 if(dcl_ubyte) {
7258 color = getPixelColor(device, 160, 120);
7259 ok(color == 0x0000ffff || !ub_ok,
7260 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7262 if(dcl_color) {
7263 color = getPixelColor(device, 160, 360);
7264 ok(color == 0x00ffff00,
7265 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7267 if(dcl_float) {
7268 color = getPixelColor(device, 480, 120);
7269 ok(color == 0x00ff0000 || !f_ok,
7270 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7272 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7274 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7275 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7276 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7277 * whether the immediate mode code works
7279 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7280 hr = IDirect3DDevice9_BeginScene(device);
7281 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7282 if(SUCCEEDED(hr)) {
7283 if(dcl_color) {
7284 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7285 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7286 memcpy(data, quad1, sizeof(quad1));
7287 hr = IDirect3DVertexBuffer9_Unlock(vb);
7288 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7289 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7290 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7291 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7292 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7293 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7294 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7297 if(dcl_ubyte) {
7298 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7299 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7300 memcpy(data, quad2, sizeof(quad2));
7301 hr = IDirect3DVertexBuffer9_Unlock(vb);
7302 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7303 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7305 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7306 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7307 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7308 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7309 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7310 ub_ok = SUCCEEDED(hr);
7313 if(dcl_short) {
7314 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7315 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7316 memcpy(data, quad3, sizeof(quad3));
7317 hr = IDirect3DVertexBuffer9_Unlock(vb);
7318 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7319 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7321 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7322 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7323 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7324 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7325 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7326 s_ok = SUCCEEDED(hr);
7329 if(dcl_float) {
7330 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7331 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7332 memcpy(data, quad4, sizeof(quad4));
7333 hr = IDirect3DVertexBuffer9_Unlock(vb);
7334 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7335 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7336 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7337 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7338 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7339 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7340 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7341 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7342 f_ok = SUCCEEDED(hr);
7345 hr = IDirect3DDevice9_EndScene(device);
7346 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7349 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7350 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7351 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7354 if(dcl_short) {
7355 color = getPixelColor(device, 480, 360);
7356 ok(color == 0x000000ff || !s_ok,
7357 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7359 if(dcl_ubyte) {
7360 color = getPixelColor(device, 160, 120);
7361 ok(color == 0x0000ffff || !ub_ok,
7362 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7364 if(dcl_color) {
7365 color = getPixelColor(device, 160, 360);
7366 ok(color == 0x00ffff00,
7367 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7369 if(dcl_float) {
7370 color = getPixelColor(device, 480, 120);
7371 ok(color == 0x00ff0000 || !f_ok,
7372 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7374 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7376 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7377 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7379 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7380 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7381 memcpy(data, quad_transformed, sizeof(quad_transformed));
7382 hr = IDirect3DVertexBuffer9_Unlock(vb);
7383 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7385 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7386 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7388 hr = IDirect3DDevice9_BeginScene(device);
7389 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7390 if(SUCCEEDED(hr)) {
7391 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7392 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7393 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7394 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7396 hr = IDirect3DDevice9_EndScene(device);
7397 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7400 color = getPixelColor(device, 88, 108);
7401 ok(color == 0x000000ff,
7402 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7403 color = getPixelColor(device, 92, 108);
7404 ok(color == 0x000000ff,
7405 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7406 color = getPixelColor(device, 88, 112);
7407 ok(color == 0x000000ff,
7408 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7409 color = getPixelColor(device, 92, 112);
7410 ok(color == 0x00ffff00,
7411 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7413 color = getPixelColor(device, 568, 108);
7414 ok(color == 0x000000ff,
7415 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7416 color = getPixelColor(device, 572, 108);
7417 ok(color == 0x000000ff,
7418 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7419 color = getPixelColor(device, 568, 112);
7420 ok(color == 0x00ffff00,
7421 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7422 color = getPixelColor(device, 572, 112);
7423 ok(color == 0x000000ff,
7424 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7426 color = getPixelColor(device, 88, 298);
7427 ok(color == 0x000000ff,
7428 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7429 color = getPixelColor(device, 92, 298);
7430 ok(color == 0x00ffff00,
7431 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7432 color = getPixelColor(device, 88, 302);
7433 ok(color == 0x000000ff,
7434 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7435 color = getPixelColor(device, 92, 302);
7436 ok(color == 0x000000ff,
7437 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7439 color = getPixelColor(device, 568, 298);
7440 ok(color == 0x00ffff00,
7441 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7442 color = getPixelColor(device, 572, 298);
7443 ok(color == 0x000000ff,
7444 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7445 color = getPixelColor(device, 568, 302);
7446 ok(color == 0x000000ff,
7447 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7448 color = getPixelColor(device, 572, 302);
7449 ok(color == 0x000000ff,
7450 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7452 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7454 /* This test is pointless without those two declarations: */
7455 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7456 skip("color-ubyte switching test declarations aren't supported\n");
7457 goto out;
7460 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7461 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7462 memcpy(data, quads, sizeof(quads));
7463 hr = IDirect3DVertexBuffer9_Unlock(vb);
7464 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7465 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7466 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7467 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7468 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7469 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7470 memcpy(data, colors, sizeof(colors));
7471 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7472 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7474 for(i = 0; i < 2; i++) {
7475 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7476 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7478 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7479 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7480 if(i == 0) {
7481 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7482 } else {
7483 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7485 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7487 hr = IDirect3DDevice9_BeginScene(device);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7489 ub_ok = FALSE;
7490 if(SUCCEEDED(hr)) {
7491 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7493 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7494 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7495 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7496 ub_ok = SUCCEEDED(hr);
7498 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7500 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7501 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7503 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7504 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7505 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7506 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7507 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7508 ub_ok = (SUCCEEDED(hr) && ub_ok);
7510 hr = IDirect3DDevice9_EndScene(device);
7511 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7514 if(i == 0) {
7515 color = getPixelColor(device, 480, 360);
7516 ok(color == 0x00ff0000,
7517 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7518 color = getPixelColor(device, 160, 120);
7519 ok(color == 0x00ffffff,
7520 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7521 color = getPixelColor(device, 160, 360);
7522 ok(color == 0x000000ff || !ub_ok,
7523 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7524 color = getPixelColor(device, 480, 120);
7525 ok(color == 0x000000ff || !ub_ok,
7526 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7527 } else {
7528 color = getPixelColor(device, 480, 360);
7529 ok(color == 0x000000ff,
7530 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7531 color = getPixelColor(device, 160, 120);
7532 ok(color == 0x00ffffff,
7533 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7534 color = getPixelColor(device, 160, 360);
7535 ok(color == 0x00ff0000 || !ub_ok,
7536 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7537 color = getPixelColor(device, 480, 120);
7538 ok(color == 0x00ff0000 || !ub_ok,
7539 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7541 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7544 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7545 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7546 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7547 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7548 IDirect3DVertexBuffer9_Release(vb2);
7550 out:
7551 IDirect3DVertexBuffer9_Release(vb);
7552 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7553 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7554 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7555 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7556 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7557 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7558 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7561 struct vertex_float16color {
7562 float x, y, z;
7563 DWORD c1, c2;
7566 static void test_vshader_float16(IDirect3DDevice9 *device)
7568 HRESULT hr;
7569 DWORD color;
7570 void *data;
7571 static const D3DVERTEXELEMENT9 decl_elements[] = {
7572 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7573 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7574 D3DDECL_END()
7576 IDirect3DVertexDeclaration9 *vdecl = NULL;
7577 IDirect3DVertexBuffer9 *buffer = NULL;
7578 IDirect3DVertexShader9 *shader;
7579 DWORD shader_code[] = {
7580 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7581 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7582 0x90e40001, 0x0000ffff
7584 struct vertex_float16color quad[] = {
7585 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7586 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7587 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7588 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7590 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7591 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7592 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7593 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7595 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7596 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7597 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7598 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7600 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7601 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7602 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7603 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7607 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7609 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7610 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7611 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7612 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7613 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7614 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7616 hr = IDirect3DDevice9_BeginScene(device);
7617 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7618 if(SUCCEEDED(hr)) {
7619 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7620 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7622 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7623 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7624 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7626 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7628 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7630 hr = IDirect3DDevice9_EndScene(device);
7631 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7633 color = getPixelColor(device, 480, 360);
7634 ok(color == 0x00ff0000,
7635 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7636 color = getPixelColor(device, 160, 120);
7637 ok(color == 0x00000000,
7638 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7639 color = getPixelColor(device, 160, 360);
7640 ok(color == 0x0000ff00,
7641 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7642 color = getPixelColor(device, 480, 120);
7643 ok(color == 0x000000ff,
7644 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7645 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7648 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7650 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7651 D3DPOOL_MANAGED, &buffer, NULL);
7652 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7653 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7654 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7655 memcpy(data, quad, sizeof(quad));
7656 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7657 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7658 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7659 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7661 hr = IDirect3DDevice9_BeginScene(device);
7662 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7663 if(SUCCEEDED(hr)) {
7664 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7665 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7666 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7667 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7668 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7669 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7670 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7673 hr = IDirect3DDevice9_EndScene(device);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7677 color = getPixelColor(device, 480, 360);
7678 ok(color == 0x00ff0000,
7679 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7680 color = getPixelColor(device, 160, 120);
7681 ok(color == 0x00000000,
7682 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7683 color = getPixelColor(device, 160, 360);
7684 ok(color == 0x0000ff00,
7685 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7686 color = getPixelColor(device, 480, 120);
7687 ok(color == 0x000000ff,
7688 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7689 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7691 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7692 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7693 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7694 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7695 IDirect3DDevice9_SetVertexShader(device, NULL);
7696 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7698 IDirect3DVertexDeclaration9_Release(vdecl);
7699 IDirect3DVertexShader9_Release(shader);
7700 IDirect3DVertexBuffer9_Release(buffer);
7703 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7705 D3DCAPS9 caps;
7706 IDirect3DTexture9 *texture;
7707 HRESULT hr;
7708 D3DLOCKED_RECT rect;
7709 unsigned int x, y;
7710 DWORD *dst, color;
7711 const float quad[] = {
7712 -1.0, -1.0, 0.1, -0.2, -0.2,
7713 1.0, -1.0, 0.1, 1.2, -0.2,
7714 -1.0, 1.0, 0.1, -0.2, 1.2,
7715 1.0, 1.0, 0.1, 1.2, 1.2
7717 memset(&caps, 0, sizeof(caps));
7719 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7720 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7721 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7722 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7723 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7724 "Card has conditional NP2 support without power of two restriction set\n");
7725 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7726 return;
7727 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7728 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7729 return;
7732 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7733 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7735 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7736 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7738 memset(&rect, 0, sizeof(rect));
7739 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7740 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7741 for(y = 0; y < 10; y++) {
7742 for(x = 0; x < 10; x++) {
7743 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7744 if(x == 0 || x == 9 || y == 0 || y == 9) {
7745 *dst = 0x00ff0000;
7746 } else {
7747 *dst = 0x000000ff;
7751 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7752 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7754 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7755 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7757 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7758 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7759 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7760 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7761 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7763 hr = IDirect3DDevice9_BeginScene(device);
7764 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7765 if(SUCCEEDED(hr)) {
7766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7767 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7769 hr = IDirect3DDevice9_EndScene(device);
7770 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7773 color = getPixelColor(device, 1, 1);
7774 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7775 color = getPixelColor(device, 639, 479);
7776 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7778 color = getPixelColor(device, 135, 101);
7779 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7780 color = getPixelColor(device, 140, 101);
7781 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7782 color = getPixelColor(device, 135, 105);
7783 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7784 color = getPixelColor(device, 140, 105);
7785 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7787 color = getPixelColor(device, 135, 376);
7788 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7789 color = getPixelColor(device, 140, 376);
7790 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7791 color = getPixelColor(device, 135, 379);
7792 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7793 color = getPixelColor(device, 140, 379);
7794 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7796 color = getPixelColor(device, 500, 101);
7797 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7798 color = getPixelColor(device, 504, 101);
7799 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7800 color = getPixelColor(device, 500, 105);
7801 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7802 color = getPixelColor(device, 504, 105);
7803 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7805 color = getPixelColor(device, 500, 376);
7806 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7807 color = getPixelColor(device, 504, 376);
7808 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7809 color = getPixelColor(device, 500, 380);
7810 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7811 color = getPixelColor(device, 504, 380);
7812 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7814 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7816 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7817 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7818 IDirect3DTexture9_Release(texture);
7821 static void vFace_register_test(IDirect3DDevice9 *device)
7823 HRESULT hr;
7824 DWORD color;
7825 const DWORD shader_code[] = {
7826 0xffff0300, /* ps_3_0 */
7827 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7828 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7829 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7830 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7831 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7832 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7833 0x0000ffff /* END */
7835 IDirect3DPixelShader9 *shader;
7836 IDirect3DTexture9 *texture;
7837 IDirect3DSurface9 *surface, *backbuffer;
7838 const float quad[] = {
7839 -1.0, -1.0, 0.1,
7840 1.0, -1.0, 0.1,
7841 -1.0, 0.0, 0.1,
7843 1.0, -1.0, 0.1,
7844 1.0, 0.0, 0.1,
7845 -1.0, 0.0, 0.1,
7847 -1.0, 0.0, 0.1,
7848 -1.0, 1.0, 0.1,
7849 1.0, 0.0, 0.1,
7851 1.0, 0.0, 0.1,
7852 -1.0, 1.0, 0.1,
7853 1.0, 1.0, 0.1,
7855 const float blit[] = {
7856 0.0, -1.0, 0.1, 0.0, 0.0,
7857 1.0, -1.0, 0.1, 1.0, 0.0,
7858 0.0, 1.0, 0.1, 0.0, 1.0,
7859 1.0, 1.0, 0.1, 1.0, 1.0,
7862 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7863 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7864 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7865 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7866 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7867 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7868 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7869 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7870 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7871 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7872 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7873 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7875 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7876 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7878 hr = IDirect3DDevice9_BeginScene(device);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7880 if(SUCCEEDED(hr)) {
7881 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7882 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7883 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7885 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7887 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7888 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7891 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7893 /* Blit the texture onto the back buffer to make it visible */
7894 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7895 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7896 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7897 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7898 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7899 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7900 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7902 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7905 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7906 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7908 hr = IDirect3DDevice9_EndScene(device);
7909 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7912 color = getPixelColor(device, 160, 360);
7913 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7914 color = getPixelColor(device, 160, 120);
7915 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7916 color = getPixelColor(device, 480, 360);
7917 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7918 color = getPixelColor(device, 480, 120);
7919 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7920 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7922 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7923 IDirect3DDevice9_SetTexture(device, 0, NULL);
7924 IDirect3DPixelShader9_Release(shader);
7925 IDirect3DSurface9_Release(surface);
7926 IDirect3DSurface9_Release(backbuffer);
7927 IDirect3DTexture9_Release(texture);
7930 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7932 HRESULT hr;
7933 DWORD color;
7934 int i;
7935 D3DCAPS9 caps;
7936 BOOL L6V5U5_supported = FALSE;
7937 IDirect3DTexture9 *tex1, *tex2;
7938 D3DLOCKED_RECT locked_rect;
7940 static const float quad[][7] = {
7941 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7942 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7943 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7944 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7947 static const D3DVERTEXELEMENT9 decl_elements[] = {
7948 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7949 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7950 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7951 D3DDECL_END()
7954 /* use asymmetric matrix to test loading */
7955 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7956 float scale, offset;
7958 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7959 IDirect3DTexture9 *texture = NULL;
7961 memset(&caps, 0, sizeof(caps));
7962 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7963 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7964 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7965 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7966 return;
7967 } else {
7968 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7969 * They report that it is not supported, but after that bump mapping works properly. So just test
7970 * if the format is generally supported, and check the BUMPENVMAP flag
7972 IDirect3D9 *d3d9;
7974 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7975 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7976 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7977 L6V5U5_supported = SUCCEEDED(hr);
7978 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7979 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7980 IDirect3D9_Release(d3d9);
7981 if(FAILED(hr)) {
7982 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7983 return;
7987 /* Generate the textures */
7988 generate_bumpmap_textures(device);
7990 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7991 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7992 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7993 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7994 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7995 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7996 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7997 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7999 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8000 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8001 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8002 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8003 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8004 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8006 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8007 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8008 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8009 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8010 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8011 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8013 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8014 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8016 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8017 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8020 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8023 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8024 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8025 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8026 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8028 hr = IDirect3DDevice9_BeginScene(device);
8029 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8032 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8034 hr = IDirect3DDevice9_EndScene(device);
8035 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8037 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8038 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8039 * But since testing the color match is not the purpose of the test don't be too picky
8041 color = getPixelColor(device, 320-32, 240);
8042 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8043 color = getPixelColor(device, 320+32, 240);
8044 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8045 color = getPixelColor(device, 320, 240-32);
8046 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8047 color = getPixelColor(device, 320, 240+32);
8048 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8049 color = getPixelColor(device, 320, 240);
8050 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8051 color = getPixelColor(device, 320+32, 240+32);
8052 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8053 color = getPixelColor(device, 320-32, 240+32);
8054 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8055 color = getPixelColor(device, 320+32, 240-32);
8056 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8057 color = getPixelColor(device, 320-32, 240-32);
8058 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8059 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8060 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8062 for(i = 0; i < 2; i++) {
8063 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8064 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8065 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8066 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8067 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8068 IDirect3DTexture9_Release(texture); /* To destroy it */
8071 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8072 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8073 goto cleanup;
8075 if(L6V5U5_supported == FALSE) {
8076 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8077 goto cleanup;
8080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8081 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8082 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8083 * would only make this test more complicated
8085 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8086 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8087 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8088 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8090 memset(&locked_rect, 0, sizeof(locked_rect));
8091 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8092 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8093 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8094 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8095 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8097 memset(&locked_rect, 0, sizeof(locked_rect));
8098 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8099 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8100 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8101 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8102 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8104 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8105 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8106 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8107 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8109 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8110 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8111 scale = 2.0;
8112 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8113 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8114 offset = 0.1;
8115 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8116 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8118 hr = IDirect3DDevice9_BeginScene(device);
8119 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8120 if(SUCCEEDED(hr)) {
8121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8122 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8123 hr = IDirect3DDevice9_EndScene(device);
8124 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8127 color = getPixelColor(device, 320, 240);
8128 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8129 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8130 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8132 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8133 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8134 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8136 /* Check a result scale factor > 1.0 */
8137 scale = 10;
8138 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8139 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8140 offset = 10;
8141 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8142 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8144 hr = IDirect3DDevice9_BeginScene(device);
8145 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8146 if(SUCCEEDED(hr)) {
8147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8148 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8149 hr = IDirect3DDevice9_EndScene(device);
8150 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8152 color = getPixelColor(device, 320, 240);
8153 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8155 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8157 /* Check clamping in the scale factor calculation */
8158 scale = 1000;
8159 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8160 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8161 offset = -1;
8162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8163 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8165 hr = IDirect3DDevice9_BeginScene(device);
8166 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8167 if(SUCCEEDED(hr)) {
8168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8169 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8170 hr = IDirect3DDevice9_EndScene(device);
8171 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8173 color = getPixelColor(device, 320, 240);
8174 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8175 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8176 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8178 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8179 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8180 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8181 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8183 IDirect3DTexture9_Release(tex1);
8184 IDirect3DTexture9_Release(tex2);
8186 cleanup:
8187 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8188 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8189 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8190 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8192 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8193 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8194 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8197 static void stencil_cull_test(IDirect3DDevice9 *device) {
8198 HRESULT hr;
8199 IDirect3DSurface9 *depthstencil = NULL;
8200 D3DSURFACE_DESC desc;
8201 float quad1[] = {
8202 -1.0, -1.0, 0.1,
8203 0.0, -1.0, 0.1,
8204 -1.0, 0.0, 0.1,
8205 0.0, 0.0, 0.1,
8207 float quad2[] = {
8208 0.0, -1.0, 0.1,
8209 1.0, -1.0, 0.1,
8210 0.0, 0.0, 0.1,
8211 1.0, 0.0, 0.1,
8213 float quad3[] = {
8214 0.0, 0.0, 0.1,
8215 1.0, 0.0, 0.1,
8216 0.0, 1.0, 0.1,
8217 1.0, 1.0, 0.1,
8219 float quad4[] = {
8220 -1.0, 0.0, 0.1,
8221 0.0, 0.0, 0.1,
8222 -1.0, 1.0, 0.1,
8223 0.0, 1.0, 0.1,
8225 struct vertex painter[] = {
8226 {-1.0, -1.0, 0.0, 0x00000000},
8227 { 1.0, -1.0, 0.0, 0x00000000},
8228 {-1.0, 1.0, 0.0, 0x00000000},
8229 { 1.0, 1.0, 0.0, 0x00000000},
8231 WORD indices_cw[] = {0, 1, 3};
8232 WORD indices_ccw[] = {0, 2, 3};
8233 unsigned int i;
8234 DWORD color;
8236 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8237 if(depthstencil == NULL) {
8238 skip("No depth stencil buffer\n");
8239 return;
8241 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8242 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8243 IDirect3DSurface9_Release(depthstencil);
8244 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8245 skip("No 4 or 8 bit stencil surface\n");
8246 return;
8249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8250 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8251 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8258 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8260 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8265 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8267 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8274 /* First pass: Fill the stencil buffer with some values... */
8275 hr = IDirect3DDevice9_BeginScene(device);
8276 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8277 if(SUCCEEDED(hr))
8279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8280 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8281 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8282 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8283 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8284 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8285 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8286 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8292 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8293 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8294 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8295 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8296 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8297 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8301 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8302 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8303 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8304 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8305 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8306 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8310 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8311 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8312 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8313 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8314 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8315 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8317 hr = IDirect3DDevice9_EndScene(device);
8318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8327 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8329 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8331 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8335 /* 2nd pass: Make the stencil values visible */
8336 hr = IDirect3DDevice9_BeginScene(device);
8337 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8338 if(SUCCEEDED(hr))
8340 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8341 for(i = 0; i < 16; i++) {
8342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8345 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8346 painter[1].diffuse = (i * 16);
8347 painter[2].diffuse = (i * 16);
8348 painter[3].diffuse = (i * 16);
8349 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8350 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8352 hr = IDirect3DDevice9_EndScene(device);
8353 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8357 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8359 color = getPixelColor(device, 160, 420);
8360 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8361 color = getPixelColor(device, 160, 300);
8362 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8364 color = getPixelColor(device, 480, 420);
8365 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8366 color = getPixelColor(device, 480, 300);
8367 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8369 color = getPixelColor(device, 160, 180);
8370 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8371 color = getPixelColor(device, 160, 60);
8372 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8374 color = getPixelColor(device, 480, 180);
8375 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8376 color = getPixelColor(device, 480, 60);
8377 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8379 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8383 static void vpos_register_test(IDirect3DDevice9 *device)
8385 HRESULT hr;
8386 DWORD color;
8387 const DWORD shader_code[] = {
8388 0xffff0300, /* ps_3_0 */
8389 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8390 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8391 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8392 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8393 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8394 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8395 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8396 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8397 0x0000ffff /* end */
8399 const DWORD shader_frac_code[] = {
8400 0xffff0300, /* ps_3_0 */
8401 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8402 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8403 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8404 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8405 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8406 0x0000ffff /* end */
8408 IDirect3DPixelShader9 *shader, *shader_frac;
8409 IDirect3DSurface9 *surface = NULL, *backbuffer;
8410 const float quad[] = {
8411 -1.0, -1.0, 0.1, 0.0, 0.0,
8412 1.0, -1.0, 0.1, 1.0, 0.0,
8413 -1.0, 1.0, 0.1, 0.0, 1.0,
8414 1.0, 1.0, 0.1, 1.0, 1.0,
8416 D3DLOCKED_RECT lr;
8417 float constant[4] = {1.0, 0.0, 320, 240};
8418 DWORD *pos;
8420 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8421 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8422 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8423 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8424 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8425 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8426 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8427 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8428 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8429 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8430 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8431 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8433 hr = IDirect3DDevice9_BeginScene(device);
8434 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8435 if(SUCCEEDED(hr)) {
8436 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8437 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8439 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8440 hr = IDirect3DDevice9_EndScene(device);
8441 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8444 /* This has to be pixel exact */
8445 color = getPixelColor(device, 319, 239);
8446 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8447 color = getPixelColor(device, 320, 239);
8448 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8449 color = getPixelColor(device, 319, 240);
8450 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8451 color = getPixelColor(device, 320, 240);
8452 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8453 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8455 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8456 &surface, NULL);
8457 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8458 hr = IDirect3DDevice9_BeginScene(device);
8459 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8460 if(SUCCEEDED(hr)) {
8461 constant[2] = 16; constant[3] = 16;
8462 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8463 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8464 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8465 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468 hr = IDirect3DDevice9_EndScene(device);
8469 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8471 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8472 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8474 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8475 color = *pos & 0x00ffffff;
8476 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8477 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8478 color = *pos & 0x00ffffff;
8479 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8480 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8481 color = *pos & 0x00ffffff;
8482 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8483 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8484 color = *pos & 0x00ffffff;
8485 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8487 hr = IDirect3DSurface9_UnlockRect(surface);
8488 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8490 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8491 * have full control over the multisampling setting inside this test
8493 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8494 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8495 hr = IDirect3DDevice9_BeginScene(device);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8497 if(SUCCEEDED(hr)) {
8498 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8499 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8501 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8502 hr = IDirect3DDevice9_EndScene(device);
8503 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8505 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8506 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8508 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8509 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8511 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8512 color = *pos & 0x00ffffff;
8513 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8515 hr = IDirect3DSurface9_UnlockRect(surface);
8516 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8518 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8519 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8520 IDirect3DPixelShader9_Release(shader);
8521 IDirect3DPixelShader9_Release(shader_frac);
8522 if(surface) IDirect3DSurface9_Release(surface);
8523 IDirect3DSurface9_Release(backbuffer);
8526 static void pointsize_test(IDirect3DDevice9 *device)
8528 HRESULT hr;
8529 D3DCAPS9 caps;
8530 D3DMATRIX matrix;
8531 D3DMATRIX identity;
8532 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8533 DWORD color;
8534 IDirect3DTexture9 *tex1, *tex2;
8535 D3DLOCKED_RECT lr;
8536 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8537 0x00000000, 0x00000000};
8538 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8539 0x00000000, 0x0000ff00};
8541 const float vertices[] = {
8542 64, 64, 0.1,
8543 128, 64, 0.1,
8544 192, 64, 0.1,
8545 256, 64, 0.1,
8546 320, 64, 0.1,
8547 384, 64, 0.1,
8548 448, 64, 0.1,
8549 512, 64, 0.1,
8550 576, 64, 0.1,
8553 /* 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 */
8554 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;
8555 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;
8556 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;
8557 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;
8559 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;
8560 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;
8561 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;
8562 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;
8564 memset(&caps, 0, sizeof(caps));
8565 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8566 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8567 if(caps.MaxPointSize < 32.0) {
8568 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8569 return;
8572 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8574 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8576 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8577 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8578 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8579 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8581 hr = IDirect3DDevice9_BeginScene(device);
8582 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8583 if(SUCCEEDED(hr)) {
8584 ptsize = 16.0;
8585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8586 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8588 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8590 ptsize = 32.0;
8591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8592 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8594 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8596 ptsize = 31.5;
8597 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8598 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8600 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8602 if(caps.MaxPointSize >= 64.0) {
8603 ptsize = 64.0;
8604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8605 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8607 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8609 ptsize = 63.75;
8610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8611 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8612 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8613 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8616 ptsize = 1.0;
8617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8618 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8619 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8620 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8622 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8623 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8624 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8625 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8627 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8628 ptsize = 16.0;
8629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8630 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8631 ptsize = 1.0;
8632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8633 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8635 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8637 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8638 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8640 ptsize = 4.0;
8641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8642 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8643 ptsize = 16.0;
8644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8652 /* pointsize < pointsize_min < pointsize_max?
8653 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8655 ptsize = 1.0;
8656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8657 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8658 ptsize = 16.0;
8659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8660 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8661 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8662 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8664 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8665 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8667 hr = IDirect3DDevice9_EndScene(device);
8668 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8670 color = getPixelColor(device, 64-9, 64-9);
8671 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8672 color = getPixelColor(device, 64-8, 64-8);
8673 ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8674 color = getPixelColor(device, 64-7, 64-7);
8675 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8676 color = getPixelColor(device, 64+7, 64+7);
8677 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8678 color = getPixelColor(device, 64+8, 64+8);
8679 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8680 color = getPixelColor(device, 64+9, 64+9);
8681 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8683 color = getPixelColor(device, 128-17, 64-17);
8684 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8685 color = getPixelColor(device, 128-16, 64-16);
8686 ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8687 color = getPixelColor(device, 128-15, 64-15);
8688 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8689 color = getPixelColor(device, 128+15, 64+15);
8690 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8691 color = getPixelColor(device, 128+16, 64+16);
8692 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8693 color = getPixelColor(device, 128+17, 64+17);
8694 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8696 color = getPixelColor(device, 192-17, 64-17);
8697 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8698 color = getPixelColor(device, 192-16, 64-16);
8699 todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8700 color = getPixelColor(device, 192-15, 64-15);
8701 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8702 color = getPixelColor(device, 192+15, 64+15);
8703 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8704 color = getPixelColor(device, 192+16, 64+16);
8705 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8706 color = getPixelColor(device, 192+17, 64+17);
8707 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8709 if(caps.MaxPointSize >= 64.0) {
8710 color = getPixelColor(device, 256-33, 64-33);
8711 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8712 color = getPixelColor(device, 256-32, 64-32);
8713 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8714 color = getPixelColor(device, 256-31, 64-31);
8715 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8716 color = getPixelColor(device, 256+31, 64+31);
8717 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8718 color = getPixelColor(device, 256+32, 64+32);
8719 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8720 color = getPixelColor(device, 256+33, 64+33);
8721 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8723 color = getPixelColor(device, 384-33, 64-33);
8724 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8725 color = getPixelColor(device, 384-32, 64-32);
8726 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8727 color = getPixelColor(device, 384-31, 64-31);
8728 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8729 color = getPixelColor(device, 384+31, 64+31);
8730 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8731 color = getPixelColor(device, 384+32, 64+32);
8732 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8733 color = getPixelColor(device, 384+33, 64+33);
8734 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8737 color = getPixelColor(device, 320-1, 64-1);
8738 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8739 color = getPixelColor(device, 320-0, 64-0);
8740 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8741 color = getPixelColor(device, 320+1, 64+1);
8742 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8744 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8745 color = getPixelColor(device, 448-4, 64-4);
8746 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8747 color = getPixelColor(device, 448+4, 64+4);
8748 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8750 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8751 color = getPixelColor(device, 512-4, 64-4);
8752 ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8753 color = getPixelColor(device, 512+4, 64+4);
8754 ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8756 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8757 * Don't be overly picky - just show that the point is bigger than 1 pixel
8759 color = getPixelColor(device, 576-4, 64-4);
8760 ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8761 color = getPixelColor(device, 576+4, 64+4);
8762 ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8764 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8766 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8767 * generates texture coordinates for the point(result: Yes, it does)
8769 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8770 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8771 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8774 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8776 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8777 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8778 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8779 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8780 memset(&lr, 0, sizeof(lr));
8781 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8782 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8783 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8784 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8785 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8786 memset(&lr, 0, sizeof(lr));
8787 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8788 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8789 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8790 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8791 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8792 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8793 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8794 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8795 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8796 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8797 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8798 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8799 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8800 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8801 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8802 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8803 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8804 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8805 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8808 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8809 ptsize = 32.0;
8810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8811 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8813 hr = IDirect3DDevice9_BeginScene(device);
8814 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8815 if(SUCCEEDED(hr))
8817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8818 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8819 hr = IDirect3DDevice9_EndScene(device);
8820 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8823 color = getPixelColor(device, 64-4, 64-4);
8824 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8825 color = getPixelColor(device, 64-4, 64+4);
8826 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8827 color = getPixelColor(device, 64+4, 64+4);
8828 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8829 color = getPixelColor(device, 64+4, 64-4);
8830 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8831 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8833 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8834 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8835 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8836 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8837 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8838 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8839 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8840 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8841 IDirect3DTexture9_Release(tex1);
8842 IDirect3DTexture9_Release(tex2);
8844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8847 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8848 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8849 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8852 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8854 HRESULT hr;
8855 IDirect3DPixelShader9 *ps;
8856 IDirect3DTexture9 *tex1, *tex2;
8857 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8858 D3DCAPS9 caps;
8859 DWORD color;
8860 DWORD shader_code[] = {
8861 0xffff0300, /* ps_3_0 */
8862 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8863 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8864 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8865 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8866 0x0000ffff /* END */
8868 float quad[] = {
8869 -1.0, -1.0, 0.1,
8870 1.0, -1.0, 0.1,
8871 -1.0, 1.0, 0.1,
8872 1.0, 1.0, 0.1,
8874 float texquad[] = {
8875 -1.0, -1.0, 0.1, 0.0, 0.0,
8876 0.0, -1.0, 0.1, 1.0, 0.0,
8877 -1.0, 1.0, 0.1, 0.0, 1.0,
8878 0.0, 1.0, 0.1, 1.0, 1.0,
8880 0.0, -1.0, 0.1, 0.0, 0.0,
8881 1.0, -1.0, 0.1, 1.0, 0.0,
8882 0.0, 1.0, 0.1, 0.0, 1.0,
8883 1.0, 1.0, 0.1, 1.0, 1.0,
8886 memset(&caps, 0, sizeof(caps));
8887 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8888 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8889 if(caps.NumSimultaneousRTs < 2) {
8890 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8891 return;
8894 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8895 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8897 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8898 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8899 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8900 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8901 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8902 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8904 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8905 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8906 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8907 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8908 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8909 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8911 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8912 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8913 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8915 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8917 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8920 hr = IDirect3DDevice9_BeginScene(device);
8921 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8922 if(SUCCEEDED(hr)) {
8923 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8924 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8926 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8927 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8928 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8929 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8930 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8931 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8932 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8933 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8935 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8936 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8938 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8940 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8941 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8943 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8945 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8946 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8948 hr = IDirect3DDevice9_EndScene(device);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8952 color = getPixelColor(device, 160, 240);
8953 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8954 color = getPixelColor(device, 480, 240);
8955 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8956 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8958 IDirect3DPixelShader9_Release(ps);
8959 IDirect3DTexture9_Release(tex1);
8960 IDirect3DTexture9_Release(tex2);
8961 IDirect3DSurface9_Release(surf1);
8962 IDirect3DSurface9_Release(surf2);
8963 IDirect3DSurface9_Release(backbuf);
8966 struct formats {
8967 const char *fmtName;
8968 D3DFORMAT textureFormat;
8969 DWORD resultColorBlending;
8970 DWORD resultColorNoBlending;
8973 const struct formats test_formats[] = {
8974 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8975 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8976 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8977 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8978 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8979 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8980 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8981 { NULL, 0 }
8984 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8986 HRESULT hr;
8987 IDirect3DTexture9 *offscreenTexture = NULL;
8988 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8989 IDirect3D9 *d3d = NULL;
8990 DWORD color;
8991 DWORD r0, g0, b0, r1, g1, b1;
8992 int fmt_index;
8994 static const float quad[][5] = {
8995 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8996 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8997 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8998 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9001 /* Quad with R=0x10, G=0x20 */
9002 static const struct vertex quad1[] = {
9003 {-1.0f, -1.0f, 0.1f, 0x80102000},
9004 {-1.0f, 1.0f, 0.1f, 0x80102000},
9005 { 1.0f, -1.0f, 0.1f, 0x80102000},
9006 { 1.0f, 1.0f, 0.1f, 0x80102000},
9009 /* Quad with R=0x20, G=0x10 */
9010 static const struct vertex quad2[] = {
9011 {-1.0f, -1.0f, 0.1f, 0x80201000},
9012 {-1.0f, 1.0f, 0.1f, 0x80201000},
9013 { 1.0f, -1.0f, 0.1f, 0x80201000},
9014 { 1.0f, 1.0f, 0.1f, 0x80201000},
9017 IDirect3DDevice9_GetDirect3D(device, &d3d);
9019 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9020 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9021 if(!backbuffer) {
9022 goto out;
9025 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9027 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9028 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9029 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9030 continue;
9033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9034 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9036 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9037 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9038 if(!offscreenTexture) {
9039 continue;
9042 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9043 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9044 if(!offscreen) {
9045 continue;
9048 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9049 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9051 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9052 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9053 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9054 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9055 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9056 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9057 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9058 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9060 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9062 /* Below we will draw two quads with different colors and try to blend them together.
9063 * The result color is compared with the expected outcome.
9065 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9066 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9067 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9069 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9072 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9074 /* Draw a quad using color 0x0010200 */
9075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9080 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9082 /* Draw a quad using color 0x0020100 */
9083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9084 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9086 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9088 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9090 /* We don't want to blend the result on the backbuffer */
9091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9092 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9094 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9095 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9096 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9097 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9098 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9100 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9101 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9103 /* This time with the texture */
9104 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9105 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9107 IDirect3DDevice9_EndScene(device);
9110 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9111 /* Compare the color of the center quad with our expectation */
9112 color = getPixelColor(device, 320, 240);
9113 r0 = (color & 0x00ff0000) >> 16;
9114 g0 = (color & 0x0000ff00) >> 8;
9115 b0 = (color & 0x000000ff) >> 0;
9117 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9118 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9119 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9121 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9122 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9123 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9124 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9125 } else {
9126 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9127 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9128 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9129 color = getPixelColor(device, 320, 240);
9130 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);
9132 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9134 IDirect3DDevice9_SetTexture(device, 0, NULL);
9135 if(offscreenTexture) {
9136 IDirect3DTexture9_Release(offscreenTexture);
9138 if(offscreen) {
9139 IDirect3DSurface9_Release(offscreen);
9143 out:
9144 /* restore things */
9145 if(backbuffer) {
9146 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9147 IDirect3DSurface9_Release(backbuffer);
9151 static void tssargtemp_test(IDirect3DDevice9 *device)
9153 HRESULT hr;
9154 DWORD color;
9155 static const struct vertex quad[] = {
9156 {-1.0, -1.0, 0.1, 0x00ff0000},
9157 { 1.0, -1.0, 0.1, 0x00ff0000},
9158 {-1.0, 1.0, 0.1, 0x00ff0000},
9159 { 1.0, 1.0, 0.1, 0x00ff0000}
9161 D3DCAPS9 caps;
9163 memset(&caps, 0, sizeof(caps));
9164 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9165 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9166 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9167 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9168 return;
9171 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9172 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9174 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9175 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9176 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9177 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9179 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9180 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9181 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9182 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9183 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9184 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9186 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9187 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9188 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9189 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9190 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9191 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9193 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9194 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9197 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9198 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9199 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9201 hr = IDirect3DDevice9_BeginScene(device);
9202 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9203 if(SUCCEEDED(hr)) {
9204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9205 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9206 hr = IDirect3DDevice9_EndScene(device);
9207 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9209 color = getPixelColor(device, 320, 240);
9210 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9211 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9213 /* Set stage 1 back to default */
9214 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9215 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9216 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9217 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9218 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9219 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9220 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9221 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9222 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9223 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9226 struct testdata
9228 DWORD idxVertex; /* number of instances in the first stream */
9229 DWORD idxColor; /* number of instances in the second stream */
9230 DWORD idxInstance; /* should be 1 ?? */
9231 DWORD color1; /* color 1 instance */
9232 DWORD color2; /* color 2 instance */
9233 DWORD color3; /* color 3 instance */
9234 DWORD color4; /* color 4 instance */
9235 WORD strVertex; /* specify which stream to use 0-2*/
9236 WORD strColor;
9237 WORD strInstance;
9240 static const struct testdata testcases[]=
9242 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9243 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9244 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9245 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9246 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9247 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9248 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9249 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9250 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9251 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9252 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9253 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9254 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9255 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9256 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9258 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9259 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9263 /* Drawing Indexed Geometry with instances*/
9264 static void stream_test(IDirect3DDevice9 *device)
9266 IDirect3DVertexBuffer9 *vb = NULL;
9267 IDirect3DVertexBuffer9 *vb2 = NULL;
9268 IDirect3DVertexBuffer9 *vb3 = NULL;
9269 IDirect3DIndexBuffer9 *ib = NULL;
9270 IDirect3DVertexDeclaration9 *pDecl = NULL;
9271 IDirect3DVertexShader9 *shader = NULL;
9272 HRESULT hr;
9273 BYTE *data;
9274 DWORD color;
9275 DWORD ind;
9276 unsigned i;
9278 const DWORD shader_code[] =
9280 0xfffe0101, /* vs_1_1 */
9281 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9282 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9283 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9284 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9285 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9286 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9287 0x0000ffff
9290 const float quad[][3] =
9292 {-0.5f, -0.5f, 1.1f}, /*0 */
9293 {-0.5f, 0.5f, 1.1f}, /*1 */
9294 { 0.5f, -0.5f, 1.1f}, /*2 */
9295 { 0.5f, 0.5f, 1.1f}, /*3 */
9298 const float vertcolor[][4] =
9300 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9301 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9302 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9303 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9306 /* 4 position for 4 instances */
9307 const float instancepos[][3] =
9309 {-0.6f,-0.6f, 0.0f},
9310 { 0.6f,-0.6f, 0.0f},
9311 { 0.6f, 0.6f, 0.0f},
9312 {-0.6f, 0.6f, 0.0f},
9315 short indices[] = {0, 1, 2, 1, 2, 3};
9317 D3DVERTEXELEMENT9 decl[] =
9319 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9320 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9321 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9322 D3DDECL_END()
9325 /* set the default value because it isn't done in wine? */
9326 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9327 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9329 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9330 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9331 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9333 /* check wrong cases */
9334 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9335 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9336 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9337 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9338 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9339 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9340 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9341 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9342 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9343 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9344 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9345 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9346 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9347 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9348 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9349 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9350 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9351 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9352 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9353 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9355 /* set the default value back */
9356 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9357 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9359 /* create all VertexBuffers*/
9360 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9361 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9362 if(!vb) {
9363 skip("Failed to create a vertex buffer\n");
9364 return;
9366 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9367 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9368 if(!vb2) {
9369 skip("Failed to create a vertex buffer\n");
9370 goto out;
9372 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9373 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9374 if(!vb3) {
9375 skip("Failed to create a vertex buffer\n");
9376 goto out;
9379 /* create IndexBuffer*/
9380 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9381 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9382 if(!ib) {
9383 skip("Failed to create a index buffer\n");
9384 goto out;
9387 /* copy all Buffers (Vertex + Index)*/
9388 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9390 memcpy(data, quad, sizeof(quad));
9391 hr = IDirect3DVertexBuffer9_Unlock(vb);
9392 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9393 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9394 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9395 memcpy(data, vertcolor, sizeof(vertcolor));
9396 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9397 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9398 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9399 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9400 memcpy(data, instancepos, sizeof(instancepos));
9401 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9402 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9403 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9404 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9405 memcpy(data, indices, sizeof(indices));
9406 hr = IDirect3DIndexBuffer9_Unlock(ib);
9407 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9409 /* create VertexShader */
9410 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9411 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9412 if(!shader) {
9413 skip("Failed to create a vetex shader\n");
9414 goto out;
9417 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9418 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9420 hr = IDirect3DDevice9_SetIndices(device, ib);
9421 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9423 /* run all tests */
9424 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9426 struct testdata act = testcases[i];
9427 decl[0].Stream = act.strVertex;
9428 decl[1].Stream = act.strColor;
9429 decl[2].Stream = act.strInstance;
9430 /* create VertexDeclarations */
9431 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9432 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9434 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9435 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9437 hr = IDirect3DDevice9_BeginScene(device);
9438 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9439 if(SUCCEEDED(hr))
9441 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9442 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9444 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9445 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9446 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9447 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9449 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9450 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9451 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9452 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9454 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9455 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9456 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9457 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9459 /* don't know if this is right (1*3 and 4*1)*/
9460 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9461 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9462 hr = IDirect3DDevice9_EndScene(device);
9463 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9465 /* set all StreamSource && StreamSourceFreq back to default */
9466 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9467 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9468 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9469 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9470 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9471 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9472 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9473 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9474 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9475 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9476 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9477 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9480 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9481 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9483 color = getPixelColor(device, 160, 360);
9484 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9485 color = getPixelColor(device, 480, 360);
9486 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9487 color = getPixelColor(device, 480, 120);
9488 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9489 color = getPixelColor(device, 160, 120);
9490 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9493 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9496 hr = IDirect3DDevice9_SetIndices(device, NULL);
9497 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9499 out:
9500 if(vb) IDirect3DVertexBuffer9_Release(vb);
9501 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9502 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9503 if(ib)IDirect3DIndexBuffer9_Release(ib);
9504 if(shader)IDirect3DVertexShader9_Release(shader);
9507 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9508 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9509 IDirect3DTexture9 *dsttex = NULL;
9510 HRESULT hr;
9511 DWORD color;
9512 D3DRECT r1 = {0, 0, 50, 50 };
9513 D3DRECT r2 = {50, 0, 100, 50 };
9514 D3DRECT r3 = {50, 50, 100, 100};
9515 D3DRECT r4 = {0, 50, 50, 100};
9516 const float quad[] = {
9517 -1.0, -1.0, 0.1, 0.0, 0.0,
9518 1.0, -1.0, 0.1, 1.0, 0.0,
9519 -1.0, 1.0, 0.1, 0.0, 1.0,
9520 1.0, 1.0, 0.1, 1.0, 1.0,
9523 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9524 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9526 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9527 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9528 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9529 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9531 if(!src || !dsttex) {
9532 skip("One or more test resources could not be created\n");
9533 goto cleanup;
9536 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9537 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9539 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9540 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9542 /* Clear the StretchRect destination for debugging */
9543 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9544 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9545 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9546 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9548 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9551 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9552 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9553 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9554 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9555 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9556 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9557 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9558 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9560 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9561 * the target -> texture GL blit path
9563 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9564 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9565 IDirect3DSurface9_Release(dst);
9567 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9568 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9570 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9574 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9576 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9577 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9579 hr = IDirect3DDevice9_BeginScene(device);
9580 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9581 if(SUCCEEDED(hr)) {
9582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9583 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9584 hr = IDirect3DDevice9_EndScene(device);
9585 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9588 color = getPixelColor(device, 160, 360);
9589 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9590 color = getPixelColor(device, 480, 360);
9591 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9592 color = getPixelColor(device, 480, 120);
9593 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9594 color = getPixelColor(device, 160, 120);
9595 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9597 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9599 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9600 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9601 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9602 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9604 cleanup:
9605 if(src) IDirect3DSurface9_Release(src);
9606 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9607 if(dsttex) IDirect3DTexture9_Release(dsttex);
9610 static void texop_test(IDirect3DDevice9 *device)
9612 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9613 IDirect3DTexture9 *texture = NULL;
9614 D3DLOCKED_RECT locked_rect;
9615 D3DCOLOR color;
9616 D3DCAPS9 caps;
9617 HRESULT hr;
9618 unsigned i;
9620 static const struct {
9621 float x, y, z;
9622 float s, t;
9623 D3DCOLOR diffuse;
9624 } quad[] = {
9625 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9626 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9627 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9628 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9631 static const D3DVERTEXELEMENT9 decl_elements[] = {
9632 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9633 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9634 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9635 D3DDECL_END()
9638 static const struct {
9639 D3DTEXTUREOP op;
9640 const char *name;
9641 DWORD caps_flag;
9642 D3DCOLOR result;
9643 } test_data[] = {
9644 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9645 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9646 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9647 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9648 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9649 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9650 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9651 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9652 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9653 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9654 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9655 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9656 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9657 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9658 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9659 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9660 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9661 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9662 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9663 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9664 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9665 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9666 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9669 memset(&caps, 0, sizeof(caps));
9670 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9671 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9673 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9674 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9675 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9676 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9678 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9679 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9680 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9681 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9682 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9683 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9684 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9685 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9686 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9688 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9689 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9690 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9691 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9692 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9693 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9695 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9696 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9699 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9701 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9703 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9705 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9706 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9708 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9710 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9712 skip("tex operation %s not supported\n", test_data[i].name);
9713 continue;
9716 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9717 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9719 hr = IDirect3DDevice9_BeginScene(device);
9720 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9723 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9725 hr = IDirect3DDevice9_EndScene(device);
9726 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9728 color = getPixelColor(device, 320, 240);
9729 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9730 test_data[i].name, color, test_data[i].result);
9732 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9733 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9736 if (texture) IDirect3DTexture9_Release(texture);
9737 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9740 static void yuv_color_test(IDirect3DDevice9 *device) {
9741 HRESULT hr;
9742 IDirect3DSurface9 *surface = NULL, *target = NULL;
9743 unsigned int fmt, i;
9744 D3DFORMAT format;
9745 const char *fmt_string;
9746 D3DLOCKED_RECT lr;
9747 IDirect3D9 *d3d;
9748 HRESULT color;
9749 DWORD ref_color_left, ref_color_right;
9751 struct {
9752 DWORD in; /* The input color */
9753 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9754 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9755 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9756 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9757 } test_data[] = {
9758 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9759 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9760 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9761 * that
9763 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9764 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9765 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9766 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9767 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9768 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9769 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9770 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9771 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9772 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9773 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9774 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9775 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9776 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9778 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9779 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9780 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9781 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9784 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9785 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9786 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9787 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9789 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9790 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9792 for(fmt = 0; fmt < 2; fmt++) {
9793 if(fmt == 0) {
9794 format = D3DFMT_UYVY;
9795 fmt_string = "D3DFMT_UYVY";
9796 } else {
9797 format = D3DFMT_YUY2;
9798 fmt_string = "D3DFMT_YUY2";
9801 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9802 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9804 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9805 D3DRTYPE_SURFACE, format) != D3D_OK) {
9806 skip("%s is not supported\n", fmt_string);
9807 continue;
9810 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9811 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9812 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9814 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9815 if(fmt == 0) {
9816 ref_color_left = test_data[i].uyvy_left;
9817 ref_color_right = test_data[i].uyvy_right;
9818 } else {
9819 ref_color_left = test_data[i].yuy2_left;
9820 ref_color_right = test_data[i].yuy2_right;
9823 memset(&lr, 0, sizeof(lr));
9824 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9825 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9826 *((DWORD *) lr.pBits) = test_data[i].in;
9827 hr = IDirect3DSurface9_UnlockRect(surface);
9828 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9830 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9831 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9832 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9833 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9835 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9836 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9837 * want to add tests for the filtered pixels as well.
9839 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9840 * differently, so we need a max diff of 16
9842 color = getPixelColor(device, 40, 240);
9843 ok(color_match(color, ref_color_left, 18),
9844 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9845 test_data[i].in, color, ref_color_left, fmt_string);
9846 color = getPixelColor(device, 600, 240);
9847 ok(color_match(color, ref_color_right, 18),
9848 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9849 test_data[i].in, color, ref_color_right, fmt_string);
9850 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9851 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9853 IDirect3DSurface9_Release(surface);
9855 IDirect3DSurface9_Release(target);
9856 IDirect3D9_Release(d3d);
9859 static void texop_range_test(IDirect3DDevice9 *device)
9861 static const struct {
9862 float x, y, z;
9863 D3DCOLOR diffuse;
9864 } quad[] = {
9865 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9866 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9867 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9868 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9870 HRESULT hr;
9871 IDirect3DTexture9 *texture;
9872 D3DLOCKED_RECT locked_rect;
9873 D3DCAPS9 caps;
9874 DWORD color;
9876 /* We need ADD and SUBTRACT operations */
9877 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9878 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9879 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9880 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9881 return;
9883 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9884 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9885 return;
9888 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9889 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9890 /* Stage 1: result = diffuse(=1.0) + diffuse
9891 * stage 2: result = result - tfactor(= 0.5)
9893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9894 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9895 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9896 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9898 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9899 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9900 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9901 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9902 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9903 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9904 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9905 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9906 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9908 hr = IDirect3DDevice9_BeginScene(device);
9909 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9911 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9912 hr = IDirect3DDevice9_EndScene(device);
9913 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9915 color = getPixelColor(device, 320, 240);
9916 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9917 color);
9918 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9919 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9921 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9922 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9923 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9924 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9925 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9926 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9927 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9928 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9929 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9931 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9932 * stage 2: result = result + diffuse(1.0)
9934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9935 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9936 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9937 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9938 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9939 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9940 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9941 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9942 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9943 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9944 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9945 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9946 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9947 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9949 hr = IDirect3DDevice9_BeginScene(device);
9950 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9952 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9953 hr = IDirect3DDevice9_EndScene(device);
9954 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9956 color = getPixelColor(device, 320, 240);
9957 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9958 color);
9959 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9960 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9962 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9963 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9964 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9965 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9966 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9967 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9968 IDirect3DTexture9_Release(texture);
9971 static void alphareplicate_test(IDirect3DDevice9 *device) {
9972 struct vertex quad[] = {
9973 { -1.0, -1.0, 0.1, 0x80ff00ff },
9974 { 1.0, -1.0, 0.1, 0x80ff00ff },
9975 { -1.0, 1.0, 0.1, 0x80ff00ff },
9976 { 1.0, 1.0, 0.1, 0x80ff00ff },
9978 HRESULT hr;
9979 DWORD color;
9981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9982 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9984 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9985 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9987 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9988 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9989 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9990 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9992 hr = IDirect3DDevice9_BeginScene(device);
9993 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9994 if(SUCCEEDED(hr)) {
9995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9996 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9997 hr = IDirect3DDevice9_EndScene(device);
9998 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10001 color = getPixelColor(device, 320, 240);
10002 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10003 color);
10004 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10005 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10007 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10008 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10012 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10013 HRESULT hr;
10014 D3DCAPS9 caps;
10015 DWORD color;
10016 struct vertex quad[] = {
10017 { -1.0, -1.0, 0.1, 0x408080c0 },
10018 { 1.0, -1.0, 0.1, 0x408080c0 },
10019 { -1.0, 1.0, 0.1, 0x408080c0 },
10020 { 1.0, 1.0, 0.1, 0x408080c0 },
10023 memset(&caps, 0, sizeof(caps));
10024 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10025 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10026 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10027 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10028 return;
10031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10034 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10035 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10037 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10038 * mov r0.a, diffuse.a
10039 * mov r0, r0.a
10041 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10042 * 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
10043 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10045 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10048 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10049 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10050 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10051 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10052 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10053 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10054 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10055 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10056 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10057 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10058 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10059 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10060 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10062 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10064 hr = IDirect3DDevice9_BeginScene(device);
10065 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10066 if(SUCCEEDED(hr)) {
10067 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10068 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10069 hr = IDirect3DDevice9_EndScene(device);
10070 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10073 color = getPixelColor(device, 320, 240);
10074 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10075 color);
10076 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10077 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10079 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10080 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10081 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10082 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10083 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10084 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10087 static void zwriteenable_test(IDirect3DDevice9 *device) {
10088 HRESULT hr;
10089 DWORD color;
10090 struct vertex quad1[] = {
10091 { -1.0, -1.0, 0.1, 0x00ff0000},
10092 { -1.0, 1.0, 0.1, 0x00ff0000},
10093 { 1.0, -1.0, 0.1, 0x00ff0000},
10094 { 1.0, 1.0, 0.1, 0x00ff0000},
10096 struct vertex quad2[] = {
10097 { -1.0, -1.0, 0.9, 0x0000ff00},
10098 { -1.0, 1.0, 0.9, 0x0000ff00},
10099 { 1.0, -1.0, 0.9, 0x0000ff00},
10100 { 1.0, 1.0, 0.9, 0x0000ff00},
10103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10104 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10106 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10107 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10109 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10113 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10115 hr = IDirect3DDevice9_BeginScene(device);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10117 if(SUCCEEDED(hr)) {
10118 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10119 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10120 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10121 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10122 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10123 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10126 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10128 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10132 hr = IDirect3DDevice9_EndScene(device);
10133 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10136 color = getPixelColor(device, 320, 240);
10137 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10138 color);
10139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10140 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10146 static void alphatest_test(IDirect3DDevice9 *device) {
10147 #define ALPHATEST_PASSED 0x0000ff00
10148 #define ALPHATEST_FAILED 0x00ff0000
10149 struct {
10150 D3DCMPFUNC func;
10151 DWORD color_less;
10152 DWORD color_equal;
10153 DWORD color_greater;
10154 } testdata[] = {
10155 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10156 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10157 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10158 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10159 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10160 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10161 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10162 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10164 unsigned int i, j;
10165 HRESULT hr;
10166 DWORD color;
10167 struct vertex quad[] = {
10168 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10169 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10170 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10171 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10173 D3DCAPS9 caps;
10175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10176 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10177 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10178 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10180 for(j = 0; j < 2; j++) {
10181 if(j == 1) {
10182 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10183 * the alpha test either for performance reasons(floating point RTs) or to work
10184 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10185 * codepath for ffp and shader in this case, and the test should cover both
10187 IDirect3DPixelShader9 *ps;
10188 DWORD shader_code[] = {
10189 0xffff0101, /* ps_1_1 */
10190 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10191 0x0000ffff /* end */
10193 memset(&caps, 0, sizeof(caps));
10194 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10195 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10196 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10197 break;
10200 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10201 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10202 IDirect3DDevice9_SetPixelShader(device, ps);
10203 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10204 IDirect3DPixelShader9_Release(ps);
10207 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10209 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10212 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10215 hr = IDirect3DDevice9_BeginScene(device);
10216 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10217 if(SUCCEEDED(hr)) {
10218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10219 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10220 hr = IDirect3DDevice9_EndScene(device);
10221 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10223 color = getPixelColor(device, 320, 240);
10224 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10225 color, testdata[i].color_less, testdata[i].func);
10226 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10227 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10230 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10232 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10233 hr = IDirect3DDevice9_BeginScene(device);
10234 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10235 if(SUCCEEDED(hr)) {
10236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10237 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10238 hr = IDirect3DDevice9_EndScene(device);
10239 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10241 color = getPixelColor(device, 320, 240);
10242 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10243 color, testdata[i].color_equal, testdata[i].func);
10244 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10245 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10248 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10249 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10250 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10251 hr = IDirect3DDevice9_BeginScene(device);
10252 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10253 if(SUCCEEDED(hr)) {
10254 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10255 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10256 hr = IDirect3DDevice9_EndScene(device);
10257 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10259 color = getPixelColor(device, 320, 240);
10260 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10261 color, testdata[i].color_greater, testdata[i].func);
10262 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10263 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10267 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10268 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10269 IDirect3DDevice9_SetPixelShader(device, NULL);
10270 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10273 static void sincos_test(IDirect3DDevice9 *device) {
10274 const DWORD sin_shader_code[] = {
10275 0xfffe0200, /* vs_2_0 */
10276 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10277 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10278 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10279 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10280 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10281 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10282 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10283 0x0000ffff /* end */
10285 const DWORD cos_shader_code[] = {
10286 0xfffe0200, /* vs_2_0 */
10287 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10288 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10289 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10290 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10291 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10292 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10293 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10294 0x0000ffff /* end */
10296 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10297 HRESULT hr;
10298 struct {
10299 float x, y, z;
10300 } data[1280];
10301 unsigned int i;
10302 float sincosc1[4] = {D3DSINCOSCONST1};
10303 float sincosc2[4] = {D3DSINCOSCONST2};
10305 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10306 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10308 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10310 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10311 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10312 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10313 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10314 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10315 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10316 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10317 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10319 /* Generate a point from -1 to 1 every 0.5 pixels */
10320 for(i = 0; i < 1280; i++) {
10321 data[i].x = (-640.0 + i) / 640.0;
10322 data[i].y = 0.0;
10323 data[i].z = 0.1;
10326 hr = IDirect3DDevice9_BeginScene(device);
10327 if(SUCCEEDED(hr)) {
10328 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10329 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10330 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10331 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10333 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10334 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10336 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10338 hr = IDirect3DDevice9_EndScene(device);
10339 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10341 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10342 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10343 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10345 IDirect3DDevice9_SetVertexShader(device, NULL);
10346 IDirect3DVertexShader9_Release(sin_shader);
10347 IDirect3DVertexShader9_Release(cos_shader);
10350 static void loop_index_test(IDirect3DDevice9 *device) {
10351 const DWORD shader_code[] = {
10352 0xfffe0200, /* vs_2_0 */
10353 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10354 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10355 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10356 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10357 0x0000001d, /* endloop */
10358 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10359 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10360 0x0000ffff /* END */
10362 IDirect3DVertexShader9 *shader;
10363 HRESULT hr;
10364 DWORD color;
10365 const float quad[] = {
10366 -1.0, -1.0, 0.1,
10367 1.0, -1.0, 0.1,
10368 -1.0, 1.0, 0.1,
10369 1.0, 1.0, 0.1
10371 const float zero[4] = {0, 0, 0, 0};
10372 const float one[4] = {1, 1, 1, 1};
10373 int i0[4] = {2, 10, -3, 0};
10374 float values[4];
10376 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10377 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10378 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10379 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10380 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10381 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10383 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10385 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10386 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10387 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10388 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10389 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10390 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10391 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10392 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10393 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10394 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10395 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10396 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10397 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10398 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10399 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10400 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10401 values[0] = 1.0;
10402 values[1] = 1.0;
10403 values[2] = 0.0;
10404 values[3] = 0.0;
10405 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10406 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10407 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10408 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10409 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10411 values[0] = -1.0;
10412 values[1] = 0.0;
10413 values[2] = 0.0;
10414 values[3] = 0.0;
10415 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10416 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10417 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10418 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10419 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10420 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10421 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10422 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10423 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10424 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10426 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10429 hr = IDirect3DDevice9_BeginScene(device);
10430 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10431 if(SUCCEEDED(hr))
10433 trace("going to draw index\n");
10434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10435 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10436 hr = IDirect3DDevice9_EndScene(device);
10437 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10439 color = getPixelColor(device, 320, 240);
10440 ok(color_match(color, 0x0000ff00, 1),
10441 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10442 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10443 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10445 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10446 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10447 IDirect3DVertexShader9_Release(shader);
10450 static void sgn_test(IDirect3DDevice9 *device) {
10451 const DWORD shader_code[] = {
10452 0xfffe0200, /* vs_2_0 */
10453 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10454 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10455 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10456 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10457 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10458 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10459 0x0000ffff /* end */
10461 IDirect3DVertexShader9 *shader;
10462 HRESULT hr;
10463 DWORD color;
10464 const float quad[] = {
10465 -1.0, -1.0, 0.1,
10466 1.0, -1.0, 0.1,
10467 -1.0, 1.0, 0.1,
10468 1.0, 1.0, 0.1
10471 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10472 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10473 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10474 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10475 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10476 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10477 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10478 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10480 hr = IDirect3DDevice9_BeginScene(device);
10481 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10482 if(SUCCEEDED(hr))
10484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10485 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10486 hr = IDirect3DDevice9_EndScene(device);
10487 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10489 color = getPixelColor(device, 320, 240);
10490 ok(color_match(color, 0x008000ff, 1),
10491 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10493 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10495 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10496 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10497 IDirect3DVertexShader9_Release(shader);
10500 static void viewport_test(IDirect3DDevice9 *device) {
10501 HRESULT hr;
10502 DWORD color;
10503 D3DVIEWPORT9 vp, old_vp;
10504 const float quad[] =
10506 -0.5, -0.5, 0.1,
10507 0.5, -0.5, 0.1,
10508 -0.5, 0.5, 0.1,
10509 0.5, 0.5, 0.1
10512 memset(&old_vp, 0, sizeof(old_vp));
10513 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10514 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10516 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10517 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10519 /* Test a viewport with Width and Height bigger than the surface dimensions
10521 * TODO: Test Width < surface.width, but X + Width > surface.width
10522 * TODO: Test Width < surface.width, what happens with the height?
10524 memset(&vp, 0, sizeof(vp));
10525 vp.X = 0;
10526 vp.Y = 0;
10527 vp.Width = 10000;
10528 vp.Height = 10000;
10529 vp.MinZ = 0.0;
10530 vp.MaxZ = 0.0;
10531 hr = IDirect3DDevice9_SetViewport(device, &vp);
10532 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10534 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10535 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10536 hr = IDirect3DDevice9_BeginScene(device);
10537 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10538 if(SUCCEEDED(hr))
10540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10541 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10542 hr = IDirect3DDevice9_EndScene(device);
10543 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10546 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10547 color = getPixelColor(device, 158, 118);
10548 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10549 color = getPixelColor(device, 162, 118);
10550 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10551 color = getPixelColor(device, 158, 122);
10552 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10553 color = getPixelColor(device, 162, 122);
10554 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10556 color = getPixelColor(device, 478, 358);
10557 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10558 color = getPixelColor(device, 482, 358);
10559 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10560 color = getPixelColor(device, 478, 362);
10561 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10562 color = getPixelColor(device, 482, 362);
10563 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10566 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10568 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10569 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10572 START_TEST(visual)
10574 IDirect3DDevice9 *device_ptr;
10575 D3DCAPS9 caps;
10576 HRESULT hr;
10577 DWORD color;
10579 d3d9_handle = LoadLibraryA("d3d9.dll");
10580 if (!d3d9_handle)
10582 skip("Could not load d3d9.dll\n");
10583 return;
10586 device_ptr = init_d3d9();
10587 if (!device_ptr)
10589 skip("Creating the device failed\n");
10590 return;
10593 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10595 /* Check for the reliability of the returned data */
10596 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10597 if(FAILED(hr))
10599 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10600 goto cleanup;
10603 color = getPixelColor(device_ptr, 1, 1);
10604 if(color !=0x00ff0000)
10606 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10607 goto cleanup;
10609 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10611 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10612 if(FAILED(hr))
10614 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10615 goto cleanup;
10618 color = getPixelColor(device_ptr, 639, 479);
10619 if(color != 0x0000ddee)
10621 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10622 goto cleanup;
10624 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10626 /* Now execute the real tests */
10627 stretchrect_test(device_ptr);
10628 lighting_test(device_ptr);
10629 clear_test(device_ptr);
10630 fog_test(device_ptr);
10631 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10633 test_cube_wrap(device_ptr);
10634 } else {
10635 skip("No cube texture support\n");
10637 z_range_test(device_ptr);
10638 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10640 maxmip_test(device_ptr);
10642 else
10644 skip("No mipmap support\n");
10646 offscreen_test(device_ptr);
10647 alpha_test(device_ptr);
10648 shademode_test(device_ptr);
10649 srgbtexture_test(device_ptr);
10650 release_buffer_test(device_ptr);
10651 float_texture_test(device_ptr);
10652 g16r16_texture_test(device_ptr);
10653 pixelshader_blending_test(device_ptr);
10654 texture_transform_flags_test(device_ptr);
10655 autogen_mipmap_test(device_ptr);
10656 fixed_function_decl_test(device_ptr);
10657 conditional_np2_repeat_test(device_ptr);
10658 fixed_function_bumpmap_test(device_ptr);
10659 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10660 stencil_cull_test(device_ptr);
10661 } else {
10662 skip("No two sided stencil support\n");
10664 pointsize_test(device_ptr);
10665 tssargtemp_test(device_ptr);
10666 np2_stretch_rect_test(device_ptr);
10667 yuv_color_test(device_ptr);
10668 zwriteenable_test(device_ptr);
10669 alphatest_test(device_ptr);
10670 viewport_test(device_ptr);
10672 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10674 test_constant_clamp_vs(device_ptr);
10675 test_compare_instructions(device_ptr);
10677 else skip("No vs_1_1 support\n");
10679 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10681 test_mova(device_ptr);
10682 loop_index_test(device_ptr);
10683 sincos_test(device_ptr);
10684 sgn_test(device_ptr);
10685 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10686 test_vshader_input(device_ptr);
10687 test_vshader_float16(device_ptr);
10688 stream_test(device_ptr);
10689 } else {
10690 skip("No vs_3_0 support\n");
10693 else skip("No vs_2_0 support\n");
10695 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10697 fog_with_shader_test(device_ptr);
10698 fog_srgbwrite_test(device_ptr);
10700 else skip("No vs_1_1 and ps_1_1 support\n");
10702 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10704 texbem_test(device_ptr);
10705 texdepth_test(device_ptr);
10706 texkill_test(device_ptr);
10707 x8l8v8u8_test(device_ptr);
10708 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10709 constant_clamp_ps_test(device_ptr);
10710 cnd_test(device_ptr);
10711 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10712 dp2add_ps_test(device_ptr);
10713 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10714 nested_loop_test(device_ptr);
10715 fixed_function_varying_test(device_ptr);
10716 vFace_register_test(device_ptr);
10717 vpos_register_test(device_ptr);
10718 multiple_rendertargets_test(device_ptr);
10719 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10720 vshader_version_varying_test(device_ptr);
10721 pshader_version_varying_test(device_ptr);
10722 } else {
10723 skip("No vs_3_0 support\n");
10725 } else {
10726 skip("No ps_3_0 support\n");
10728 } else {
10729 skip("No ps_2_0 support\n");
10733 else skip("No ps_1_1 support\n");
10735 texop_test(device_ptr);
10736 texop_range_test(device_ptr);
10737 alphareplicate_test(device_ptr);
10738 dp3_alpha_test(device_ptr);
10740 cleanup:
10741 if(device_ptr) {
10742 D3DPRESENT_PARAMETERS present_parameters;
10743 IDirect3DSwapChain9 *swapchain;
10744 ULONG ref;
10746 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10747 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10748 DestroyWindow(present_parameters.hDeviceWindow);
10749 IDirect3DSwapChain9_Release(swapchain);
10750 ref = IDirect3DDevice9_Release(device_ptr);
10751 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);