hnetcfg: Improve the stub for INetFwServices::Item.
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob22d512e2b58485b9ec79f8c278ffdfdfe30e37d0
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 c1 >>= 8; c2 >>= 8;
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55 c1 >>= 8; c2 >>= 8;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 c1 >>= 8; c2 >>= 8;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59 return TRUE;
62 /* Locks a given surface and returns the color at (x,y). It's the caller's
63 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 DWORD color;
67 HRESULT hr;
68 D3DSURFACE_DESC desc;
69 RECT rectToLock = {x, y, x+1, y+1};
70 D3DLOCKED_RECT lockedRect;
72 hr = IDirect3DSurface9_GetDesc(surface, &desc);
73 if(FAILED(hr)) /* This is not a test */
75 trace("Can't get the surface description, hr=%08x\n", hr);
76 return 0xdeadbeef;
79 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80 if(FAILED(hr)) /* This is not a test */
82 trace("Can't lock the surface, hr=%08x\n", hr);
83 return 0xdeadbeef;
85 switch(desc.Format) {
86 case D3DFMT_A8R8G8B8:
88 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89 break;
91 default:
92 trace("Error: unknown surface format: %d\n", desc.Format);
93 color = 0xdeadbeef;
94 break;
96 hr = IDirect3DSurface9_UnlockRect(surface);
97 if(FAILED(hr))
99 trace("Can't unlock the surface, hr=%08x\n", hr);
101 return color;
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 DWORD ret;
107 IDirect3DSurface9 *surf;
108 HRESULT hr;
109 D3DLOCKED_RECT lockedRect;
110 RECT rectToLock = {x, y, x+1, y+1};
112 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113 if(FAILED(hr) || !surf ) /* This is not a test */
115 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116 return 0xdeadbeef;
119 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120 if(FAILED(hr))
122 trace("Can't read the front buffer data, hr=%08x\n", hr);
123 ret = 0xdeadbeed;
124 goto out;
127 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128 if(FAILED(hr))
130 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131 ret = 0xdeadbeec;
132 goto out;
135 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136 * really important for these tests
138 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139 hr = IDirect3DSurface9_UnlockRect(surf);
140 if(FAILED(hr))
142 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
145 out:
146 if(surf) IDirect3DSurface9_Release(surf);
147 return ret;
150 static IDirect3DDevice9 *init_d3d9(void)
152 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153 IDirect3D9 *d3d9_ptr = 0;
154 IDirect3DDevice9 *device_ptr = 0;
155 D3DPRESENT_PARAMETERS present_parameters;
156 HRESULT hr;
157 D3DADAPTER_IDENTIFIER9 identifier;
159 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161 if (!d3d9_create) return NULL;
163 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164 if (!d3d9_ptr)
166 skip("could not create D3D9\n");
167 return NULL;
170 ZeroMemory(&present_parameters, sizeof(present_parameters));
171 present_parameters.Windowed = FALSE;
172 present_parameters.hDeviceWindow = create_window();
173 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174 present_parameters.BackBufferWidth = 640;
175 present_parameters.BackBufferHeight = 480;
176 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177 present_parameters.EnableAutoDepthStencil = TRUE;
178 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
180 memset(&identifier, 0, sizeof(identifier));
181 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183 trace("Driver string: \"%s\"\n", identifier.Driver);
184 trace("Description string: \"%s\"\n", identifier.Description);
185 ok(identifier.Description[0] != '\0', "Empty driver description\n");
186 trace("Device name string: \"%s\"\n", identifier.DeviceName);
187 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
188 trace("Driver version %d.%d.%d.%d\n",
189 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
190 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
192 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
193 if(FAILED(hr)) {
194 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
195 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196 if(FAILED(hr)) {
197 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
200 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
202 return device_ptr;
205 struct vertex
207 float x, y, z;
208 DWORD diffuse;
211 struct tvertex
213 float x, y, z, rhw;
214 DWORD diffuse;
217 struct nvertex
219 float x, y, z;
220 float nx, ny, nz;
221 DWORD diffuse;
224 static void lighting_test(IDirect3DDevice9 *device)
226 HRESULT hr;
227 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
228 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
229 DWORD color;
230 D3DMATERIAL9 material, old_material;
231 DWORD cop, carg;
233 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
234 0.0f, 1.0f, 0.0f, 0.0f,
235 0.0f, 0.0f, 1.0f, 0.0f,
236 0.0f, 0.0f, 0.0f, 1.0f };
238 struct vertex unlitquad[] =
240 {-1.0f, -1.0f, 0.1f, 0xffff0000},
241 {-1.0f, 0.0f, 0.1f, 0xffff0000},
242 { 0.0f, 0.0f, 0.1f, 0xffff0000},
243 { 0.0f, -1.0f, 0.1f, 0xffff0000},
245 struct vertex litquad[] =
247 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
248 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
249 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
250 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
252 struct nvertex unlitnquad[] =
254 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
255 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
256 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
257 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
259 struct nvertex litnquad[] =
261 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
262 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
263 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
264 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
266 WORD Indices[] = {0, 1, 2, 2, 3, 0};
268 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
269 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
271 /* Setup some states that may cause issues */
272 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
297 hr = IDirect3DDevice9_SetFVF(device, 0);
298 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetFVF(device, fvf);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
303 hr = IDirect3DDevice9_BeginScene(device);
304 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
305 if(hr == D3D_OK)
307 /* No lights are defined... That means, lit vertices should be entirely black */
308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
310 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
312 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
318 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
320 hr = IDirect3DDevice9_SetFVF(device, nfvf);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
324 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
327 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
331 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
332 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
333 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
335 IDirect3DDevice9_EndScene(device);
336 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
339 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
341 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
342 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
343 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
344 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
345 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
346 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
347 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
348 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
350 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
351 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
352 memset(&material, 0, sizeof(material));
353 material.Diffuse.r = 0.0;
354 material.Diffuse.g = 0.0;
355 material.Diffuse.b = 0.0;
356 material.Diffuse.a = 1.0;
357 material.Ambient.r = 0.0;
358 material.Ambient.g = 0.0;
359 material.Ambient.b = 0.0;
360 material.Ambient.a = 0.0;
361 material.Specular.r = 0.0;
362 material.Specular.g = 0.0;
363 material.Specular.b = 0.0;
364 material.Specular.a = 0.0;
365 material.Emissive.r = 0.0;
366 material.Emissive.g = 0.0;
367 material.Emissive.b = 0.0;
368 material.Emissive.a = 0.0;
369 material.Power = 0.0;
370 IDirect3DDevice9_SetMaterial(device, &material);
371 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
374 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
376 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
378 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
379 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
381 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
382 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
383 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
384 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
385 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
387 hr = IDirect3DDevice9_BeginScene(device);
388 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
389 if(SUCCEEDED(hr)) {
390 struct vertex lighting_test[] = {
391 {-1.0, -1.0, 0.1, 0x8000ff00},
392 { 1.0, -1.0, 0.1, 0x80000000},
393 {-1.0, 1.0, 0.1, 0x8000ff00},
394 { 1.0, 1.0, 0.1, 0x80000000}
396 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
397 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
401 hr = IDirect3DDevice9_EndScene(device);
402 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
405 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
406 color = getPixelColor(device, 320, 240);
407 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
409 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
410 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
414 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
417 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
418 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
419 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
423 static void clear_test(IDirect3DDevice9 *device)
425 /* Tests the correctness of clearing parameters */
426 HRESULT hr;
427 D3DRECT rect[2];
428 D3DRECT rect_negneg;
429 DWORD color;
430 D3DVIEWPORT9 old_vp, vp;
431 RECT scissor;
432 DWORD oldColorWrite;
433 BOOL invalid_clear_failed = FALSE;
435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
436 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
438 /* Positive x, negative y */
439 rect[0].x1 = 0;
440 rect[0].y1 = 480;
441 rect[0].x2 = 320;
442 rect[0].y2 = 240;
444 /* Positive x, positive y */
445 rect[1].x1 = 0;
446 rect[1].y1 = 0;
447 rect[1].x2 = 320;
448 rect[1].y2 = 240;
449 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
450 * returns D3D_OK, but ignores the rectangle silently
452 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
453 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
454 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
456 /* negative x, negative y */
457 rect_negneg.x1 = 640;
458 rect_negneg.y1 = 240;
459 rect_negneg.x2 = 320;
460 rect_negneg.y2 = 0;
461 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
462 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
463 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
467 color = getPixelColor(device, 160, 360); /* lower left quad */
468 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
469 color = getPixelColor(device, 160, 120); /* upper left quad */
470 if(invalid_clear_failed) {
471 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
472 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
473 } else {
474 /* If the negative rectangle was dropped silently, the correct ones are cleared */
475 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
477 color = getPixelColor(device, 480, 360); /* lower right quad */
478 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
479 color = getPixelColor(device, 480, 120); /* upper right quad */
480 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
482 /* Test how the viewport affects clears */
483 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
484 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
485 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
486 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
488 vp.X = 160;
489 vp.Y = 120;
490 vp.Width = 160;
491 vp.Height = 120;
492 vp.MinZ = 0.0;
493 vp.MaxZ = 1.0;
494 hr = IDirect3DDevice9_SetViewport(device, &vp);
495 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
496 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
497 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
499 vp.X = 320;
500 vp.Y = 240;
501 vp.Width = 320;
502 vp.Height = 240;
503 vp.MinZ = 0.0;
504 vp.MaxZ = 1.0;
505 hr = IDirect3DDevice9_SetViewport(device, &vp);
506 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
507 rect[0].x1 = 160;
508 rect[0].y1 = 120;
509 rect[0].x2 = 480;
510 rect[0].y2 = 360;
511 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
512 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
514 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
515 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
518 color = getPixelColor(device, 158, 118);
519 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
520 color = getPixelColor(device, 162, 118);
521 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
522 color = getPixelColor(device, 158, 122);
523 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
524 color = getPixelColor(device, 162, 122);
525 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
527 color = getPixelColor(device, 318, 238);
528 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
529 color = getPixelColor(device, 322, 238);
530 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
531 color = getPixelColor(device, 318, 242);
532 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
533 color = getPixelColor(device, 322, 242);
534 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
536 color = getPixelColor(device, 478, 358);
537 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
538 color = getPixelColor(device, 482, 358);
539 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
540 color = getPixelColor(device, 478, 362);
541 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
542 color = getPixelColor(device, 482, 362);
543 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
545 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
546 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
548 scissor.left = 160;
549 scissor.right = 480;
550 scissor.top = 120;
551 scissor.bottom = 360;
552 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
553 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
555 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
557 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
558 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
563 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566 color = getPixelColor(device, 158, 118);
567 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
568 color = getPixelColor(device, 162, 118);
569 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
570 color = getPixelColor(device, 158, 122);
571 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
572 color = getPixelColor(device, 162, 122);
573 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
575 color = getPixelColor(device, 158, 358);
576 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
577 color = getPixelColor(device, 162, 358);
578 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
579 color = getPixelColor(device, 158, 358);
580 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
581 color = getPixelColor(device, 162, 362);
582 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
584 color = getPixelColor(device, 478, 118);
585 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
586 color = getPixelColor(device, 478, 122);
587 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
588 color = getPixelColor(device, 482, 122);
589 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
590 color = getPixelColor(device, 482, 358);
591 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
593 color = getPixelColor(device, 478, 358);
594 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
595 color = getPixelColor(device, 478, 362);
596 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
597 color = getPixelColor(device, 482, 358);
598 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
599 color = getPixelColor(device, 482, 362);
600 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
602 color = getPixelColor(device, 318, 238);
603 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
604 color = getPixelColor(device, 318, 242);
605 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
606 color = getPixelColor(device, 322, 238);
607 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
608 color = getPixelColor(device, 322, 242);
609 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
611 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
612 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
614 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
622 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
624 /* Colorwriteenable does not affect the clear */
625 color = getPixelColor(device, 320, 240);
626 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
629 typedef struct {
630 float in[4];
631 DWORD out;
632 } test_data_t;
635 * c7 mova ARGB mov ARGB
636 * -2.4 -2 0x00ffff00 -3 0x00ff0000
637 * -1.6 -2 0x00ffff00 -2 0x00ffff00
638 * -0.4 0 0x0000ffff -1 0x0000ff00
639 * 0.4 0 0x0000ffff 0 0x0000ffff
640 * 1.6 2 0x00ff00ff 1 0x000000ff
641 * 2.4 2 0x00ff00ff 2 0x00ff00ff
643 static void test_mova(IDirect3DDevice9 *device)
645 static const DWORD mova_test[] = {
646 0xfffe0200, /* vs_2_0 */
647 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
648 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
649 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
650 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
651 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
652 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
653 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
654 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
655 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
656 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
657 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
658 0x0000ffff /* END */
660 static const DWORD mov_test[] = {
661 0xfffe0101, /* vs_1_1 */
662 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
663 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
664 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
665 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
666 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
667 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
668 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
669 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
670 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
671 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
672 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
673 0x0000ffff /* END */
676 static const test_data_t test_data[2][6] = {
678 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
679 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
680 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
681 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
682 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
683 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
686 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
687 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
688 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
689 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
690 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
691 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
695 static const float quad[][3] = {
696 {-1.0f, -1.0f, 0.0f},
697 {-1.0f, 1.0f, 0.0f},
698 { 1.0f, -1.0f, 0.0f},
699 { 1.0f, 1.0f, 0.0f},
702 static const D3DVERTEXELEMENT9 decl_elements[] = {
703 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
704 D3DDECL_END()
707 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
708 IDirect3DVertexShader9 *mova_shader = NULL;
709 IDirect3DVertexShader9 *mov_shader = NULL;
710 HRESULT hr;
711 UINT i, j;
713 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
714 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
716 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
717 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
718 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
719 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
720 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
722 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
723 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
724 for(j = 0; j < 2; ++j)
726 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
728 DWORD color;
730 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
731 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
733 hr = IDirect3DDevice9_BeginScene(device);
734 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
737 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
739 hr = IDirect3DDevice9_EndScene(device);
740 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
743 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
745 color = getPixelColor(device, 320, 240);
746 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
747 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
749 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
750 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
752 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
753 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
756 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
757 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
759 IDirect3DVertexDeclaration9_Release(vertex_declaration);
760 IDirect3DVertexShader9_Release(mova_shader);
761 IDirect3DVertexShader9_Release(mov_shader);
764 struct sVertex {
765 float x, y, z;
766 DWORD diffuse;
767 DWORD specular;
770 struct sVertexT {
771 float x, y, z, rhw;
772 DWORD diffuse;
773 DWORD specular;
776 static void fog_test(IDirect3DDevice9 *device)
778 HRESULT hr;
779 D3DCOLOR color;
780 float start = 0.0f, end = 1.0f;
781 D3DCAPS9 caps;
782 int i;
784 /* Gets full z based fog with linear fog, no fog with specular color */
785 struct sVertex unstransformed_1[] = {
786 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
787 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
788 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
789 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
791 /* Ok, I am too lazy to deal with transform matrices */
792 struct sVertex unstransformed_2[] = {
793 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
794 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
795 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
796 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
798 /* Untransformed ones. Give them a different diffuse color to make the test look
799 * nicer. It also makes making sure that they are drawn correctly easier.
801 struct sVertexT transformed_1[] = {
802 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
803 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
804 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
805 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
807 struct sVertexT transformed_2[] = {
808 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
809 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
810 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
811 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
813 struct vertex rev_fog_quads[] = {
814 {-1.0, -1.0, 0.1, 0x000000ff},
815 {-1.0, 0.0, 0.1, 0x000000ff},
816 { 0.0, 0.0, 0.1, 0x000000ff},
817 { 0.0, -1.0, 0.1, 0x000000ff},
819 { 0.0, -1.0, 0.9, 0x000000ff},
820 { 0.0, 0.0, 0.9, 0x000000ff},
821 { 1.0, 0.0, 0.9, 0x000000ff},
822 { 1.0, -1.0, 0.9, 0x000000ff},
824 { 0.0, 0.0, 0.4, 0x000000ff},
825 { 0.0, 1.0, 0.4, 0x000000ff},
826 { 1.0, 1.0, 0.4, 0x000000ff},
827 { 1.0, 0.0, 0.4, 0x000000ff},
829 {-1.0, 0.0, 0.7, 0x000000ff},
830 {-1.0, 1.0, 0.7, 0x000000ff},
831 { 0.0, 1.0, 0.7, 0x000000ff},
832 { 0.0, 0.0, 0.7, 0x000000ff},
834 WORD Indices[] = {0, 1, 2, 2, 3, 0};
836 memset(&caps, 0, sizeof(caps));
837 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
838 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
840 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
842 /* Setup initial states: No lighting, fog on, fog color */
843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
844 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
846 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
848 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
850 /* First test: Both table fog and vertex fog off */
851 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
852 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
854 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
856 /* Start = 0, end = 1. Should be default, but set them */
857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
858 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
860 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
862 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
864 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
865 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
866 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
867 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
868 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
869 sizeof(unstransformed_1[0]));
870 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
872 /* That makes it use the Z value */
873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
874 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
875 /* Untransformed, vertex fog != none (or table fog != none):
876 * Use the Z value as input into the equation
878 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
879 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
880 sizeof(unstransformed_1[0]));
881 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
883 /* transformed verts */
884 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
885 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
886 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
887 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
888 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
889 sizeof(transformed_1[0]));
890 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
893 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
894 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
895 * equation
897 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
898 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
899 sizeof(transformed_2[0]));
900 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
902 hr = IDirect3DDevice9_EndScene(device);
903 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
905 else
907 ok(FALSE, "BeginScene failed\n");
910 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
911 color = getPixelColor(device, 160, 360);
912 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
913 color = getPixelColor(device, 160, 120);
914 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
915 color = getPixelColor(device, 480, 120);
916 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
917 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
919 color = getPixelColor(device, 480, 360);
920 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
922 else
924 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
925 * The settings above result in no fogging with vertex fog
927 color = getPixelColor(device, 480, 120);
928 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
929 trace("Info: Table fog not supported by this device\n");
932 /* Now test the special case fogstart == fogend */
933 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
934 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
936 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
938 start = 512;
939 end = 512;
940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
941 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
943 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
946 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
948 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
950 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
952 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
953 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
954 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
955 * The third transformed quad remains unfogged because the fogcoords are read from the specular
956 * color and has fixed fogstart and fogend.
958 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
959 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
960 sizeof(unstransformed_1[0]));
961 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
962 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
964 sizeof(unstransformed_1[0]));
965 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
967 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
968 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
969 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
970 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
971 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
972 sizeof(transformed_1[0]));
973 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
975 hr = IDirect3DDevice9_EndScene(device);
976 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
978 else
980 ok(FALSE, "BeginScene failed\n");
982 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
983 color = getPixelColor(device, 160, 360);
984 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
985 color = getPixelColor(device, 160, 120);
986 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
987 color = getPixelColor(device, 480, 120);
988 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
990 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
991 * but without shaders it seems to work everywhere
993 end = 0.2;
994 start = 0.8;
995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
996 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
998 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
999 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1000 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1002 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1003 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1004 * so skip this for now
1006 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1007 const char *mode = (i ? "table" : "vertex");
1008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1009 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1011 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1013 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1014 hr = IDirect3DDevice9_BeginScene(device);
1015 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1016 if(SUCCEEDED(hr)) {
1017 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1018 4, 5, 6, 6, 7, 4,
1019 8, 9, 10, 10, 11, 8,
1020 12, 13, 14, 14, 15, 12};
1022 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1023 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1024 sizeof(rev_fog_quads[0]));
1025 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1027 hr = IDirect3DDevice9_EndScene(device);
1028 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1030 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1031 color = getPixelColor(device, 160, 360);
1032 ok(color_match(color, 0x0000ff00, 1),
1033 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1035 color = getPixelColor(device, 160, 120);
1036 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1037 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1039 color = getPixelColor(device, 480, 120);
1040 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1041 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1043 color = getPixelColor(device, 480, 360);
1044 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1046 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1047 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1048 break;
1051 /* Turn off the fog master switch to avoid confusing other tests */
1052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1053 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1054 start = 0.0;
1055 end = 1.0;
1056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1057 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1059 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1061 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1063 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1066 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1067 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1068 * regardless of the actual addressing mode set. */
1069 static void test_cube_wrap(IDirect3DDevice9 *device)
1071 static const float quad[][6] = {
1072 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1073 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1074 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1075 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1078 static const D3DVERTEXELEMENT9 decl_elements[] = {
1079 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1080 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1081 D3DDECL_END()
1084 static const struct {
1085 D3DTEXTUREADDRESS mode;
1086 const char *name;
1087 } address_modes[] = {
1088 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1089 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1090 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1091 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1092 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1095 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1096 IDirect3DCubeTexture9 *texture = NULL;
1097 IDirect3DSurface9 *surface = NULL;
1098 D3DLOCKED_RECT locked_rect;
1099 HRESULT hr;
1100 UINT x;
1101 INT y, face;
1103 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1104 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1105 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1106 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1108 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1109 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1110 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1112 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1113 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1115 for (y = 0; y < 128; ++y)
1117 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1118 for (x = 0; x < 64; ++x)
1120 *ptr++ = 0xffff0000;
1122 for (x = 64; x < 128; ++x)
1124 *ptr++ = 0xff0000ff;
1128 hr = IDirect3DSurface9_UnlockRect(surface);
1129 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1131 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1132 D3DPOOL_DEFAULT, &texture, NULL);
1133 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1135 /* Create cube faces */
1136 for (face = 0; face < 6; ++face)
1138 IDirect3DSurface9 *face_surface = NULL;
1140 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1141 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1143 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1144 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1146 IDirect3DSurface9_Release(face_surface);
1149 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1150 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1152 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1153 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1154 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1155 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1156 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1157 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1159 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1160 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1162 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1164 DWORD color;
1166 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1167 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1168 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1169 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1171 hr = IDirect3DDevice9_BeginScene(device);
1172 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1175 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1177 hr = IDirect3DDevice9_EndScene(device);
1178 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1180 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1181 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1183 /* Due to the nature of this test, we sample essentially at the edge
1184 * between two faces. Because of this it's undefined from which face
1185 * the driver will sample. Fortunately that's not important for this
1186 * test, since all we care about is that it doesn't sample from the
1187 * other side of the surface or from the border. */
1188 color = getPixelColor(device, 320, 240);
1189 ok(color == 0x00ff0000 || color == 0x000000ff,
1190 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1191 color, address_modes[x].name);
1193 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1194 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1197 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1198 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1200 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1201 IDirect3DCubeTexture9_Release(texture);
1202 IDirect3DSurface9_Release(surface);
1205 static void offscreen_test(IDirect3DDevice9 *device)
1207 HRESULT hr;
1208 IDirect3DTexture9 *offscreenTexture = NULL;
1209 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1210 DWORD color;
1212 static const float quad[][5] = {
1213 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1214 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1215 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1216 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1220 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1222 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1223 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1224 if(!offscreenTexture) {
1225 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1226 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1227 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1228 if(!offscreenTexture) {
1229 skip("Cannot create an offscreen render target\n");
1230 goto out;
1234 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1235 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1236 if(!backbuffer) {
1237 goto out;
1240 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1241 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1242 if(!offscreen) {
1243 goto out;
1246 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1247 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1249 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1250 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1251 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1252 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1253 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1254 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1255 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1256 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1258 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1260 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1261 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1262 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1264 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1266 /* Draw without textures - Should result in a white quad */
1267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1268 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1270 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1271 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1272 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1273 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1275 /* This time with the texture */
1276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1277 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1279 IDirect3DDevice9_EndScene(device);
1282 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1284 /* Center quad - should be white */
1285 color = getPixelColor(device, 320, 240);
1286 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1287 /* Some quad in the cleared part of the texture */
1288 color = getPixelColor(device, 170, 240);
1289 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1290 /* Part of the originally cleared back buffer */
1291 color = getPixelColor(device, 10, 10);
1292 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1293 if(0) {
1294 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1295 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1296 * the offscreen rendering mode this test would succeed or fail
1298 color = getPixelColor(device, 10, 470);
1299 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1302 out:
1303 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1306 /* restore things */
1307 if(backbuffer) {
1308 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1309 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1310 IDirect3DSurface9_Release(backbuffer);
1312 if(offscreenTexture) {
1313 IDirect3DTexture9_Release(offscreenTexture);
1315 if(offscreen) {
1316 IDirect3DSurface9_Release(offscreen);
1320 /* This test tests fog in combination with shaders.
1321 * What's tested: linear fog (vertex and table) with pixel shader
1322 * linear table fog with non foggy vertex shader
1323 * vertex fog with foggy vertex shader, non-linear
1324 * fog with shader, non-linear fog with foggy shader,
1325 * linear table fog with foggy shader
1327 static void fog_with_shader_test(IDirect3DDevice9 *device)
1329 HRESULT hr;
1330 DWORD color;
1331 union {
1332 float f;
1333 DWORD i;
1334 } start, end;
1335 unsigned int i, j;
1337 /* basic vertex shader without fog computation ("non foggy") */
1338 static const DWORD vertex_shader_code1[] = {
1339 0xfffe0101, /* vs_1_1 */
1340 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1341 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1342 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1343 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1344 0x0000ffff
1346 /* basic vertex shader with reversed fog computation ("foggy") */
1347 static const DWORD vertex_shader_code2[] = {
1348 0xfffe0101, /* vs_1_1 */
1349 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1350 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1351 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1352 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1353 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1354 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1355 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1356 0x0000ffff
1358 /* basic pixel shader */
1359 static const DWORD pixel_shader_code[] = {
1360 0xffff0101, /* ps_1_1 */
1361 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1362 0x0000ffff
1365 static struct vertex quad[] = {
1366 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1367 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1368 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1369 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1372 static const D3DVERTEXELEMENT9 decl_elements[] = {
1373 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1374 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1375 D3DDECL_END()
1378 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1379 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1380 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1382 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1383 static const struct test_data_t {
1384 int vshader;
1385 int pshader;
1386 D3DFOGMODE vfog;
1387 D3DFOGMODE tfog;
1388 unsigned int color[11];
1389 } test_data[] = {
1390 /* only pixel shader: */
1391 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1392 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1395 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1398 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1401 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1404 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1405 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407 /* vertex shader */
1408 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1409 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1410 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1411 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1412 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1415 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1419 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1422 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1423 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1425 /* vertex shader and pixel shader */
1426 /* The next 4 tests would read the fog coord output, but it isn't available.
1427 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1428 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1429 * These tests should be disabled if some other hardware behaves differently
1431 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1432 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1433 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1434 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1435 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1436 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1437 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1438 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1439 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1440 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1441 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1442 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1444 /* These use the Z coordinate with linear table fog */
1445 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1446 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1447 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1448 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1449 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1450 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1451 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1452 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1453 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1454 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1455 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1456 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1458 /* Non-linear table fog without fog coord */
1459 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1460 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1461 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1462 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1463 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1464 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1466 #if 0 /* FIXME: these fail on GeForce 8500 */
1467 /* foggy vertex shader */
1468 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1469 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1470 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1471 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1472 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1473 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1474 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1475 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1476 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1477 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1478 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1479 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1480 #endif
1482 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1483 * all using the fixed fog-coord linear fog
1485 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1486 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1487 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1488 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1489 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1490 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1491 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1492 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1493 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1494 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1495 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1496 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1498 /* These use table fog. Here the shader-provided fog coordinate is
1499 * ignored and the z coordinate used instead
1501 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1502 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1503 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1504 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1505 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1506 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1507 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1508 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1509 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1513 start.f=0.1f;
1514 end.f=0.9f;
1516 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1517 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1518 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1519 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1520 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1521 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1522 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1523 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1525 /* Setup initial states: No lighting, fog on, fog color */
1526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1527 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1529 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1531 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1532 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1533 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1536 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1538 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1540 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1542 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1544 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1546 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1548 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1549 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1550 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1551 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1553 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1555 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1557 for(j=0; j < 11; j++)
1559 /* Don't use the whole zrange to prevent rounding errors */
1560 quad[0].z = 0.001f + (float)j / 10.02f;
1561 quad[1].z = 0.001f + (float)j / 10.02f;
1562 quad[2].z = 0.001f + (float)j / 10.02f;
1563 quad[3].z = 0.001f + (float)j / 10.02f;
1565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1566 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1568 hr = IDirect3DDevice9_BeginScene(device);
1569 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1572 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1574 hr = IDirect3DDevice9_EndScene(device);
1575 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1577 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1579 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1580 color = getPixelColor(device, 128, 240);
1581 ok(color_match(color, test_data[i].color[j], 13),
1582 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1583 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1587 /* reset states */
1588 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1589 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1590 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1591 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1592 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1593 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1595 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1597 IDirect3DVertexShader9_Release(vertex_shader[1]);
1598 IDirect3DVertexShader9_Release(vertex_shader[2]);
1599 IDirect3DPixelShader9_Release(pixel_shader[1]);
1600 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1603 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1604 unsigned int i, x, y;
1605 HRESULT hr;
1606 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1607 D3DLOCKED_RECT locked_rect;
1609 /* Generate the textures */
1610 for(i=0; i<2; i++)
1612 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1613 D3DPOOL_MANAGED, &texture[i], NULL);
1614 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1616 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1617 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1618 for (y = 0; y < 128; ++y)
1620 if(i)
1621 { /* Set up black texture with 2x2 texel white spot in the middle */
1622 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1623 for (x = 0; x < 128; ++x)
1625 if(y>62 && y<66 && x>62 && x<66)
1626 *ptr++ = 0xffffffff;
1627 else
1628 *ptr++ = 0xff000000;
1631 else
1632 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1633 * (if multiplied with bumpenvmat)
1635 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1636 for (x = 0; x < 128; ++x)
1638 if(abs(x-64)>abs(y-64))
1640 if(x < 64)
1641 *ptr++ = 0xc000;
1642 else
1643 *ptr++ = 0x4000;
1645 else
1647 if(y < 64)
1648 *ptr++ = 0x0040;
1649 else
1650 *ptr++ = 0x00c0;
1655 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1656 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1658 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1659 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1661 /* Disable texture filtering */
1662 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1663 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1664 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1665 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1667 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1668 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1669 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1670 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1674 /* test the behavior of the texbem instruction
1675 * with normal 2D and projective 2D textures
1677 static void texbem_test(IDirect3DDevice9 *device)
1679 HRESULT hr;
1680 DWORD color;
1681 int i;
1683 static const DWORD pixel_shader_code[] = {
1684 0xffff0101, /* ps_1_1*/
1685 0x00000042, 0xb00f0000, /* tex t0*/
1686 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1687 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1688 0x0000ffff
1690 static const DWORD double_texbem_code[] = {
1691 0xffff0103, /* ps_1_3 */
1692 0x00000042, 0xb00f0000, /* tex t0 */
1693 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1694 0x00000042, 0xb00f0002, /* tex t2 */
1695 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1696 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1697 0x0000ffff /* end */
1701 static const float quad[][7] = {
1702 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1703 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1704 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1705 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1707 static const float quad_proj[][9] = {
1708 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1709 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1710 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1711 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1714 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1715 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1716 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1717 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1718 D3DDECL_END()
1720 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1721 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1722 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1723 D3DDECL_END()
1724 } };
1726 /* use asymmetric matrix to test loading */
1727 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1729 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1730 IDirect3DPixelShader9 *pixel_shader = NULL;
1731 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1732 D3DLOCKED_RECT locked_rect;
1734 generate_bumpmap_textures(device);
1736 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1737 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1738 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1739 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1740 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1742 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1743 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1748 for(i=0; i<2; i++)
1750 if(i)
1752 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1753 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1756 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1757 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1758 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1759 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1761 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1762 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1763 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1764 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1766 hr = IDirect3DDevice9_BeginScene(device);
1767 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1769 if(!i)
1770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1771 else
1772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1773 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1775 hr = IDirect3DDevice9_EndScene(device);
1776 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1779 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1781 color = getPixelColor(device, 320-32, 240);
1782 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783 color = getPixelColor(device, 320+32, 240);
1784 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1785 color = getPixelColor(device, 320, 240-32);
1786 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1787 color = getPixelColor(device, 320, 240+32);
1788 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1790 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1791 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1792 IDirect3DPixelShader9_Release(pixel_shader);
1794 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1795 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1796 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1799 /* clean up */
1800 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1801 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1803 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1804 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1806 for(i=0; i<2; i++)
1808 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1809 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1810 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1811 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1812 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1813 IDirect3DTexture9_Release(texture);
1816 /* Test double texbem */
1817 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1818 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1819 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1820 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1821 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1822 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1823 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1824 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1826 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1827 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1828 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1829 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1831 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1832 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1834 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1835 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1837 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1838 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1839 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1842 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1843 #define tex 0x00ff0000
1844 #define tex1 0x0000ff00
1845 #define origin 0x000000ff
1846 static const DWORD pixel_data[] = {
1847 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1848 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1851 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1852 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1853 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1854 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1856 #undef tex1
1857 #undef tex2
1858 #undef origin
1860 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1861 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1862 for(i = 0; i < 8; i++) {
1863 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1865 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1866 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1870 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1872 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1873 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1874 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1875 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1876 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1877 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1878 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1879 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1880 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1882 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1883 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1884 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1885 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1886 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1887 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1888 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1889 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1890 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1891 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1893 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1894 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1895 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1896 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1897 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1898 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1899 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1900 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1901 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1902 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1904 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1905 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1906 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1907 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1908 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1909 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1910 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1912 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1914 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1915 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1916 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1917 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1918 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1919 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1921 hr = IDirect3DDevice9_BeginScene(device);
1922 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1923 if(SUCCEEDED(hr)) {
1924 static const float double_quad[] = {
1925 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1926 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1927 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1928 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1932 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1933 hr = IDirect3DDevice9_EndScene(device);
1934 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1937 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1938 color = getPixelColor(device, 320, 240);
1939 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1941 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1942 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1943 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1944 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1945 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1946 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1947 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1948 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1949 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1950 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1952 IDirect3DPixelShader9_Release(pixel_shader);
1953 IDirect3DTexture9_Release(texture);
1954 IDirect3DTexture9_Release(texture1);
1955 IDirect3DTexture9_Release(texture2);
1958 static void z_range_test(IDirect3DDevice9 *device)
1960 const struct vertex quad[] =
1962 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1963 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1964 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1965 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1967 const struct vertex quad2[] =
1969 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1970 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1971 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1972 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1975 const struct tvertex quad3[] =
1977 { 0, 240, 1.1f, 1.0, 0xffffff00},
1978 { 0, 480, 1.1f, 1.0, 0xffffff00},
1979 { 640, 240, -1.1f, 1.0, 0xffffff00},
1980 { 640, 480, -1.1f, 1.0, 0xffffff00},
1982 const struct tvertex quad4[] =
1984 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1985 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1986 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1987 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1989 HRESULT hr;
1990 DWORD color;
1991 IDirect3DVertexShader9 *shader;
1992 IDirect3DVertexDeclaration9 *decl;
1993 D3DCAPS9 caps;
1994 const DWORD shader_code[] = {
1995 0xfffe0101, /* vs_1_1 */
1996 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1997 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1998 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1999 0x0000ffff /* end */
2001 static const D3DVERTEXELEMENT9 decl_elements[] = {
2002 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2003 D3DDECL_END()
2005 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2006 * then call Present. Then clear the color buffer to make sure it has some defined content
2007 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2008 * by the depth value.
2010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2012 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2013 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2014 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2018 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2020 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2022 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2024 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2025 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2026 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2028 hr = IDirect3DDevice9_BeginScene(device);
2029 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2030 if(hr == D3D_OK)
2032 /* Test the untransformed vertex path */
2033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2034 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2036 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2038 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2040 /* Test the transformed vertex path */
2041 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2042 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2045 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2047 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2049 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2051 hr = IDirect3DDevice9_EndScene(device);
2052 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2055 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2056 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058 /* Do not test the exact corner pixels, but go pretty close to them */
2060 /* Clipped because z > 1.0 */
2061 color = getPixelColor(device, 28, 238);
2062 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2063 color = getPixelColor(device, 28, 241);
2064 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2066 /* Not clipped, > z buffer clear value(0.75) */
2067 color = getPixelColor(device, 31, 238);
2068 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2069 color = getPixelColor(device, 31, 241);
2070 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2071 color = getPixelColor(device, 100, 238);
2072 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2073 color = getPixelColor(device, 100, 241);
2074 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2076 /* Not clipped, < z buffer clear value */
2077 color = getPixelColor(device, 104, 238);
2078 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2079 color = getPixelColor(device, 104, 241);
2080 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2081 color = getPixelColor(device, 318, 238);
2082 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2083 color = getPixelColor(device, 318, 241);
2084 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2086 /* Clipped because z < 0.0 */
2087 color = getPixelColor(device, 321, 238);
2088 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2089 color = getPixelColor(device, 321, 241);
2090 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2092 /* Test the shader path */
2093 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2094 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2095 skip("Vertex shaders not supported\n");
2096 goto out;
2098 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2099 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2100 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2101 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2105 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2106 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2107 IDirect3DDevice9_SetVertexShader(device, shader);
2108 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2110 hr = IDirect3DDevice9_BeginScene(device);
2111 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2112 if(hr == D3D_OK)
2114 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2115 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2116 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2118 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2121 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2123 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2125 hr = IDirect3DDevice9_EndScene(device);
2126 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2129 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2130 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2131 IDirect3DDevice9_SetVertexShader(device, NULL);
2132 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2134 IDirect3DVertexDeclaration9_Release(decl);
2135 IDirect3DVertexShader9_Release(shader);
2137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2138 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2139 /* Z < 1.0 */
2140 color = getPixelColor(device, 28, 238);
2141 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2143 /* 1.0 < z < 0.75 */
2144 color = getPixelColor(device, 31, 238);
2145 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2146 color = getPixelColor(device, 100, 238);
2147 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2149 /* 0.75 < z < 0.0 */
2150 color = getPixelColor(device, 104, 238);
2151 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2152 color = getPixelColor(device, 318, 238);
2153 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2155 /* 0.0 < z */
2156 color = getPixelColor(device, 321, 238);
2157 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2159 out:
2160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2161 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2163 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2165 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2168 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2170 D3DSURFACE_DESC desc;
2171 D3DLOCKED_RECT l;
2172 HRESULT hr;
2173 unsigned int x, y;
2174 DWORD *mem;
2176 memset(&desc, 0, sizeof(desc));
2177 memset(&l, 0, sizeof(l));
2178 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2179 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2180 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2181 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2182 if(FAILED(hr)) return;
2184 for(y = 0; y < desc.Height; y++)
2186 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2187 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2189 mem[x] = color;
2192 hr = IDirect3DSurface9_UnlockRect(surface);
2193 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2196 /* This tests a variety of possible StretchRect() situations */
2197 static void stretchrect_test(IDirect3DDevice9 *device)
2199 HRESULT hr;
2200 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2201 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2202 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2203 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2204 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2205 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2206 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2207 IDirect3DSurface9 *orig_rt = NULL;
2208 DWORD color;
2210 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2211 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2212 if(!orig_rt) {
2213 goto out;
2216 /* Create our temporary surfaces in system memory */
2217 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2218 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2219 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2220 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2222 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2223 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2225 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2226 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2227 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2228 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2230 /* Create render target surfaces */
2231 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2232 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2233 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2234 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2235 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2236 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2238 /* Create render target textures */
2239 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2240 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2241 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2242 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2243 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2244 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2245 if (tex_rt32) {
2246 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2247 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2249 if (tex_rt64) {
2250 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2251 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2253 if (tex_rt_dest64) {
2254 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2255 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2258 /* Create regular textures in D3DPOOL_DEFAULT */
2259 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2260 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2261 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2262 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2263 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2264 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2265 if (tex32) {
2266 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2267 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2269 if (tex64) {
2270 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2271 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2273 if (tex_dest64) {
2274 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2275 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2278 /*********************************************************************
2279 * Tests for when the source parameter is an offscreen plain surface *
2280 *********************************************************************/
2282 /* Fill the offscreen 64x64 surface with green */
2283 if (surf_offscreen64)
2284 fill_surface(surf_offscreen64, 0xff00ff00);
2286 /* offscreenplain ==> offscreenplain, same size */
2287 if(surf_offscreen64 && surf_offscreen_dest64) {
2288 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2289 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2291 if (hr == D3D_OK) {
2292 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2293 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2297 /* offscreenplain ==> rendertarget texture, same size */
2298 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2299 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2300 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2302 /* We can't lock rendertarget textures, so copy to our temp surface first */
2303 if (hr == D3D_OK) {
2304 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2305 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2308 if (hr == D3D_OK) {
2309 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2310 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2314 /* offscreenplain ==> rendertarget surface, same size */
2315 if(surf_offscreen64 && surf_rt_dest64) {
2316 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2317 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2319 if (hr == D3D_OK) {
2320 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2321 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2325 /* offscreenplain ==> texture, same size (should fail) */
2326 if(surf_offscreen64 && surf_tex_dest64) {
2327 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2328 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2331 /* Fill the smaller offscreen surface with red */
2332 fill_surface(surf_offscreen32, 0xffff0000);
2334 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2335 if(surf_offscreen32 && surf_offscreen64) {
2336 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2337 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2340 /* offscreenplain ==> rendertarget texture, scaling */
2341 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2342 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2343 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2345 /* We can't lock rendertarget textures, so copy to our temp surface first */
2346 if (hr == D3D_OK) {
2347 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2348 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2351 if (hr == D3D_OK) {
2352 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2353 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2357 /* offscreenplain ==> rendertarget surface, scaling */
2358 if(surf_offscreen32 && surf_rt_dest64) {
2359 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2360 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2362 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2363 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2366 /* offscreenplain ==> texture, scaling (should fail) */
2367 if(surf_offscreen32 && surf_tex_dest64) {
2368 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2369 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2372 /************************************************************
2373 * Tests for when the source parameter is a regular texture *
2374 ************************************************************/
2376 /* Fill the surface of the regular texture with blue */
2377 if (surf_tex64 && surf_temp64) {
2378 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2379 fill_surface(surf_temp64, 0xff0000ff);
2380 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2381 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2384 /* texture ==> offscreenplain, same size */
2385 if(surf_tex64 && surf_offscreen64) {
2386 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2387 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2390 /* texture ==> rendertarget texture, same size */
2391 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2392 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2393 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2395 /* We can't lock rendertarget textures, so copy to our temp surface first */
2396 if (hr == D3D_OK) {
2397 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2398 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2401 if (hr == D3D_OK) {
2402 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2403 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2407 /* texture ==> rendertarget surface, same size */
2408 if(surf_tex64 && surf_rt_dest64) {
2409 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2410 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412 if (hr == D3D_OK) {
2413 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2414 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2418 /* texture ==> texture, same size (should fail) */
2419 if(surf_tex64 && surf_tex_dest64) {
2420 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2421 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2424 /* Fill the surface of the smaller regular texture with red */
2425 if (surf_tex32 && surf_temp32) {
2426 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2427 fill_surface(surf_temp32, 0xffff0000);
2428 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2429 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2432 /* texture ==> offscreenplain, scaling (should fail) */
2433 if(surf_tex32 && surf_offscreen64) {
2434 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2435 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2438 /* texture ==> rendertarget texture, scaling */
2439 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2440 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2441 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2443 /* We can't lock rendertarget textures, so copy to our temp surface first */
2444 if (hr == D3D_OK) {
2445 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2446 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2449 if (hr == D3D_OK) {
2450 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2451 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2455 /* texture ==> rendertarget surface, scaling */
2456 if(surf_tex32 && surf_rt_dest64) {
2457 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2458 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2461 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2464 /* texture ==> texture, scaling (should fail) */
2465 if(surf_tex32 && surf_tex_dest64) {
2466 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2467 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2470 /*****************************************************************
2471 * Tests for when the source parameter is a rendertarget texture *
2472 *****************************************************************/
2474 /* Fill the surface of the rendertarget texture with white */
2475 if (surf_tex_rt64 && surf_temp64) {
2476 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2477 fill_surface(surf_temp64, 0xffffffff);
2478 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2479 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2482 /* rendertarget texture ==> offscreenplain, same size */
2483 if(surf_tex_rt64 && surf_offscreen64) {
2484 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2485 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2488 /* rendertarget texture ==> rendertarget texture, same size */
2489 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2490 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2491 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2493 /* We can't lock rendertarget textures, so copy to our temp surface first */
2494 if (hr == D3D_OK) {
2495 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2496 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2499 if (hr == D3D_OK) {
2500 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2501 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2505 /* rendertarget texture ==> rendertarget surface, same size */
2506 if(surf_tex_rt64 && surf_rt_dest64) {
2507 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2508 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2510 if (hr == D3D_OK) {
2511 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2512 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2516 /* rendertarget texture ==> texture, same size (should fail) */
2517 if(surf_tex_rt64 && surf_tex_dest64) {
2518 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2519 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2522 /* Fill the surface of the smaller rendertarget texture with red */
2523 if (surf_tex_rt32 && surf_temp32) {
2524 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2525 fill_surface(surf_temp32, 0xffff0000);
2526 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2527 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2530 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2531 if(surf_tex_rt32 && surf_offscreen64) {
2532 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2533 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2536 /* rendertarget texture ==> rendertarget texture, scaling */
2537 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2538 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2539 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2541 /* We can't lock rendertarget textures, so copy to our temp surface first */
2542 if (hr == D3D_OK) {
2543 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2544 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2547 if (hr == D3D_OK) {
2548 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2549 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2553 /* rendertarget texture ==> rendertarget surface, scaling */
2554 if(surf_tex_rt32 && surf_rt_dest64) {
2555 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2556 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2558 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2559 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2562 /* rendertarget texture ==> texture, scaling (should fail) */
2563 if(surf_tex_rt32 && surf_tex_dest64) {
2564 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2565 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2568 /*****************************************************************
2569 * Tests for when the source parameter is a rendertarget surface *
2570 *****************************************************************/
2572 /* Fill the surface of the rendertarget surface with black */
2573 if (surf_rt64)
2574 fill_surface(surf_rt64, 0xff000000);
2576 /* rendertarget texture ==> offscreenplain, same size */
2577 if(surf_rt64 && surf_offscreen64) {
2578 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2579 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2582 /* rendertarget surface ==> rendertarget texture, same size */
2583 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2584 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2585 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2587 /* We can't lock rendertarget textures, so copy to our temp surface first */
2588 if (hr == D3D_OK) {
2589 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2590 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2593 if (hr == D3D_OK) {
2594 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2595 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2599 /* rendertarget surface ==> rendertarget surface, same size */
2600 if(surf_rt64 && surf_rt_dest64) {
2601 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2602 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2604 if (hr == D3D_OK) {
2605 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2606 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2610 /* rendertarget surface ==> texture, same size (should fail) */
2611 if(surf_rt64 && surf_tex_dest64) {
2612 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2613 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2616 /* Fill the surface of the smaller rendertarget texture with red */
2617 if (surf_rt32)
2618 fill_surface(surf_rt32, 0xffff0000);
2620 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2621 if(surf_rt32 && surf_offscreen64) {
2622 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2623 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2626 /* rendertarget surface ==> rendertarget texture, scaling */
2627 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2628 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2629 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2631 /* We can't lock rendertarget textures, so copy to our temp surface first */
2632 if (hr == D3D_OK) {
2633 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2634 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2637 if (hr == D3D_OK) {
2638 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2639 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2643 /* rendertarget surface ==> rendertarget surface, scaling */
2644 if(surf_rt32 && surf_rt_dest64) {
2645 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2646 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2648 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2649 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2652 /* rendertarget surface ==> texture, scaling (should fail) */
2653 if(surf_rt32 && surf_tex_dest64) {
2654 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2655 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2658 /* TODO: Test when source and destination RECT parameters are given... */
2659 /* TODO: Test format conversions */
2662 out:
2663 /* Clean up */
2664 if (surf_rt32)
2665 IDirect3DSurface9_Release(surf_rt32);
2666 if (surf_rt64)
2667 IDirect3DSurface9_Release(surf_rt64);
2668 if (surf_rt_dest64)
2669 IDirect3DSurface9_Release(surf_rt_dest64);
2670 if (surf_temp32)
2671 IDirect3DSurface9_Release(surf_temp32);
2672 if (surf_temp64)
2673 IDirect3DSurface9_Release(surf_temp64);
2674 if (surf_offscreen32)
2675 IDirect3DSurface9_Release(surf_offscreen32);
2676 if (surf_offscreen64)
2677 IDirect3DSurface9_Release(surf_offscreen64);
2678 if (surf_offscreen_dest64)
2679 IDirect3DSurface9_Release(surf_offscreen_dest64);
2681 if (tex_rt32) {
2682 if (surf_tex_rt32)
2683 IDirect3DSurface9_Release(surf_tex_rt32);
2684 IDirect3DTexture9_Release(tex_rt32);
2686 if (tex_rt64) {
2687 if (surf_tex_rt64)
2688 IDirect3DSurface9_Release(surf_tex_rt64);
2689 IDirect3DTexture9_Release(tex_rt64);
2691 if (tex_rt_dest64) {
2692 if (surf_tex_rt_dest64)
2693 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2694 IDirect3DTexture9_Release(tex_rt_dest64);
2696 if (tex32) {
2697 if (surf_tex32)
2698 IDirect3DSurface9_Release(surf_tex32);
2699 IDirect3DTexture9_Release(tex32);
2701 if (tex64) {
2702 if (surf_tex64)
2703 IDirect3DSurface9_Release(surf_tex64);
2704 IDirect3DTexture9_Release(tex64);
2706 if (tex_dest64) {
2707 if (surf_tex_dest64)
2708 IDirect3DSurface9_Release(surf_tex_dest64);
2709 IDirect3DTexture9_Release(tex_dest64);
2712 if (orig_rt) {
2713 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2714 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2715 IDirect3DSurface9_Release(orig_rt);
2719 static void maxmip_test(IDirect3DDevice9 *device)
2721 IDirect3DTexture9 *texture = NULL;
2722 IDirect3DSurface9 *surface = NULL;
2723 HRESULT hr;
2724 DWORD color;
2725 const float quads[] = {
2726 -1.0, -1.0, 0.0, 0.0, 0.0,
2727 -1.0, 0.0, 0.0, 0.0, 1.0,
2728 0.0, -1.0, 0.0, 1.0, 0.0,
2729 0.0, 0.0, 0.0, 1.0, 1.0,
2731 0.0, -1.0, 0.0, 0.0, 0.0,
2732 0.0, 0.0, 0.0, 0.0, 1.0,
2733 1.0, -1.0, 0.0, 1.0, 0.0,
2734 1.0, 0.0, 0.0, 1.0, 1.0,
2736 0.0, 0.0, 0.0, 0.0, 0.0,
2737 0.0, 1.0, 0.0, 0.0, 1.0,
2738 1.0, 0.0, 0.0, 1.0, 0.0,
2739 1.0, 1.0, 0.0, 1.0, 1.0,
2741 -1.0, 0.0, 0.0, 0.0, 0.0,
2742 -1.0, 1.0, 0.0, 0.0, 1.0,
2743 0.0, 0.0, 0.0, 1.0, 0.0,
2744 0.0, 1.0, 0.0, 1.0, 1.0,
2747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2748 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2750 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2751 &texture, NULL);
2752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2753 if(!texture)
2755 skip("Failed to create test texture\n");
2756 return;
2759 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2760 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2761 fill_surface(surface, 0xffff0000);
2762 IDirect3DSurface9_Release(surface);
2763 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2764 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2765 fill_surface(surface, 0xff00ff00);
2766 IDirect3DSurface9_Release(surface);
2767 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2768 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2769 fill_surface(surface, 0xff0000ff);
2770 IDirect3DSurface9_Release(surface);
2772 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2774 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2775 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2777 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2778 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2780 hr = IDirect3DDevice9_BeginScene(device);
2781 if(SUCCEEDED(hr))
2783 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2784 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2786 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2788 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2789 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2791 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2793 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2794 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2796 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2798 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2799 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2801 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2802 hr = IDirect3DDevice9_EndScene(device);
2803 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
2806 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2807 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2808 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2809 color = getPixelColor(device, 160, 360);
2810 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2811 color = getPixelColor(device, 160, 120);
2812 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2813 color = getPixelColor(device, 480, 120);
2814 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2815 color = getPixelColor(device, 480, 360);
2816 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2819 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2822 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2824 hr = IDirect3DDevice9_BeginScene(device);
2825 if(SUCCEEDED(hr))
2827 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2828 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2832 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2833 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2835 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2837 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2838 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2840 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2842 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2843 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2845 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2846 hr = IDirect3DDevice9_EndScene(device);
2847 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
2850 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2851 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2852 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2853 * samples from the highest level in the texture(level 2)
2855 color = getPixelColor(device, 160, 360);
2856 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2857 color = getPixelColor(device, 160, 120);
2858 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2859 color = getPixelColor(device, 480, 120);
2860 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2861 color = getPixelColor(device, 480, 360);
2862 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2864 hr = IDirect3DDevice9_BeginScene(device);
2865 if(SUCCEEDED(hr))
2867 DWORD ret;
2869 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2870 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2871 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2872 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2873 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2874 ret = IDirect3DTexture9_SetLOD(texture, 1);
2875 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2877 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2879 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2880 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2881 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2882 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2883 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2884 ret = IDirect3DTexture9_SetLOD(texture, 2);
2885 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2887 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2889 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2890 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2891 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2892 ret = IDirect3DTexture9_SetLOD(texture, 1);
2893 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2895 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2897 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2898 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2899 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2900 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2901 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2902 ret = IDirect3DTexture9_SetLOD(texture, 1);
2903 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2905 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2906 hr = IDirect3DDevice9_EndScene(device);
2909 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2910 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2911 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2912 * samples from the highest level in the texture(level 2)
2914 color = getPixelColor(device, 160, 360);
2915 ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2916 color = getPixelColor(device, 160, 120);
2917 ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2918 color = getPixelColor(device, 480, 120);
2919 ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2920 color = getPixelColor(device, 480, 360);
2921 ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2923 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2925 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2926 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2927 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2928 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2929 IDirect3DTexture9_Release(texture);
2932 static void release_buffer_test(IDirect3DDevice9 *device)
2934 IDirect3DVertexBuffer9 *vb = NULL;
2935 IDirect3DIndexBuffer9 *ib = NULL;
2936 HRESULT hr;
2937 BYTE *data;
2938 LONG ref;
2940 static const struct vertex quad[] = {
2941 {-1.0, -1.0, 0.1, 0xffff0000},
2942 {-1.0, 1.0, 0.1, 0xffff0000},
2943 { 1.0, 1.0, 0.1, 0xffff0000},
2945 {-1.0, -1.0, 0.1, 0xff00ff00},
2946 {-1.0, 1.0, 0.1, 0xff00ff00},
2947 { 1.0, 1.0, 0.1, 0xff00ff00}
2949 short indices[] = {3, 4, 5};
2951 /* Index and vertex buffers should always be creatable */
2952 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2953 D3DPOOL_MANAGED, &vb, NULL);
2954 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2955 if(!vb) {
2956 skip("Failed to create a vertex buffer\n");
2957 return;
2959 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2960 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2961 if(!ib) {
2962 skip("Failed to create an index buffer\n");
2963 return;
2966 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2967 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2968 memcpy(data, quad, sizeof(quad));
2969 hr = IDirect3DVertexBuffer9_Unlock(vb);
2970 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2972 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2973 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2974 memcpy(data, indices, sizeof(indices));
2975 hr = IDirect3DIndexBuffer9_Unlock(ib);
2976 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2978 hr = IDirect3DDevice9_SetIndices(device, ib);
2979 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2980 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2981 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2982 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2983 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2985 /* Now destroy the bound index buffer and draw again */
2986 ref = IDirect3DIndexBuffer9_Release(ib);
2987 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2990 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2992 hr = IDirect3DDevice9_BeginScene(device);
2993 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2994 if(SUCCEEDED(hr))
2996 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2997 * making assumptions about the indices or vertices
2999 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3000 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3001 hr = IDirect3DDevice9_EndScene(device);
3002 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3006 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3008 hr = IDirect3DDevice9_SetIndices(device, NULL);
3009 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3010 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3011 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3013 /* Index buffer was already destroyed as part of the test */
3014 IDirect3DVertexBuffer9_Release(vb);
3017 static void float_texture_test(IDirect3DDevice9 *device)
3019 IDirect3D9 *d3d = NULL;
3020 HRESULT hr;
3021 IDirect3DTexture9 *texture = NULL;
3022 D3DLOCKED_RECT lr;
3023 float *data;
3024 DWORD color;
3025 float quad[] = {
3026 -1.0, -1.0, 0.1, 0.0, 0.0,
3027 -1.0, 1.0, 0.1, 0.0, 1.0,
3028 1.0, -1.0, 0.1, 1.0, 0.0,
3029 1.0, 1.0, 0.1, 1.0, 1.0,
3032 memset(&lr, 0, sizeof(lr));
3033 IDirect3DDevice9_GetDirect3D(device, &d3d);
3034 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3035 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3036 skip("D3DFMT_R32F textures not supported\n");
3037 goto out;
3040 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3041 D3DPOOL_MANAGED, &texture, NULL);
3042 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3043 if(!texture) {
3044 skip("Failed to create R32F texture\n");
3045 goto out;
3048 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3049 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3050 data = lr.pBits;
3051 *data = 0.0;
3052 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3053 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3055 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3056 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3058 hr = IDirect3DDevice9_BeginScene(device);
3059 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3060 if(SUCCEEDED(hr))
3062 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3063 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3066 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3068 hr = IDirect3DDevice9_EndScene(device);
3069 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3071 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3072 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3075 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3077 color = getPixelColor(device, 240, 320);
3078 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3080 out:
3081 if(texture) IDirect3DTexture9_Release(texture);
3082 IDirect3D9_Release(d3d);
3085 static void g16r16_texture_test(IDirect3DDevice9 *device)
3087 IDirect3D9 *d3d = NULL;
3088 HRESULT hr;
3089 IDirect3DTexture9 *texture = NULL;
3090 D3DLOCKED_RECT lr;
3091 DWORD *data;
3092 DWORD color;
3093 float quad[] = {
3094 -1.0, -1.0, 0.1, 0.0, 0.0,
3095 -1.0, 1.0, 0.1, 0.0, 1.0,
3096 1.0, -1.0, 0.1, 1.0, 0.0,
3097 1.0, 1.0, 0.1, 1.0, 1.0,
3100 memset(&lr, 0, sizeof(lr));
3101 IDirect3DDevice9_GetDirect3D(device, &d3d);
3102 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3103 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3104 skip("D3DFMT_G16R16 textures not supported\n");
3105 goto out;
3108 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3109 D3DPOOL_MANAGED, &texture, NULL);
3110 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3111 if(!texture) {
3112 skip("Failed to create D3DFMT_G16R16 texture\n");
3113 goto out;
3116 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3117 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3118 data = lr.pBits;
3119 *data = 0x0f00f000;
3120 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3121 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3123 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3124 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3126 hr = IDirect3DDevice9_BeginScene(device);
3127 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3128 if(SUCCEEDED(hr))
3130 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3131 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3134 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3136 hr = IDirect3DDevice9_EndScene(device);
3137 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3139 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3140 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3142 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3143 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3145 color = getPixelColor(device, 240, 320);
3146 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3147 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3149 out:
3150 if(texture) IDirect3DTexture9_Release(texture);
3151 IDirect3D9_Release(d3d);
3154 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3156 HRESULT hr;
3157 IDirect3D9 *d3d;
3158 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3159 D3DCAPS9 caps;
3160 IDirect3DTexture9 *texture = NULL;
3161 IDirect3DVolumeTexture9 *volume = NULL;
3162 unsigned int x, y, z;
3163 D3DLOCKED_RECT lr;
3164 D3DLOCKED_BOX lb;
3165 DWORD color;
3166 UINT w, h;
3167 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3168 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3169 0.0, 1.0, 0.0, 0.0,
3170 0.0, 0.0, 1.0, 0.0,
3171 0.0, 0.0, 0.0, 1.0};
3172 static const D3DVERTEXELEMENT9 decl_elements[] = {
3173 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3174 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3175 D3DDECL_END()
3177 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3178 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3179 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3180 D3DDECL_END()
3182 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3183 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3184 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3185 D3DDECL_END()
3187 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3188 0x00, 0xff, 0x00, 0x00,
3189 0x00, 0x00, 0x00, 0x00,
3190 0x00, 0x00, 0x00, 0x00};
3192 memset(&lr, 0, sizeof(lr));
3193 memset(&lb, 0, sizeof(lb));
3194 IDirect3DDevice9_GetDirect3D(device, &d3d);
3195 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3196 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3197 fmt = D3DFMT_A16B16G16R16;
3199 IDirect3D9_Release(d3d);
3201 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3203 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3205 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3207 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3208 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3209 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3210 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3212 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3213 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3214 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3215 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3216 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3217 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3218 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3219 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3220 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3222 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3223 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3224 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3226 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3227 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3228 w = min(1024, caps.MaxTextureWidth);
3229 h = min(1024, caps.MaxTextureHeight);
3230 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3231 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3232 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3233 if(!texture) {
3234 skip("Failed to create the test texture\n");
3235 return;
3238 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3239 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3240 * 1.0 in red and green for the x and y coords
3242 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3243 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3244 for(y = 0; y < h; y++) {
3245 for(x = 0; x < w; x++) {
3246 double r_f = (double) y / (double) h;
3247 double g_f = (double) x / (double) w;
3248 if(fmt == D3DFMT_A16B16G16R16) {
3249 unsigned short r, g;
3250 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3251 r = (unsigned short) (r_f * 65536.0);
3252 g = (unsigned short) (g_f * 65536.0);
3253 dst[0] = r;
3254 dst[1] = g;
3255 dst[2] = 0;
3256 dst[3] = 65535;
3257 } else {
3258 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3259 unsigned char r = (unsigned char) (r_f * 255.0);
3260 unsigned char g = (unsigned char) (g_f * 255.0);
3261 dst[0] = 0;
3262 dst[1] = g;
3263 dst[2] = r;
3264 dst[3] = 255;
3268 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3269 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3270 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3271 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3273 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3274 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3275 hr = IDirect3DDevice9_BeginScene(device);
3276 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3277 if(SUCCEEDED(hr))
3279 float quad1[] = {
3280 -1.0, -1.0, 0.1, 1.0, 1.0,
3281 -1.0, 0.0, 0.1, 1.0, 1.0,
3282 0.0, -1.0, 0.1, 1.0, 1.0,
3283 0.0, 0.0, 0.1, 1.0, 1.0,
3285 float quad2[] = {
3286 -1.0, 0.0, 0.1, 1.0, 1.0,
3287 -1.0, 1.0, 0.1, 1.0, 1.0,
3288 0.0, 0.0, 0.1, 1.0, 1.0,
3289 0.0, 1.0, 0.1, 1.0, 1.0,
3291 float quad3[] = {
3292 0.0, 0.0, 0.1, 0.5, 0.5,
3293 0.0, 1.0, 0.1, 0.5, 0.5,
3294 1.0, 0.0, 0.1, 0.5, 0.5,
3295 1.0, 1.0, 0.1, 0.5, 0.5,
3297 float quad4[] = {
3298 320, 480, 0.1, 1.0, 0.0, 1.0,
3299 320, 240, 0.1, 1.0, 0.0, 1.0,
3300 640, 480, 0.1, 1.0, 0.0, 1.0,
3301 640, 240, 0.1, 1.0, 0.0, 1.0,
3303 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3304 0.0, 0.0, 0.0, 0.0,
3305 0.0, 0.0, 0.0, 0.0,
3306 0.0, 0.0, 0.0, 0.0};
3308 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3309 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3312 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3314 /* What happens with transforms enabled? */
3315 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3316 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3318 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3320 /* What happens if 4 coords are used, but only 2 given ?*/
3321 mat[8] = 1.0;
3322 mat[13] = 1.0;
3323 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3324 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3325 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3326 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3328 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3330 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3331 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3332 * due to the coords in the vertices. (turns out red, indeed)
3334 memset(mat, 0, sizeof(mat));
3335 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3336 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3337 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3338 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3339 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3340 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3341 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3342 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3344 hr = IDirect3DDevice9_EndScene(device);
3345 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3347 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3348 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3349 color = getPixelColor(device, 160, 360);
3350 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3351 color = getPixelColor(device, 160, 120);
3352 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3353 color = getPixelColor(device, 480, 120);
3354 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3355 color = getPixelColor(device, 480, 360);
3356 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3359 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3361 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3362 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3363 hr = IDirect3DDevice9_BeginScene(device);
3364 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3365 if(SUCCEEDED(hr))
3367 float quad1[] = {
3368 -1.0, -1.0, 0.1, 0.8, 0.2,
3369 -1.0, 0.0, 0.1, 0.8, 0.2,
3370 0.0, -1.0, 0.1, 0.8, 0.2,
3371 0.0, 0.0, 0.1, 0.8, 0.2,
3373 float quad2[] = {
3374 -1.0, 0.0, 0.1, 0.5, 1.0,
3375 -1.0, 1.0, 0.1, 0.5, 1.0,
3376 0.0, 0.0, 0.1, 0.5, 1.0,
3377 0.0, 1.0, 0.1, 0.5, 1.0,
3379 float quad3[] = {
3380 0.0, 0.0, 0.1, 0.5, 1.0,
3381 0.0, 1.0, 0.1, 0.5, 1.0,
3382 1.0, 0.0, 0.1, 0.5, 1.0,
3383 1.0, 1.0, 0.1, 0.5, 1.0,
3385 float quad4[] = {
3386 0.0, -1.0, 0.1, 0.8, 0.2,
3387 0.0, 0.0, 0.1, 0.8, 0.2,
3388 1.0, -1.0, 0.1, 0.8, 0.2,
3389 1.0, 0.0, 0.1, 0.8, 0.2,
3391 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3392 0.0, 0.0, 0.0, 0.0,
3393 0.0, 1.0, 0.0, 0.0,
3394 0.0, 0.0, 0.0, 0.0};
3396 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3398 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3399 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3400 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3401 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3406 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3407 * it behaves like COUNT2 because normal textures require 2 coords
3409 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3412 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3414 /* Just to be sure, the same as quad2 above */
3415 memset(mat, 0, sizeof(mat));
3416 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3418 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3419 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3420 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3421 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3423 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3424 * used? And what happens to the first?
3426 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3429 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3431 hr = IDirect3DDevice9_EndScene(device);
3432 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3434 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3435 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3436 color = getPixelColor(device, 160, 360);
3437 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3438 color = getPixelColor(device, 160, 120);
3439 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3440 color = getPixelColor(device, 480, 120);
3441 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3442 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3443 color = getPixelColor(device, 480, 360);
3444 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3445 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3447 IDirect3DTexture9_Release(texture);
3449 /* Test projected textures, without any fancy matrices */
3450 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3451 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3452 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3453 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3454 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3455 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3456 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3457 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3459 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3460 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3461 for(x = 0; x < 4; x++) {
3462 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3464 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3465 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3466 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3469 hr = IDirect3DDevice9_BeginScene(device);
3470 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3471 if(SUCCEEDED(hr))
3473 const float proj_quads[] = {
3474 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3475 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3476 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3477 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3478 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3479 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3480 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3481 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3484 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3485 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3487 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3489 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3490 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3492 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3494 hr = IDirect3DDevice9_EndScene(device);
3495 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3498 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3499 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3500 IDirect3DTexture9_Release(texture);
3502 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3503 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3504 color = getPixelColor(device, 158, 118);
3505 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3506 color = getPixelColor(device, 162, 118);
3507 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3508 color = getPixelColor(device, 158, 122);
3509 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3510 color = getPixelColor(device, 162, 122);
3511 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3513 color = getPixelColor(device, 158, 178);
3514 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3515 color = getPixelColor(device, 162, 178);
3516 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3517 color = getPixelColor(device, 158, 182);
3518 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3519 color = getPixelColor(device, 162, 182);
3520 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3522 color = getPixelColor(device, 318, 118);
3523 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3524 color = getPixelColor(device, 322, 118);
3525 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3526 color = getPixelColor(device, 318, 122);
3527 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3528 color = getPixelColor(device, 322, 122);
3529 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3531 color = getPixelColor(device, 318, 178);
3532 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3533 color = getPixelColor(device, 322, 178);
3534 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3535 color = getPixelColor(device, 318, 182);
3536 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3537 color = getPixelColor(device, 322, 182);
3538 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3540 color = getPixelColor(device, 238, 298);
3541 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3542 color = getPixelColor(device, 242, 298);
3543 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3544 color = getPixelColor(device, 238, 302);
3545 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3546 color = getPixelColor(device, 242, 302);
3547 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3549 color = getPixelColor(device, 238, 388);
3550 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3551 color = getPixelColor(device, 242, 388);
3552 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3553 color = getPixelColor(device, 238, 392);
3554 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3555 color = getPixelColor(device, 242, 392);
3556 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3558 color = getPixelColor(device, 478, 298);
3559 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3560 color = getPixelColor(device, 482, 298);
3561 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3562 color = getPixelColor(device, 478, 302);
3563 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3564 color = getPixelColor(device, 482, 302);
3565 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3567 color = getPixelColor(device, 478, 388);
3568 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3569 color = getPixelColor(device, 482, 388);
3570 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3571 color = getPixelColor(device, 478, 392);
3572 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3573 color = getPixelColor(device, 482, 392);
3574 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3576 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3577 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3578 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3579 * Thus watch out if sampling from texels between 0 and 1.
3581 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3582 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3583 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3584 if(!volume) {
3585 skip("Failed to create a volume texture\n");
3586 goto out;
3589 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3590 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3591 for(z = 0; z < 32; z++) {
3592 for(y = 0; y < 32; y++) {
3593 for(x = 0; x < 32; x++) {
3594 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3595 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3596 float r_f = (float) x / 31.0;
3597 float g_f = (float) y / 31.0;
3598 float b_f = (float) z / 31.0;
3600 if(fmt == D3DFMT_A16B16G16R16) {
3601 unsigned short *mem_s = mem;
3602 mem_s[0] = r_f * 65535.0;
3603 mem_s[1] = g_f * 65535.0;
3604 mem_s[2] = b_f * 65535.0;
3605 mem_s[3] = 65535;
3606 } else {
3607 unsigned char *mem_c = mem;
3608 mem_c[0] = b_f * 255.0;
3609 mem_c[1] = g_f * 255.0;
3610 mem_c[2] = r_f * 255.0;
3611 mem_c[3] = 255;
3616 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3617 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3619 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3620 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3622 hr = IDirect3DDevice9_BeginScene(device);
3623 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3624 if(SUCCEEDED(hr))
3626 float quad1[] = {
3627 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3628 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3629 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3630 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3632 float quad2[] = {
3633 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3634 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3635 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3636 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3638 float quad3[] = {
3639 0.0, 0.0, 0.1, 0.0, 0.0,
3640 0.0, 1.0, 0.1, 0.0, 0.0,
3641 1.0, 0.0, 0.1, 0.0, 0.0,
3642 1.0, 1.0, 0.1, 0.0, 0.0
3644 float quad4[] = {
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,
3647 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3648 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3650 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3651 0.0, 0.0, 1.0, 0.0,
3652 0.0, 1.0, 0.0, 0.0,
3653 0.0, 0.0, 0.0, 1.0};
3654 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3657 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3658 * values
3660 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3661 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3662 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3665 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3667 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3668 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3669 * otherwise the w will be missing(blue).
3670 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3671 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3673 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3675 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3676 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3678 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3679 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3680 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3682 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3683 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3684 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3685 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3686 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3688 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3689 * disable. ATI extends it up to the amount of values needed for the volume texture
3691 memset(mat, 0, sizeof(mat));
3692 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3693 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3694 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3696 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3697 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3698 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3699 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3701 hr = IDirect3DDevice9_EndScene(device);
3702 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3704 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3705 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3707 color = getPixelColor(device, 160, 360);
3708 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3709 color = getPixelColor(device, 160, 120);
3710 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3711 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3712 color = getPixelColor(device, 480, 120);
3713 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3714 color = getPixelColor(device, 480, 360);
3715 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3717 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3719 hr = IDirect3DDevice9_BeginScene(device);
3720 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3721 if(SUCCEEDED(hr))
3723 float quad1[] = {
3724 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3725 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3726 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3727 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3729 float quad2[] = {
3730 -1.0, 0.0, 0.1,
3731 -1.0, 1.0, 0.1,
3732 0.0, 0.0, 0.1,
3733 0.0, 1.0, 0.1,
3735 float quad3[] = {
3736 0.0, 0.0, 0.1, 1.0,
3737 0.0, 1.0, 0.1, 1.0,
3738 1.0, 0.0, 0.1, 1.0,
3739 1.0, 1.0, 0.1, 1.0
3741 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3742 0.0, 0.0, 0.0, 0.0,
3743 0.0, 0.0, 0.0, 0.0,
3744 0.0, 1.0, 0.0, 0.0};
3745 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3746 1.0, 0.0, 0.0, 0.0,
3747 0.0, 1.0, 0.0, 0.0,
3748 0.0, 0.0, 1.0, 0.0};
3749 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3750 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3752 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3754 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3755 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3756 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3757 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3759 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3761 /* None passed */
3762 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3763 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3765 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3767 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3769 /* 4 used, 1 passed */
3770 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3772 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3775 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3777 hr = IDirect3DDevice9_EndScene(device);
3778 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3780 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3781 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3782 color = getPixelColor(device, 160, 360);
3783 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3784 color = getPixelColor(device, 160, 120);
3785 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3786 color = getPixelColor(device, 480, 120);
3787 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3788 /* Quad4: unused */
3790 IDirect3DVolumeTexture9_Release(volume);
3792 out:
3793 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3795 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3796 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3797 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3799 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3801 IDirect3DVertexDeclaration9_Release(decl);
3802 IDirect3DVertexDeclaration9_Release(decl2);
3803 IDirect3DVertexDeclaration9_Release(decl3);
3806 static void texdepth_test(IDirect3DDevice9 *device)
3808 IDirect3DPixelShader9 *shader;
3809 HRESULT hr;
3810 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3811 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3812 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3813 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3814 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3815 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3816 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3817 DWORD shader_code[] = {
3818 0xffff0104, /* ps_1_4 */
3819 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3820 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3821 0x0000fffd, /* phase */
3822 0x00000057, 0x800f0005, /* texdepth r5 */
3823 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3824 0x0000ffff /* end */
3826 DWORD color;
3827 float vertex[] = {
3828 -1.0, -1.0, 0.0,
3829 1.0, -1.0, 1.0,
3830 -1.0, 1.0, 0.0,
3831 1.0, 1.0, 1.0
3834 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3835 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3838 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3840 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3842 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3844 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3845 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3846 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
3848 /* Fill the depth buffer with a gradient */
3849 hr = IDirect3DDevice9_BeginScene(device);
3850 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3851 if(SUCCEEDED(hr))
3853 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3854 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3855 hr = IDirect3DDevice9_EndScene(device);
3856 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3859 /* Now perform the actual tests. Same geometry, but with the shader */
3860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3863 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3864 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3865 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3867 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3868 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3869 hr = IDirect3DDevice9_BeginScene(device);
3870 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3871 if(SUCCEEDED(hr))
3873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3874 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3876 hr = IDirect3DDevice9_EndScene(device);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3880 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3881 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3882 color = getPixelColor(device, 158, 240);
3883 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3884 color = getPixelColor(device, 162, 240);
3885 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3888 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3890 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3891 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3892 hr = IDirect3DDevice9_BeginScene(device);
3893 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3894 if(SUCCEEDED(hr))
3896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3897 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3899 hr = IDirect3DDevice9_EndScene(device);
3900 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3903 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3905 color = getPixelColor(device, 318, 240);
3906 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3907 color = getPixelColor(device, 322, 240);
3908 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3911 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3913 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3914 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3915 hr = IDirect3DDevice9_BeginScene(device);
3916 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3917 if(SUCCEEDED(hr))
3919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3920 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3922 hr = IDirect3DDevice9_EndScene(device);
3923 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3925 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3926 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3928 color = getPixelColor(device, 1, 240);
3929 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3932 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3934 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3935 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3936 hr = IDirect3DDevice9_BeginScene(device);
3937 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3938 if(SUCCEEDED(hr))
3940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3941 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3943 hr = IDirect3DDevice9_EndScene(device);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3946 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3947 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3948 color = getPixelColor(device, 318, 240);
3949 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3950 color = getPixelColor(device, 322, 240);
3951 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3953 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3954 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3956 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3957 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3958 hr = IDirect3DDevice9_BeginScene(device);
3959 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3960 if(SUCCEEDED(hr))
3962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3963 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3965 hr = IDirect3DDevice9_EndScene(device);
3966 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3968 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3969 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3971 color = getPixelColor(device, 1, 240);
3972 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3974 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3975 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3977 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3978 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3979 hr = IDirect3DDevice9_BeginScene(device);
3980 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3981 if(SUCCEEDED(hr))
3983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3984 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3986 hr = IDirect3DDevice9_EndScene(device);
3987 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3989 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3990 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3992 color = getPixelColor(device, 638, 240);
3993 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3996 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3998 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3999 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4000 hr = IDirect3DDevice9_BeginScene(device);
4001 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4002 if(SUCCEEDED(hr))
4004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4005 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4007 hr = IDirect3DDevice9_EndScene(device);
4008 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4010 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4011 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %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 /* Cleanup */
4017 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4019 IDirect3DPixelShader9_Release(shader);
4021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4022 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4027 static void texkill_test(IDirect3DDevice9 *device)
4029 IDirect3DPixelShader9 *shader;
4030 HRESULT hr;
4031 DWORD color;
4033 const float vertex[] = {
4034 /* bottom top right left */
4035 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4036 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4037 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4038 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4041 DWORD shader_code_11[] = {
4042 0xffff0101, /* ps_1_1 */
4043 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4044 0x00000041, 0xb00f0000, /* texkill t0 */
4045 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4046 0x0000ffff /* end */
4048 DWORD shader_code_20[] = {
4049 0xffff0200, /* ps_2_0 */
4050 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4051 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4052 0x01000041, 0xb00f0000, /* texkill t0 */
4053 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4054 0x0000ffff /* end */
4057 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4058 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4059 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4062 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4063 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4064 hr = IDirect3DDevice9_BeginScene(device);
4065 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4066 if(SUCCEEDED(hr))
4068 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4069 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4071 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4072 hr = IDirect3DDevice9_EndScene(device);
4073 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4075 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4076 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4077 color = getPixelColor(device, 63, 46);
4078 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4079 color = getPixelColor(device, 66, 46);
4080 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4081 color = getPixelColor(device, 63, 49);
4082 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4083 color = getPixelColor(device, 66, 49);
4084 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4086 color = getPixelColor(device, 578, 46);
4087 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4088 color = getPixelColor(device, 575, 46);
4089 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4090 color = getPixelColor(device, 578, 49);
4091 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4092 color = getPixelColor(device, 575, 49);
4093 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4095 color = getPixelColor(device, 63, 430);
4096 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4097 color = getPixelColor(device, 63, 433);
4098 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4099 color = getPixelColor(device, 66, 433);
4100 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4101 color = getPixelColor(device, 66, 430);
4102 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4104 color = getPixelColor(device, 578, 430);
4105 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4106 color = getPixelColor(device, 578, 433);
4107 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4108 color = getPixelColor(device, 575, 433);
4109 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4110 color = getPixelColor(device, 575, 430);
4111 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4113 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4114 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4115 IDirect3DPixelShader9_Release(shader);
4117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4118 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4119 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4120 if(FAILED(hr)) {
4121 skip("Failed to create 2.0 test shader, most likely not supported\n");
4122 return;
4125 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4126 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4127 hr = IDirect3DDevice9_BeginScene(device);
4128 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4129 if(SUCCEEDED(hr))
4131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4132 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4133 hr = IDirect3DDevice9_EndScene(device);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4136 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4138 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4139 color = getPixelColor(device, 63, 46);
4140 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4141 color = getPixelColor(device, 66, 46);
4142 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4143 color = getPixelColor(device, 63, 49);
4144 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4145 color = getPixelColor(device, 66, 49);
4146 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4148 color = getPixelColor(device, 578, 46);
4149 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4150 color = getPixelColor(device, 575, 46);
4151 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4152 color = getPixelColor(device, 578, 49);
4153 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4154 color = getPixelColor(device, 575, 49);
4155 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4157 color = getPixelColor(device, 63, 430);
4158 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4159 color = getPixelColor(device, 63, 433);
4160 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4161 color = getPixelColor(device, 66, 433);
4162 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4163 color = getPixelColor(device, 66, 430);
4164 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4166 color = getPixelColor(device, 578, 430);
4167 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4168 color = getPixelColor(device, 578, 433);
4169 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4170 color = getPixelColor(device, 575, 433);
4171 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4172 color = getPixelColor(device, 575, 430);
4173 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4175 /* Cleanup */
4176 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4177 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4178 IDirect3DPixelShader9_Release(shader);
4181 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4183 IDirect3D9 *d3d9;
4184 HRESULT hr;
4185 IDirect3DTexture9 *texture;
4186 IDirect3DPixelShader9 *shader;
4187 IDirect3DPixelShader9 *shader2;
4188 D3DLOCKED_RECT lr;
4189 DWORD color;
4190 DWORD shader_code[] = {
4191 0xffff0101, /* ps_1_1 */
4192 0x00000042, 0xb00f0000, /* tex t0 */
4193 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4194 0x0000ffff /* end */
4196 DWORD shader_code2[] = {
4197 0xffff0101, /* ps_1_1 */
4198 0x00000042, 0xb00f0000, /* tex t0 */
4199 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4200 0x0000ffff /* end */
4203 float quad[] = {
4204 -1.0, -1.0, 0.1, 0.5, 0.5,
4205 1.0, -1.0, 0.1, 0.5, 0.5,
4206 -1.0, 1.0, 0.1, 0.5, 0.5,
4207 1.0, 1.0, 0.1, 0.5, 0.5,
4210 memset(&lr, 0, sizeof(lr));
4211 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4212 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4213 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4214 IDirect3D9_Release(d3d9);
4215 if(FAILED(hr)) {
4216 skip("No D3DFMT_X8L8V8U8 support\n");
4219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4222 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4223 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4224 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4225 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4226 *((DWORD *) lr.pBits) = 0x11ca3141;
4227 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4228 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4230 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4231 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4232 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4233 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4235 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4236 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4237 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4238 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4239 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4240 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4242 hr = IDirect3DDevice9_BeginScene(device);
4243 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4244 if(SUCCEEDED(hr))
4246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4247 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4249 hr = IDirect3DDevice9_EndScene(device);
4250 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4252 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4253 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4254 color = getPixelColor(device, 578, 430);
4255 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4256 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4258 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4259 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4260 hr = IDirect3DDevice9_BeginScene(device);
4261 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4262 if(SUCCEEDED(hr))
4264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4265 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4267 hr = IDirect3DDevice9_EndScene(device);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4270 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4272 color = getPixelColor(device, 578, 430);
4273 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4275 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4276 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4277 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4278 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4279 IDirect3DPixelShader9_Release(shader);
4280 IDirect3DPixelShader9_Release(shader2);
4281 IDirect3DTexture9_Release(texture);
4284 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4286 HRESULT hr;
4287 IDirect3D9 *d3d;
4288 IDirect3DTexture9 *texture = NULL;
4289 IDirect3DSurface9 *surface;
4290 DWORD color;
4291 const RECT r1 = {256, 256, 512, 512};
4292 const RECT r2 = {512, 256, 768, 512};
4293 const RECT r3 = {256, 512, 512, 768};
4294 const RECT r4 = {512, 512, 768, 768};
4295 unsigned int x, y;
4296 D3DLOCKED_RECT lr;
4297 memset(&lr, 0, sizeof(lr));
4299 IDirect3DDevice9_GetDirect3D(device, &d3d);
4300 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4301 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4302 skip("No autogenmipmap support\n");
4303 IDirect3D9_Release(d3d);
4304 return;
4306 IDirect3D9_Release(d3d);
4308 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4311 /* Make the mipmap big, so that a smaller mipmap is used
4313 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4314 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4315 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4317 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4318 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4319 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4320 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4321 for(y = 0; y < 1024; y++) {
4322 for(x = 0; x < 1024; x++) {
4323 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4324 POINT pt;
4326 pt.x = x;
4327 pt.y = y;
4328 if(PtInRect(&r1, pt)) {
4329 *dst = 0xffff0000;
4330 } else if(PtInRect(&r2, pt)) {
4331 *dst = 0xff00ff00;
4332 } else if(PtInRect(&r3, pt)) {
4333 *dst = 0xff0000ff;
4334 } else if(PtInRect(&r4, pt)) {
4335 *dst = 0xff000000;
4336 } else {
4337 *dst = 0xffffffff;
4341 hr = IDirect3DSurface9_UnlockRect(surface);
4342 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4343 IDirect3DSurface9_Release(surface);
4345 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4346 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4347 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4348 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4350 hr = IDirect3DDevice9_BeginScene(device);
4351 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4352 if(SUCCEEDED(hr)) {
4353 const float quad[] = {
4354 -0.5, -0.5, 0.1, 0.0, 0.0,
4355 -0.5, 0.5, 0.1, 0.0, 1.0,
4356 0.5, -0.5, 0.1, 1.0, 0.0,
4357 0.5, 0.5, 0.1, 1.0, 1.0
4360 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4361 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4363 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4364 hr = IDirect3DDevice9_EndScene(device);
4365 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4367 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4368 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4369 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4370 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4371 IDirect3DTexture9_Release(texture);
4373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4374 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4375 color = getPixelColor(device, 200, 200);
4376 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4377 color = getPixelColor(device, 280, 200);
4378 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4379 color = getPixelColor(device, 360, 200);
4380 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4381 color = getPixelColor(device, 440, 200);
4382 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4383 color = getPixelColor(device, 200, 270);
4384 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4385 color = getPixelColor(device, 280, 270);
4386 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4387 color = getPixelColor(device, 360, 270);
4388 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4389 color = getPixelColor(device, 440, 270);
4390 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4393 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4395 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4396 IDirect3DVertexDeclaration9 *decl;
4397 HRESULT hr;
4398 DWORD color;
4399 DWORD shader_code_11[] = {
4400 0xfffe0101, /* vs_1_1 */
4401 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4402 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4403 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4404 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4405 0x0000ffff /* end */
4407 DWORD shader_code_11_2[] = {
4408 0xfffe0101, /* vs_1_1 */
4409 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4410 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4411 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4412 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4413 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4414 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4415 0x0000ffff /* end */
4417 DWORD shader_code_20[] = {
4418 0xfffe0200, /* vs_2_0 */
4419 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4420 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4421 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4422 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4423 0x0000ffff /* end */
4425 DWORD shader_code_20_2[] = {
4426 0xfffe0200, /* vs_2_0 */
4427 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4428 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4429 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4430 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4431 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4432 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4433 0x0000ffff /* end */
4435 static const D3DVERTEXELEMENT9 decl_elements[] = {
4436 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4437 D3DDECL_END()
4439 float quad1[] = {
4440 -1.0, -1.0, 0.1,
4441 0.0, -1.0, 0.1,
4442 -1.0, 0.0, 0.1,
4443 0.0, 0.0, 0.1
4445 float quad2[] = {
4446 0.0, -1.0, 0.1,
4447 1.0, -1.0, 0.1,
4448 0.0, 0.0, 0.1,
4449 1.0, 0.0, 0.1
4451 float quad3[] = {
4452 0.0, 0.0, 0.1,
4453 1.0, 0.0, 0.1,
4454 0.0, 1.0, 0.1,
4455 1.0, 1.0, 0.1
4457 float quad4[] = {
4458 -1.0, 0.0, 0.1,
4459 0.0, 0.0, 0.1,
4460 -1.0, 1.0, 0.1,
4461 0.0, 1.0, 0.1
4463 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4464 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4467 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4469 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4470 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4471 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4472 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4473 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4474 if(FAILED(hr)) shader_20 = NULL;
4475 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4476 if(FAILED(hr)) shader_20_2 = NULL;
4477 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4478 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4480 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4481 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4482 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4483 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4484 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4485 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4487 hr = IDirect3DDevice9_BeginScene(device);
4488 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4489 if(SUCCEEDED(hr))
4491 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4494 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4496 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4497 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4499 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4501 if(shader_20) {
4502 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4503 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4505 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4508 if(shader_20_2) {
4509 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4510 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4511 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4512 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4515 hr = IDirect3DDevice9_EndScene(device);
4516 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4518 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4519 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4521 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4522 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4523 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4524 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4526 color = getPixelColor(device, 160, 360);
4527 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4528 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4529 color = getPixelColor(device, 480, 360);
4530 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4531 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4532 if(shader_20) {
4533 color = getPixelColor(device, 160, 120);
4534 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4535 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4537 if(shader_20_2) {
4538 color = getPixelColor(device, 480, 120);
4539 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4540 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4543 IDirect3DVertexDeclaration9_Release(decl);
4544 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4545 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4546 IDirect3DVertexShader9_Release(shader_11_2);
4547 IDirect3DVertexShader9_Release(shader_11);
4550 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4552 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4553 HRESULT hr;
4554 DWORD color;
4555 DWORD shader_code_11[] = {
4556 0xffff0101, /* ps_1_1 */
4557 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4558 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4559 0x0000ffff /* end */
4561 DWORD shader_code_12[] = {
4562 0xffff0102, /* ps_1_2 */
4563 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4564 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4565 0x0000ffff /* end */
4567 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4568 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4569 * During development of this test, 1.3 shaders were verified too
4571 DWORD shader_code_14[] = {
4572 0xffff0104, /* ps_1_4 */
4573 /* Try to make one constant local. It gets clamped too, although the binary contains
4574 * the bigger numbers
4576 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4577 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4578 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4579 0x0000ffff /* end */
4581 DWORD shader_code_20[] = {
4582 0xffff0200, /* ps_2_0 */
4583 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4584 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4585 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4586 0x0000ffff /* end */
4588 float quad1[] = {
4589 -1.0, -1.0, 0.1,
4590 0.0, -1.0, 0.1,
4591 -1.0, 0.0, 0.1,
4592 0.0, 0.0, 0.1
4594 float quad2[] = {
4595 0.0, -1.0, 0.1,
4596 1.0, -1.0, 0.1,
4597 0.0, 0.0, 0.1,
4598 1.0, 0.0, 0.1
4600 float quad3[] = {
4601 0.0, 0.0, 0.1,
4602 1.0, 0.0, 0.1,
4603 0.0, 1.0, 0.1,
4604 1.0, 1.0, 0.1
4606 float quad4[] = {
4607 -1.0, 0.0, 0.1,
4608 0.0, 0.0, 0.1,
4609 -1.0, 1.0, 0.1,
4610 0.0, 1.0, 0.1
4612 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4613 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4616 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4618 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4619 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4620 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4621 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4622 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4623 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4624 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4625 if(FAILED(hr)) shader_20 = NULL;
4627 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4628 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4629 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4630 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4632 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4634 hr = IDirect3DDevice9_BeginScene(device);
4635 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4636 if(SUCCEEDED(hr))
4638 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4639 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4641 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4643 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4644 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4646 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4648 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4649 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4650 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4651 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4653 if(shader_20) {
4654 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4655 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4657 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4660 hr = IDirect3DDevice9_EndScene(device);
4661 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4663 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4664 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4666 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4669 color = getPixelColor(device, 160, 360);
4670 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4671 "quad 1 has color %08x, expected 0x00808000\n", color);
4672 color = getPixelColor(device, 480, 360);
4673 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4674 "quad 2 has color %08x, expected 0x00808000\n", color);
4675 color = getPixelColor(device, 480, 120);
4676 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4677 "quad 3 has color %08x, expected 0x00808000\n", color);
4678 if(shader_20) {
4679 color = getPixelColor(device, 160, 120);
4680 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4681 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4684 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4685 IDirect3DPixelShader9_Release(shader_14);
4686 IDirect3DPixelShader9_Release(shader_12);
4687 IDirect3DPixelShader9_Release(shader_11);
4690 static void dp2add_ps_test(IDirect3DDevice9 *device)
4692 IDirect3DPixelShader9 *shader_dp2add = NULL;
4693 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4694 HRESULT hr;
4695 DWORD color;
4697 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4698 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4699 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4700 * r0 first.
4701 * The result here for the r,g,b components should be roughly 0.5:
4702 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4703 static const DWORD shader_code_dp2add[] = {
4704 0xffff0200, /* ps_2_0 */
4705 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4707 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4708 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4710 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4711 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4712 0x0000ffff /* end */
4715 /* Test the _sat modifier, too. Result here should be:
4716 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4717 * _SAT: ==> 1.0
4718 * ADD: (1.0 + -0.5) = 0.5
4720 static const DWORD shader_code_dp2add_sat[] = {
4721 0xffff0200, /* ps_2_0 */
4722 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4724 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4725 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4726 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4728 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4729 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4730 0x0000ffff /* end */
4733 const float quad[] = {
4734 -1.0, -1.0, 0.1,
4735 1.0, -1.0, 0.1,
4736 -1.0, 1.0, 0.1,
4737 1.0, 1.0, 0.1
4741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4744 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4747 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4748 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4750 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4753 if (shader_dp2add) {
4755 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4756 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4758 hr = IDirect3DDevice9_BeginScene(device);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4760 if(SUCCEEDED(hr))
4762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4763 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4765 hr = IDirect3DDevice9_EndScene(device);
4766 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4768 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4771 color = getPixelColor(device, 360, 240);
4772 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4773 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4775 IDirect3DPixelShader9_Release(shader_dp2add);
4776 } else {
4777 skip("dp2add shader creation failed\n");
4780 if (shader_dp2add_sat) {
4782 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
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);
4795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4798 color = getPixelColor(device, 360, 240);
4799 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4800 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4802 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4803 } else {
4804 skip("dp2add shader creation failed\n");
4807 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4811 static void cnd_test(IDirect3DDevice9 *device)
4813 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4814 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4815 HRESULT hr;
4816 DWORD color;
4817 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4818 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4819 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4821 DWORD shader_code_11[] = {
4822 0xffff0101, /* ps_1_1 */
4823 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4824 0x00000040, 0xb00f0000, /* texcoord t0 */
4825 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4826 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4827 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4828 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4829 0x0000ffff /* end */
4831 DWORD shader_code_12[] = {
4832 0xffff0102, /* ps_1_2 */
4833 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4834 0x00000040, 0xb00f0000, /* texcoord t0 */
4835 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4836 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4837 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4838 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4839 0x0000ffff /* end */
4841 DWORD shader_code_13[] = {
4842 0xffff0103, /* ps_1_3 */
4843 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4844 0x00000040, 0xb00f0000, /* texcoord t0 */
4845 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4846 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4847 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4848 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4849 0x0000ffff /* end */
4851 DWORD shader_code_14[] = {
4852 0xffff0104, /* ps_1_3 */
4853 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4854 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4855 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4856 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4857 0x0000ffff /* end */
4860 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4861 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4862 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4863 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4864 * native CreatePixelShader returns an error.
4866 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4867 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4868 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4869 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4871 DWORD shader_code_11_coissue[] = {
4872 0xffff0101, /* ps_1_1 */
4873 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4874 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4875 0x00000040, 0xb00f0000, /* texcoord t0 */
4876 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4877 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4878 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4879 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4880 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4881 /* 0x40000000 = D3DSI_COISSUE */
4882 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4883 0x0000ffff /* end */
4885 DWORD shader_code_12_coissue[] = {
4886 0xffff0102, /* ps_1_2 */
4887 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4888 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4889 0x00000040, 0xb00f0000, /* texcoord t0 */
4890 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4891 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4892 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4893 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4894 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4895 /* 0x40000000 = D3DSI_COISSUE */
4896 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4897 0x0000ffff /* end */
4899 DWORD shader_code_13_coissue[] = {
4900 0xffff0103, /* ps_1_3 */
4901 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4902 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4903 0x00000040, 0xb00f0000, /* texcoord t0 */
4904 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4905 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4906 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4907 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4908 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4909 /* 0x40000000 = D3DSI_COISSUE */
4910 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4911 0x0000ffff /* end */
4913 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4914 * compare against 0.5
4916 DWORD shader_code_14_coissue[] = {
4917 0xffff0104, /* ps_1_4 */
4918 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4919 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4920 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4921 /* 0x40000000 = D3DSI_COISSUE */
4922 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4923 0x0000ffff /* end */
4925 float quad1[] = {
4926 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4927 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4928 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4929 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4931 float quad2[] = {
4932 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4933 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4934 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4935 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4937 float quad3[] = {
4938 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4939 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4940 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4941 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4943 float quad4[] = {
4944 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4945 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4946 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4947 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4949 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4950 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4951 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4952 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4954 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4957 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4958 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4959 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4960 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4961 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4962 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4963 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4964 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4965 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4966 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4967 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4968 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4969 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4970 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4971 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4972 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4974 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4975 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4976 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4978 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4979 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4981 hr = IDirect3DDevice9_BeginScene(device);
4982 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4983 if(SUCCEEDED(hr))
4985 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4987 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4988 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4990 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4993 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4995 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4996 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4998 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5000 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5001 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5003 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5005 hr = IDirect3DDevice9_EndScene(device);
5006 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5009 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5011 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5012 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5014 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5015 color = getPixelColor(device, 158, 118);
5016 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5017 color = getPixelColor(device, 162, 118);
5018 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5019 color = getPixelColor(device, 158, 122);
5020 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5021 color = getPixelColor(device, 162, 122);
5022 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5024 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5025 color = getPixelColor(device, 158, 358);
5026 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5027 color = getPixelColor(device, 162, 358);
5028 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5029 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5030 color = getPixelColor(device, 158, 362);
5031 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5032 color = getPixelColor(device, 162, 362);
5033 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5034 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5036 /* 1.2 shader */
5037 color = getPixelColor(device, 478, 358);
5038 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5039 color = getPixelColor(device, 482, 358);
5040 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5041 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5042 color = getPixelColor(device, 478, 362);
5043 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5044 color = getPixelColor(device, 482, 362);
5045 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5046 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5048 /* 1.3 shader */
5049 color = getPixelColor(device, 478, 118);
5050 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5051 color = getPixelColor(device, 482, 118);
5052 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5053 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5054 color = getPixelColor(device, 478, 122);
5055 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5056 color = getPixelColor(device, 482, 122);
5057 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5058 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5060 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5061 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5062 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5064 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5065 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5067 hr = IDirect3DDevice9_BeginScene(device);
5068 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5069 if(SUCCEEDED(hr))
5071 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5072 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5074 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5076 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5077 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5078 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5079 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5081 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5082 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5084 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5086 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5087 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5089 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5091 hr = IDirect3DDevice9_EndScene(device);
5092 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5094 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5095 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5097 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5098 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5100 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5101 * that we swapped the values in c1 and c2 to make the other tests return some color
5103 color = getPixelColor(device, 158, 118);
5104 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5105 color = getPixelColor(device, 162, 118);
5106 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5107 color = getPixelColor(device, 158, 122);
5108 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5109 color = getPixelColor(device, 162, 122);
5110 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5112 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5113 color = getPixelColor(device, 158, 358);
5114 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5115 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5116 color = getPixelColor(device, 162, 358);
5117 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5118 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5119 color = getPixelColor(device, 158, 362);
5120 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5121 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5122 color = getPixelColor(device, 162, 362);
5123 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5124 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5126 /* 1.2 shader */
5127 color = getPixelColor(device, 478, 358);
5128 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5129 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5130 color = getPixelColor(device, 482, 358);
5131 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5132 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5133 color = getPixelColor(device, 478, 362);
5134 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5135 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5136 color = getPixelColor(device, 482, 362);
5137 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5138 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5140 /* 1.3 shader */
5141 color = getPixelColor(device, 478, 118);
5142 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5143 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5144 color = getPixelColor(device, 482, 118);
5145 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5146 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5147 color = getPixelColor(device, 478, 122);
5148 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5149 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5150 color = getPixelColor(device, 482, 122);
5151 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5152 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5154 IDirect3DPixelShader9_Release(shader_14_coissue);
5155 IDirect3DPixelShader9_Release(shader_13_coissue);
5156 IDirect3DPixelShader9_Release(shader_12_coissue);
5157 IDirect3DPixelShader9_Release(shader_11_coissue);
5158 IDirect3DPixelShader9_Release(shader_14);
5159 IDirect3DPixelShader9_Release(shader_13);
5160 IDirect3DPixelShader9_Release(shader_12);
5161 IDirect3DPixelShader9_Release(shader_11);
5164 static void nested_loop_test(IDirect3DDevice9 *device) {
5165 const DWORD shader_code[] = {
5166 0xffff0300, /* ps_3_0 */
5167 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5168 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5169 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5170 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5171 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5172 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5173 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5174 0x0000001d, /* endloop */
5175 0x0000001d, /* endloop */
5176 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5177 0x0000ffff /* end */
5179 IDirect3DPixelShader9 *shader;
5180 HRESULT hr;
5181 DWORD color;
5182 const float quad[] = {
5183 -1.0, -1.0, 0.1,
5184 1.0, -1.0, 0.1,
5185 -1.0, 1.0, 0.1,
5186 1.0, 1.0, 0.1
5189 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5190 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5191 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5192 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5193 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5194 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5195 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5196 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5198 hr = IDirect3DDevice9_BeginScene(device);
5199 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5200 if(SUCCEEDED(hr))
5202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5203 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5204 hr = IDirect3DDevice9_EndScene(device);
5205 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5207 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5208 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5210 color = getPixelColor(device, 360, 240);
5211 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5212 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5214 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5215 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5216 IDirect3DPixelShader9_Release(shader);
5219 struct varying_test_struct
5221 const DWORD *shader_code;
5222 IDirect3DPixelShader9 *shader;
5223 DWORD color, color_rhw;
5224 const char *name;
5225 BOOL todo, todo_rhw;
5228 struct hugeVertex
5230 float pos_x, pos_y, pos_z, rhw;
5231 float weight_1, weight_2, weight_3, weight_4;
5232 float index_1, index_2, index_3, index_4;
5233 float normal_1, normal_2, normal_3, normal_4;
5234 float fog_1, fog_2, fog_3, fog_4;
5235 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5236 float tangent_1, tangent_2, tangent_3, tangent_4;
5237 float binormal_1, binormal_2, binormal_3, binormal_4;
5238 float depth_1, depth_2, depth_3, depth_4;
5239 DWORD diffuse, specular;
5242 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5243 /* dcl_position: fails to compile */
5244 const DWORD blendweight_code[] = {
5245 0xffff0300, /* ps_3_0 */
5246 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5247 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5248 0x0000ffff /* end */
5250 const DWORD blendindices_code[] = {
5251 0xffff0300, /* ps_3_0 */
5252 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5253 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5254 0x0000ffff /* end */
5256 const DWORD normal_code[] = {
5257 0xffff0300, /* ps_3_0 */
5258 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5259 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5260 0x0000ffff /* end */
5262 /* psize: fails? */
5263 const DWORD texcoord0_code[] = {
5264 0xffff0300, /* ps_3_0 */
5265 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5266 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5267 0x0000ffff /* end */
5269 const DWORD tangent_code[] = {
5270 0xffff0300, /* ps_3_0 */
5271 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5272 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5273 0x0000ffff /* end */
5275 const DWORD binormal_code[] = {
5276 0xffff0300, /* ps_3_0 */
5277 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5278 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5279 0x0000ffff /* end */
5281 /* tessfactor: fails */
5282 /* positiont: fails */
5283 const DWORD color_code[] = {
5284 0xffff0300, /* ps_3_0 */
5285 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5286 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5287 0x0000ffff /* end */
5289 const DWORD fog_code[] = {
5290 0xffff0300, /* ps_3_0 */
5291 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5292 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5293 0x0000ffff /* end */
5295 const DWORD depth_code[] = {
5296 0xffff0300, /* ps_3_0 */
5297 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5298 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5299 0x0000ffff /* end */
5301 const DWORD specular_code[] = {
5302 0xffff0300, /* ps_3_0 */
5303 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5304 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5305 0x0000ffff /* end */
5307 /* sample: fails */
5309 struct varying_test_struct tests[] = {
5310 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5311 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5312 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5313 /* Why does dx not forward the texcoord? */
5314 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5315 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5316 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5317 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5318 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5319 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5320 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5322 /* Declare a monster vertex type :-) */
5323 static const D3DVERTEXELEMENT9 decl_elements[] = {
5324 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5325 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5326 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5327 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5328 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5329 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5330 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5331 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5332 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5333 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5334 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5335 D3DDECL_END()
5337 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5338 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5339 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5340 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5341 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5342 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5343 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5344 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5345 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5346 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5347 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5348 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5349 D3DDECL_END()
5351 struct hugeVertex data[4] = {
5353 -1.0, -1.0, 0.1, 1.0,
5354 0.1, 0.1, 0.1, 0.1,
5355 0.2, 0.2, 0.2, 0.2,
5356 0.3, 0.3, 0.3, 0.3,
5357 0.4, 0.4, 0.4, 0.4,
5358 0.50, 0.55, 0.55, 0.55,
5359 0.6, 0.6, 0.6, 0.7,
5360 0.7, 0.7, 0.7, 0.6,
5361 0.8, 0.8, 0.8, 0.8,
5362 0xe6e6e6e6, /* 0.9 * 256 */
5363 0x224488ff /* Nothing special */
5366 1.0, -1.0, 0.1, 1.0,
5367 0.1, 0.1, 0.1, 0.1,
5368 0.2, 0.2, 0.2, 0.2,
5369 0.3, 0.3, 0.3, 0.3,
5370 0.4, 0.4, 0.4, 0.4,
5371 0.50, 0.55, 0.55, 0.55,
5372 0.6, 0.6, 0.6, 0.7,
5373 0.7, 0.7, 0.7, 0.6,
5374 0.8, 0.8, 0.8, 0.8,
5375 0xe6e6e6e6, /* 0.9 * 256 */
5376 0x224488ff /* Nothing special */
5379 -1.0, 1.0, 0.1, 1.0,
5380 0.1, 0.1, 0.1, 0.1,
5381 0.2, 0.2, 0.2, 0.2,
5382 0.3, 0.3, 0.3, 0.3,
5383 0.4, 0.4, 0.4, 0.4,
5384 0.50, 0.55, 0.55, 0.55,
5385 0.6, 0.6, 0.6, 0.7,
5386 0.7, 0.7, 0.7, 0.6,
5387 0.8, 0.8, 0.8, 0.8,
5388 0xe6e6e6e6, /* 0.9 * 256 */
5389 0x224488ff /* Nothing special */
5392 1.0, 1.0, 0.1, 1.0,
5393 0.1, 0.1, 0.1, 0.1,
5394 0.2, 0.2, 0.2, 0.2,
5395 0.3, 0.3, 0.3, 0.3,
5396 0.4, 0.4, 0.4, 0.4,
5397 0.50, 0.55, 0.55, 0.55,
5398 0.6, 0.6, 0.6, 0.7,
5399 0.7, 0.7, 0.7, 0.6,
5400 0.8, 0.8, 0.8, 0.8,
5401 0xe6e6e6e6, /* 0.9 * 256 */
5402 0x224488ff /* Nothing special */
5405 struct hugeVertex data2[4];
5406 IDirect3DVertexDeclaration9 *decl;
5407 IDirect3DVertexDeclaration9 *decl2;
5408 HRESULT hr;
5409 unsigned int i;
5410 DWORD color, r, g, b, r_e, g_e, b_e;
5411 BOOL drawok;
5413 memcpy(data2, data, sizeof(data2));
5414 data2[0].pos_x = 0; data2[0].pos_y = 0;
5415 data2[1].pos_x = 640; data2[1].pos_y = 0;
5416 data2[2].pos_x = 0; data2[2].pos_y = 480;
5417 data2[3].pos_x = 640; data2[3].pos_y = 480;
5419 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5420 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5421 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5423 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5424 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5426 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5428 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5429 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5430 tests[i].name, hr);
5433 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5436 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5438 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5439 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5441 hr = IDirect3DDevice9_BeginScene(device);
5442 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5443 drawok = FALSE;
5444 if(SUCCEEDED(hr))
5446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5447 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5448 drawok = SUCCEEDED(hr);
5449 hr = IDirect3DDevice9_EndScene(device);
5450 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5452 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5453 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5455 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5456 * the failure and do not check the color if it failed
5458 if(!drawok) {
5459 continue;
5462 color = getPixelColor(device, 360, 240);
5463 r = color & 0x00ff0000 >> 16;
5464 g = color & 0x0000ff00 >> 8;
5465 b = color & 0x000000ff;
5466 r_e = tests[i].color & 0x00ff0000 >> 16;
5467 g_e = tests[i].color & 0x0000ff00 >> 8;
5468 b_e = tests[i].color & 0x000000ff;
5470 if(tests[i].todo) {
5471 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5472 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5473 tests[i].name, color, tests[i].color);
5474 } else {
5475 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5476 "Test %s returned color 0x%08x, expected 0x%08x\n",
5477 tests[i].name, color, tests[i].color);
5481 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5483 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5486 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5488 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5489 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5491 hr = IDirect3DDevice9_BeginScene(device);
5492 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5493 if(SUCCEEDED(hr))
5495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5496 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5497 hr = IDirect3DDevice9_EndScene(device);
5498 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5500 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5501 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5503 color = getPixelColor(device, 360, 240);
5504 r = color & 0x00ff0000 >> 16;
5505 g = color & 0x0000ff00 >> 8;
5506 b = color & 0x000000ff;
5507 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5508 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5509 b_e = tests[i].color_rhw & 0x000000ff;
5511 if(tests[i].todo_rhw) {
5512 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5513 * pipeline
5515 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5516 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5517 tests[i].name, color, tests[i].color_rhw);
5518 } else {
5519 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5520 "Test %s returned color 0x%08x, expected 0x%08x\n",
5521 tests[i].name, color, tests[i].color_rhw);
5525 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5527 IDirect3DPixelShader9_Release(tests[i].shader);
5530 IDirect3DVertexDeclaration9_Release(decl2);
5531 IDirect3DVertexDeclaration9_Release(decl);
5534 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5535 static const DWORD ps_code[] = {
5536 0xffff0300, /* ps_3_0 */
5537 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5538 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5539 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5540 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5541 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5542 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5543 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5544 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5545 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5547 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5548 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5549 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5550 0x0000001d, /* endloop */
5551 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5552 0x0000ffff /* end */
5554 static const DWORD vs_1_code[] = {
5555 0xfffe0101, /* vs_1_1 */
5556 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5557 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5558 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5559 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5560 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5561 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5562 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5563 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5564 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5565 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5566 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5567 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5568 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5569 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5570 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5571 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5572 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5573 0x0000ffff
5575 DWORD vs_2_code[] = {
5576 0xfffe0200, /* vs_2_0 */
5577 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5578 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5579 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5580 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5581 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5582 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5583 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5584 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5585 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5586 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5587 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5588 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5589 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5590 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5591 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5592 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5593 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5594 0x0000ffff /* end */
5596 /* TODO: Define normal, tangent, blendweight and depth here */
5597 static const DWORD vs_3_code[] = {
5598 0xfffe0300, /* vs_3_0 */
5599 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5600 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5601 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5602 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5603 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5604 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5605 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5606 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5607 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5608 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5609 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5610 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5611 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5612 0x0000ffff /* end */
5614 float quad1[] = {
5615 -1.0, -1.0, 0.1,
5616 0.0, -1.0, 0.1,
5617 -1.0, 0.0, 0.1,
5618 0.0, 0.0, 0.1
5620 float quad2[] = {
5621 0.0, -1.0, 0.1,
5622 1.0, -1.0, 0.1,
5623 0.0, 0.0, 0.1,
5624 1.0, 0.0, 0.1
5626 float quad3[] = {
5627 -1.0, 0.0, 0.1,
5628 0.0, 0.0, 0.1,
5629 -1.0, 1.0, 0.1,
5630 0.0, 1.0, 0.1
5633 HRESULT hr;
5634 DWORD color;
5635 IDirect3DPixelShader9 *pixelshader = NULL;
5636 IDirect3DVertexShader9 *vs_1_shader = NULL;
5637 IDirect3DVertexShader9 *vs_2_shader = NULL;
5638 IDirect3DVertexShader9 *vs_3_shader = NULL;
5640 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5641 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5643 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5644 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5645 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5646 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5647 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5649 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5650 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5651 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5652 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5653 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5655 hr = IDirect3DDevice9_BeginScene(device);
5656 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5657 if(SUCCEEDED(hr))
5659 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5660 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5661 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5662 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5664 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5665 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5666 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5667 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5669 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5670 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5672 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5674 hr = IDirect3DDevice9_EndScene(device);
5675 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5678 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5680 color = getPixelColor(device, 160, 120);
5681 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5682 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5683 /* Accept two ways of oFog handling:
5685 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5686 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5688 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5689 * This happens with software vertex processing and on Intel cards
5691 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5692 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5694 color = getPixelColor(device, 160, 360);
5695 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5696 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5697 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5698 color = getPixelColor(device, 480, 360);
5699 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5700 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5701 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5703 /* cleanup */
5704 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5705 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5706 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5707 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5708 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5709 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5710 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5711 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5714 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5715 static const DWORD vs_code[] = {
5716 0xfffe0300, /* vs_3_0 */
5717 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5718 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5719 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5720 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5721 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5722 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5723 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5724 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5725 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5726 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5727 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5728 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5729 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5731 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5732 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5733 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5734 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5735 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5736 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5737 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5738 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5739 0x0000ffff /* end */
5741 static const DWORD ps_1_code[] = {
5742 0xffff0104, /* ps_1_4 */
5743 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5744 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5745 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5746 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5747 0x0000ffff /* end */
5749 static const DWORD ps_2_code[] = {
5750 0xffff0200, /* ps_2_0 */
5751 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5752 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5753 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5755 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5756 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5757 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5758 0x0000ffff /* end */
5760 static const DWORD ps_3_code[] = {
5761 0xffff0300, /* ps_3_0 */
5762 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5763 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5764 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5766 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5767 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5768 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5769 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5770 0x0000ffff /* end */
5773 float quad1[] = {
5774 -1.0, -1.0, 0.1,
5775 0.0, -1.0, 0.1,
5776 -1.0, 0.0, 0.1,
5777 0.0, 0.0, 0.1
5779 float quad2[] = {
5780 0.0, -1.0, 0.1,
5781 1.0, -1.0, 0.1,
5782 0.0, 0.0, 0.1,
5783 1.0, 0.0, 0.1
5785 float quad3[] = {
5786 -1.0, 0.0, 0.1,
5787 0.0, 0.0, 0.1,
5788 -1.0, 1.0, 0.1,
5789 0.0, 1.0, 0.1
5791 float quad4[] = {
5792 0.0, 0.0, 0.1,
5793 1.0, 0.0, 0.1,
5794 0.0, 1.0, 0.1,
5795 1.0, 1.0, 0.1
5798 HRESULT hr;
5799 DWORD color;
5800 IDirect3DVertexShader9 *vertexshader = NULL;
5801 IDirect3DPixelShader9 *ps_1_shader = NULL;
5802 IDirect3DPixelShader9 *ps_2_shader = NULL;
5803 IDirect3DPixelShader9 *ps_3_shader = NULL;
5804 IDirect3DTexture9 *texture = NULL;
5805 D3DLOCKED_RECT lr;
5806 unsigned int x, y;
5808 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5809 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5811 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5813 if(FAILED(hr)) {
5814 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5815 return;
5817 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5818 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5819 for(y = 0; y < 512; y++) {
5820 for(x = 0; x < 512; x++) {
5821 double r_f = (double) x / (double) 512;
5822 double g_f = (double) y / (double) 512;
5823 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5824 unsigned short r = (unsigned short) (r_f * 65535.0);
5825 unsigned short g = (unsigned short) (g_f * 65535.0);
5826 dst[0] = r;
5827 dst[1] = g;
5828 dst[2] = 0;
5829 dst[3] = 65535;
5832 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5833 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5835 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5836 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5837 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5838 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5839 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5840 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5841 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5842 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5843 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5844 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5845 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5847 hr = IDirect3DDevice9_BeginScene(device);
5848 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5849 if(SUCCEEDED(hr))
5851 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5852 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5853 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5854 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5856 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5857 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5858 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5859 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5861 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5864 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5866 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5867 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5868 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5869 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5870 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5871 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5872 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5873 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5874 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5875 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5876 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5877 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5879 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5881 hr = IDirect3DDevice9_EndScene(device);
5882 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5885 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5887 color = getPixelColor(device, 160, 120);
5888 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5889 (color & 0x0000ff00) == 0x0000ff00 &&
5890 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5891 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5892 color = getPixelColor(device, 160, 360);
5893 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5894 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5895 (color & 0x000000ff) == 0x00000000,
5896 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5897 color = getPixelColor(device, 480, 360);
5898 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5899 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5900 (color & 0x000000ff) == 0x00000000,
5901 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5902 color = getPixelColor(device, 480, 160);
5903 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5904 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5905 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5906 (color & 0x000000ff) == 0x00000000),
5907 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5909 /* cleanup */
5910 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5911 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5912 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5914 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5915 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5916 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5917 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5918 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5919 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5920 if(texture) IDirect3DTexture9_Release(texture);
5923 static void test_compare_instructions(IDirect3DDevice9 *device)
5925 DWORD shader_sge_vec_code[] = {
5926 0xfffe0101, /* vs_1_1 */
5927 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5928 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5929 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5930 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5931 0x0000ffff /* end */
5933 DWORD shader_slt_vec_code[] = {
5934 0xfffe0101, /* vs_1_1 */
5935 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5936 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5937 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5938 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5939 0x0000ffff /* end */
5941 DWORD shader_sge_scalar_code[] = {
5942 0xfffe0101, /* vs_1_1 */
5943 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5944 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5945 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5946 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5947 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5948 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5949 0x0000ffff /* end */
5951 DWORD shader_slt_scalar_code[] = {
5952 0xfffe0101, /* vs_1_1 */
5953 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5954 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5955 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5956 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5957 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5958 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5959 0x0000ffff /* end */
5961 IDirect3DVertexShader9 *shader_sge_vec;
5962 IDirect3DVertexShader9 *shader_slt_vec;
5963 IDirect3DVertexShader9 *shader_sge_scalar;
5964 IDirect3DVertexShader9 *shader_slt_scalar;
5965 HRESULT hr, color;
5966 float quad1[] = {
5967 -1.0, -1.0, 0.1,
5968 0.0, -1.0, 0.1,
5969 -1.0, 0.0, 0.1,
5970 0.0, 0.0, 0.1
5972 float quad2[] = {
5973 0.0, -1.0, 0.1,
5974 1.0, -1.0, 0.1,
5975 0.0, 0.0, 0.1,
5976 1.0, 0.0, 0.1
5978 float quad3[] = {
5979 -1.0, 0.0, 0.1,
5980 0.0, 0.0, 0.1,
5981 -1.0, 1.0, 0.1,
5982 0.0, 1.0, 0.1
5984 float quad4[] = {
5985 0.0, 0.0, 0.1,
5986 1.0, 0.0, 0.1,
5987 0.0, 1.0, 0.1,
5988 1.0, 1.0, 0.1
5990 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5991 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5994 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5996 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5997 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5998 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5999 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6000 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6001 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6002 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6003 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6004 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6005 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6006 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6007 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6008 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6009 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6011 hr = IDirect3DDevice9_BeginScene(device);
6012 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6013 if(SUCCEEDED(hr))
6015 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6016 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6018 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6020 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6021 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6022 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6023 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6025 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6026 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6027 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6028 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6030 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6031 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6033 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6034 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6036 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6038 hr = IDirect3DDevice9_EndScene(device);
6039 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6042 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6043 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6044 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6045 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6047 color = getPixelColor(device, 160, 360);
6048 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6049 color = getPixelColor(device, 480, 360);
6050 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6051 color = getPixelColor(device, 160, 120);
6052 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6053 color = getPixelColor(device, 480, 160);
6054 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6056 IDirect3DVertexShader9_Release(shader_sge_vec);
6057 IDirect3DVertexShader9_Release(shader_slt_vec);
6058 IDirect3DVertexShader9_Release(shader_sge_scalar);
6059 IDirect3DVertexShader9_Release(shader_slt_scalar);
6062 static void test_vshader_input(IDirect3DDevice9 *device)
6064 DWORD swapped_shader_code_3[] = {
6065 0xfffe0300, /* vs_3_0 */
6066 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6067 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6068 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6069 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6070 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6071 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6072 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6073 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6074 0x0000ffff /* end */
6076 DWORD swapped_shader_code_1[] = {
6077 0xfffe0101, /* vs_1_1 */
6078 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6079 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6080 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6081 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6082 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6083 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6084 0x0000ffff /* end */
6086 DWORD swapped_shader_code_2[] = {
6087 0xfffe0200, /* vs_2_0 */
6088 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6089 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6090 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6091 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6092 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6093 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6094 0x0000ffff /* end */
6096 DWORD texcoord_color_shader_code_3[] = {
6097 0xfffe0300, /* vs_3_0 */
6098 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6099 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6100 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6101 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6102 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6103 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6104 0x0000ffff /* end */
6106 DWORD texcoord_color_shader_code_2[] = {
6107 0xfffe0200, /* vs_2_0 */
6108 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6109 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6110 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6111 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6112 0x0000ffff /* end */
6114 DWORD texcoord_color_shader_code_1[] = {
6115 0xfffe0101, /* vs_1_1 */
6116 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6117 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6118 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6119 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6120 0x0000ffff /* end */
6122 DWORD color_color_shader_code_3[] = {
6123 0xfffe0300, /* vs_3_0 */
6124 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6125 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6126 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6127 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6128 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6129 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6130 0x0000ffff /* end */
6132 DWORD color_color_shader_code_2[] = {
6133 0xfffe0200, /* vs_2_0 */
6134 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6135 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6136 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6137 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6138 0x0000ffff /* end */
6140 DWORD color_color_shader_code_1[] = {
6141 0xfffe0101, /* vs_1_1 */
6142 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6143 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6144 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6145 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6146 0x0000ffff /* end */
6148 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6149 HRESULT hr;
6150 DWORD color;
6151 float quad1[] = {
6152 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6153 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6154 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6155 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6157 float quad2[] = {
6158 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6159 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6160 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6161 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6163 float quad3[] = {
6164 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6165 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6166 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6167 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6169 float quad4[] = {
6170 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6171 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6172 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6173 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6175 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6176 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6177 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6178 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6179 D3DDECL_END()
6181 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6182 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6183 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6184 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6185 D3DDECL_END()
6187 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6188 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6189 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6190 D3DDECL_END()
6192 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6193 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6194 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6195 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6196 D3DDECL_END()
6198 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6199 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6200 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6201 D3DDECL_END()
6203 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6204 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6205 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6206 D3DDECL_END()
6208 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6209 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6210 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6211 D3DDECL_END()
6213 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6214 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6215 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6216 D3DDECL_END()
6218 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6219 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6220 unsigned int i;
6221 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6222 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6224 struct vertex quad1_color[] = {
6225 {-1.0, -1.0, 0.1, 0x00ff8040},
6226 { 0.0, -1.0, 0.1, 0x00ff8040},
6227 {-1.0, 0.0, 0.1, 0x00ff8040},
6228 { 0.0, 0.0, 0.1, 0x00ff8040}
6230 struct vertex quad2_color[] = {
6231 { 0.0, -1.0, 0.1, 0x00ff8040},
6232 { 1.0, -1.0, 0.1, 0x00ff8040},
6233 { 0.0, 0.0, 0.1, 0x00ff8040},
6234 { 1.0, 0.0, 0.1, 0x00ff8040}
6236 struct vertex quad3_color[] = {
6237 {-1.0, 0.0, 0.1, 0x00ff8040},
6238 { 0.0, 0.0, 0.1, 0x00ff8040},
6239 {-1.0, 1.0, 0.1, 0x00ff8040},
6240 { 0.0, 1.0, 0.1, 0x00ff8040}
6242 float quad4_color[] = {
6243 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6244 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6245 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6246 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6249 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6250 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6251 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6252 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6253 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6254 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6255 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6258 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6259 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6260 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6262 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6263 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6264 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6265 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6267 for(i = 1; i <= 3; i++) {
6268 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6269 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6270 if(i == 3) {
6271 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6272 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6273 } else if(i == 2){
6274 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6275 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6276 } else if(i == 1) {
6277 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6278 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6281 hr = IDirect3DDevice9_BeginScene(device);
6282 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6283 if(SUCCEEDED(hr))
6285 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6286 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6288 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6290 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6291 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6293 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6294 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6296 if(i == 3 || i == 2) {
6297 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6298 } else if(i == 1) {
6299 /* Succeeds or fails, depending on SW or HW vertex processing */
6300 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6303 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6306 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6308 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6309 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6311 if(i == 3 || i == 2) {
6312 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6313 } else if(i == 1) {
6314 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6317 hr = IDirect3DDevice9_EndScene(device);
6318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6321 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6322 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6324 if(i == 3 || i == 2) {
6325 color = getPixelColor(device, 160, 360);
6326 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6327 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6329 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6330 color = getPixelColor(device, 480, 360);
6331 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6332 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6333 color = getPixelColor(device, 160, 120);
6334 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6335 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6336 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6338 color = getPixelColor(device, 480, 160);
6339 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6340 } else if(i == 1) {
6341 color = getPixelColor(device, 160, 360);
6342 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6343 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6344 color = getPixelColor(device, 480, 360);
6345 /* Accept the clear color as well in this case, since SW VP returns an error */
6346 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6347 color = getPixelColor(device, 160, 120);
6348 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6349 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6350 color = getPixelColor(device, 480, 160);
6351 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6354 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6355 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6357 /* Now find out if the whole streams are re-read, or just the last active value for the
6358 * vertices is used.
6360 hr = IDirect3DDevice9_BeginScene(device);
6361 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6362 if(SUCCEEDED(hr))
6364 float quad1_modified[] = {
6365 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6366 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6367 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6368 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6370 float quad2_modified[] = {
6371 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6372 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6373 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6374 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6377 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6378 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6380 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6381 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6383 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6385 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6386 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6388 if(i == 3 || i == 2) {
6389 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6390 } else if(i == 1) {
6391 /* Succeeds or fails, depending on SW or HW vertex processing */
6392 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6395 hr = IDirect3DDevice9_EndScene(device);
6396 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6398 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6399 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6401 color = getPixelColor(device, 480, 350);
6402 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6403 * as well.
6405 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6406 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6407 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6408 * refrast's result.
6410 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6412 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6413 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6415 IDirect3DDevice9_SetVertexShader(device, NULL);
6416 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6418 IDirect3DVertexShader9_Release(swapped_shader);
6421 for(i = 1; i <= 3; i++) {
6422 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6423 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6424 if(i == 3) {
6425 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6426 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6427 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6428 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6429 } else if(i == 2){
6430 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6431 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6432 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6434 } else if(i == 1) {
6435 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6436 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6437 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6438 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6441 hr = IDirect3DDevice9_BeginScene(device);
6442 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6443 if(SUCCEEDED(hr))
6445 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6446 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6447 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6448 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6450 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6452 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6453 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6455 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6456 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6457 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6458 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6460 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6462 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6464 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6465 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6467 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6469 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6470 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6472 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6474 hr = IDirect3DDevice9_EndScene(device);
6475 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6477 IDirect3DDevice9_SetVertexShader(device, NULL);
6478 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6480 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6481 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6483 color = getPixelColor(device, 160, 360);
6484 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6485 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6486 color = getPixelColor(device, 480, 360);
6487 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6488 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6489 color = getPixelColor(device, 160, 120);
6490 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6491 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6492 color = getPixelColor(device, 480, 160);
6493 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6494 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6496 IDirect3DVertexShader9_Release(texcoord_color_shader);
6497 IDirect3DVertexShader9_Release(color_color_shader);
6500 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6501 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6502 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6503 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6505 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6506 IDirect3DVertexDeclaration9_Release(decl_color_color);
6507 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6508 IDirect3DVertexDeclaration9_Release(decl_color_float);
6511 static void srgbtexture_test(IDirect3DDevice9 *device)
6513 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6514 * texture stage state to render a quad using that texture. The resulting
6515 * color components should be 0x36 (~ 0.21), per this formula:
6516 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6517 * This is true where srgb_color > 0.04045.
6519 IDirect3D9 *d3d = NULL;
6520 HRESULT hr;
6521 LPDIRECT3DTEXTURE9 texture = NULL;
6522 LPDIRECT3DSURFACE9 surface = NULL;
6523 D3DLOCKED_RECT lr;
6524 DWORD color;
6525 float quad[] = {
6526 -1.0, 1.0, 0.0, 0.0, 0.0,
6527 1.0, 1.0, 0.0, 1.0, 0.0,
6528 -1.0, -1.0, 0.0, 0.0, 1.0,
6529 1.0, -1.0, 0.0, 1.0, 1.0,
6533 memset(&lr, 0, sizeof(lr));
6534 IDirect3DDevice9_GetDirect3D(device, &d3d);
6535 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6536 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6537 D3DFMT_A8R8G8B8) != D3D_OK) {
6538 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6539 goto out;
6542 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6543 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6544 &texture, NULL);
6545 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6546 if(!texture) {
6547 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6548 goto out;
6550 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6551 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6553 fill_surface(surface, 0xff7f7f7f);
6554 IDirect3DSurface9_Release(surface);
6556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6558 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6559 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6561 hr = IDirect3DDevice9_BeginScene(device);
6562 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6563 if(SUCCEEDED(hr))
6565 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6566 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6568 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6573 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6575 hr = IDirect3DDevice9_EndScene(device);
6576 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6579 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6580 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6581 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6582 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6584 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6585 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6587 color = getPixelColor(device, 320, 240);
6588 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6590 out:
6591 if(texture) IDirect3DTexture9_Release(texture);
6592 IDirect3D9_Release(d3d);
6595 static void shademode_test(IDirect3DDevice9 *device)
6597 /* Render a quad and try all of the different fixed function shading models. */
6598 HRESULT hr;
6599 DWORD color0, color1;
6600 DWORD color0_gouraud = 0, color1_gouraud = 0;
6601 DWORD shademode = D3DSHADE_FLAT;
6602 DWORD primtype = D3DPT_TRIANGLESTRIP;
6603 LPVOID data = NULL;
6604 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6605 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6606 UINT i, j;
6607 struct vertex quad_strip[] =
6609 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6610 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6611 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6612 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6614 struct vertex quad_list[] =
6616 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6617 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6618 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6620 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6621 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6622 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6625 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6626 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6627 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6628 if (FAILED(hr)) goto bail;
6630 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6631 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6632 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6633 if (FAILED(hr)) goto bail;
6635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6636 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6638 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6639 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6641 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6642 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6643 memcpy(data, quad_strip, sizeof(quad_strip));
6644 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6645 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6647 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6648 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6649 memcpy(data, quad_list, sizeof(quad_list));
6650 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6651 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6653 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6654 * the color fixups we have to do for FLAT shading will be dependent on that. */
6655 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6656 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6658 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6659 for (j=0; j<2; j++) {
6661 /* Inner loop just changes the D3DRS_SHADEMODE */
6662 for (i=0; i<3; i++) {
6663 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6669 hr = IDirect3DDevice9_BeginScene(device);
6670 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6671 if(SUCCEEDED(hr))
6673 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6674 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6676 hr = IDirect3DDevice9_EndScene(device);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6680 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6681 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6683 /* Sample two spots from the output */
6684 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6685 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6686 switch(shademode) {
6687 case D3DSHADE_FLAT:
6688 /* Should take the color of the first vertex of each triangle */
6689 if (0)
6691 /* This test depends on EXT_provoking_vertex being
6692 * available. This extension is currently (20090810)
6693 * not common enough to let the test fail if it isn't
6694 * present. */
6695 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6696 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6698 shademode = D3DSHADE_GOURAUD;
6699 break;
6700 case D3DSHADE_GOURAUD:
6701 /* Should be an interpolated blend */
6703 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6704 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6705 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6706 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6708 color0_gouraud = color0;
6709 color1_gouraud = color1;
6711 shademode = D3DSHADE_PHONG;
6712 break;
6713 case D3DSHADE_PHONG:
6714 /* Should be the same as GOURAUD, since no hardware implements this */
6715 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6716 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6717 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6718 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6720 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6721 color0_gouraud, color0);
6722 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6723 color1_gouraud, color1);
6724 break;
6727 /* Now, do it all over again with a TRIANGLELIST */
6728 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6729 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6730 primtype = D3DPT_TRIANGLELIST;
6731 shademode = D3DSHADE_FLAT;
6734 bail:
6735 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6738 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6740 if (vb_strip)
6741 IDirect3DVertexBuffer9_Release(vb_strip);
6742 if (vb_list)
6743 IDirect3DVertexBuffer9_Release(vb_list);
6747 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6749 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6750 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6751 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6752 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6753 * 0.73
6755 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6756 * so use shaders for this task
6758 IDirect3DPixelShader9 *pshader;
6759 IDirect3DVertexShader9 *vshader;
6760 IDirect3D9 *d3d;
6761 DWORD vshader_code[] = {
6762 0xfffe0101, /* vs_1_1 */
6763 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6764 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6765 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6766 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6767 0x0000ffff /* end */
6769 DWORD pshader_code[] = {
6770 0xffff0101, /* ps_1_1 */
6771 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6772 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6773 0x0000ffff /* end */
6775 const float quad[] = {
6776 -1.0, -1.0, 0.1,
6777 1.0, -1.0, 0.1,
6778 -1.0, 1.0, 0.1,
6779 1.0, 1.0, 0.1
6781 HRESULT hr;
6782 D3DCOLOR color;
6784 IDirect3DDevice9_GetDirect3D(device, &d3d);
6785 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6786 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6787 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6788 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6789 * works
6791 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6792 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6793 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6794 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6795 IDirect3D9_Release(d3d);
6796 return;
6798 IDirect3D9_Release(d3d);
6800 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6801 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6804 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6806 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6808 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6810 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6812 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6814 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6815 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6816 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6817 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6818 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6819 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6820 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6821 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6822 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6823 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6825 hr = IDirect3DDevice9_BeginScene(device);
6826 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6827 if(SUCCEEDED(hr)) {
6828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6829 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6831 hr = IDirect3DDevice9_EndScene(device);
6832 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6835 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6836 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6837 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6838 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6839 IDirect3DPixelShader9_Release(pshader);
6840 IDirect3DVertexShader9_Release(vshader);
6842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6843 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6847 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6848 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6849 color = getPixelColor(device, 160, 360);
6850 ok(color_match(color, 0x00808080, 1),
6851 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6854 static void alpha_test(IDirect3DDevice9 *device)
6856 HRESULT hr;
6857 IDirect3DTexture9 *offscreenTexture;
6858 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6859 DWORD color;
6861 struct vertex quad1[] =
6863 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6864 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6865 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6866 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6868 struct vertex quad2[] =
6870 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6871 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6872 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6873 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6875 static const float composite_quad[][5] = {
6876 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6877 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6878 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6879 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6882 /* Clear the render target with alpha = 0.5 */
6883 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6884 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6886 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6887 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6889 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6890 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6891 if(!backbuffer) {
6892 goto out;
6895 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6896 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6897 if(!offscreen) {
6898 goto out;
6901 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6902 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6904 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6905 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6906 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6907 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6908 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6909 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6910 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6911 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6913 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6917 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6919 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6921 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6923 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6925 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6928 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6930 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6932 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6934 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6935 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6936 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6937 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6938 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6940 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6943 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6945 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6947 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6950 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6952 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6954 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6956 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6957 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6959 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6960 * Disable alpha blending for the final composition
6962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6963 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6964 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6967 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6968 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6970 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6971 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6972 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6974 hr = IDirect3DDevice9_EndScene(device);
6975 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6978 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6980 color = getPixelColor(device, 160, 360);
6981 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6982 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6984 color = getPixelColor(device, 160, 120);
6985 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6986 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6988 color = getPixelColor(device, 480, 360);
6989 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6990 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6992 color = getPixelColor(device, 480, 120);
6993 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6994 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6996 out:
6997 /* restore things */
6998 if(backbuffer) {
6999 IDirect3DSurface9_Release(backbuffer);
7001 if(offscreenTexture) {
7002 IDirect3DTexture9_Release(offscreenTexture);
7004 if(offscreen) {
7005 IDirect3DSurface9_Release(offscreen);
7009 struct vertex_shortcolor {
7010 float x, y, z;
7011 unsigned short r, g, b, a;
7013 struct vertex_floatcolor {
7014 float x, y, z;
7015 float r, g, b, a;
7018 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7020 HRESULT hr;
7021 BOOL s_ok, ub_ok, f_ok;
7022 DWORD color, size, i;
7023 void *data;
7024 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7025 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7026 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7027 D3DDECL_END()
7029 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7030 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7031 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7032 D3DDECL_END()
7034 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7035 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7036 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7037 D3DDECL_END()
7039 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7040 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7041 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7042 D3DDECL_END()
7044 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7045 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7046 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7047 D3DDECL_END()
7049 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7050 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7051 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7052 D3DDECL_END()
7054 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7055 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7056 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7057 D3DDECL_END()
7059 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7060 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7061 IDirect3DVertexBuffer9 *vb, *vb2;
7062 struct vertex quad1[] = /* D3DCOLOR */
7064 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7065 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7066 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7067 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7069 struct vertex quad2[] = /* UBYTE4N */
7071 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7072 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7073 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7074 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7076 struct vertex_shortcolor quad3[] = /* short */
7078 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7079 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7080 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7081 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7083 struct vertex_floatcolor quad4[] =
7085 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7086 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7087 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7088 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7090 DWORD colors[] = {
7091 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7092 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7093 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7094 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7095 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7096 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7097 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7098 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7099 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7100 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7101 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7102 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7103 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7104 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7105 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7106 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7108 float quads[] = {
7109 -1.0, -1.0, 0.1,
7110 -1.0, 0.0, 0.1,
7111 0.0, -1.0, 0.1,
7112 0.0, 0.0, 0.1,
7114 0.0, -1.0, 0.1,
7115 0.0, 0.0, 0.1,
7116 1.0, -1.0, 0.1,
7117 1.0, 0.0, 0.1,
7119 0.0, 0.0, 0.1,
7120 0.0, 1.0, 0.1,
7121 1.0, 0.0, 0.1,
7122 1.0, 1.0, 0.1,
7124 -1.0, 0.0, 0.1,
7125 -1.0, 1.0, 0.1,
7126 0.0, 0.0, 0.1,
7127 0.0, 1.0, 0.1
7129 struct tvertex quad_transformed[] = {
7130 { 90, 110, 0.1, 2.0, 0x00ffff00},
7131 { 570, 110, 0.1, 2.0, 0x00ffff00},
7132 { 90, 300, 0.1, 2.0, 0x00ffff00},
7133 { 570, 300, 0.1, 2.0, 0x00ffff00}
7135 D3DCAPS9 caps;
7137 memset(&caps, 0, sizeof(caps));
7138 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7139 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7142 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7144 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7145 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7146 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7147 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7148 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7149 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7150 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7151 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7152 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7153 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7154 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7155 } else {
7156 trace("D3DDTCAPS_UBYTE4N not supported\n");
7157 dcl_ubyte_2 = NULL;
7158 dcl_ubyte = NULL;
7160 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7161 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7162 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7163 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7165 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7166 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7167 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7168 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7170 hr = IDirect3DDevice9_BeginScene(device);
7171 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7172 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7173 if(SUCCEEDED(hr)) {
7174 if(dcl_color) {
7175 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7176 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7177 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7178 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7181 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7182 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7183 * using software vertex processing. Doh!
7185 if(dcl_ubyte) {
7186 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7187 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7189 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7190 ub_ok = SUCCEEDED(hr);
7193 if(dcl_short) {
7194 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7195 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7197 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7198 s_ok = SUCCEEDED(hr);
7201 if(dcl_float) {
7202 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7203 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7205 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7206 f_ok = SUCCEEDED(hr);
7209 hr = IDirect3DDevice9_EndScene(device);
7210 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7213 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7214 if(dcl_short) {
7215 color = getPixelColor(device, 480, 360);
7216 ok(color == 0x000000ff || !s_ok,
7217 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7219 if(dcl_ubyte) {
7220 color = getPixelColor(device, 160, 120);
7221 ok(color == 0x0000ffff || !ub_ok,
7222 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7224 if(dcl_color) {
7225 color = getPixelColor(device, 160, 360);
7226 ok(color == 0x00ffff00,
7227 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7229 if(dcl_float) {
7230 color = getPixelColor(device, 480, 120);
7231 ok(color == 0x00ff0000 || !f_ok,
7232 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7235 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7236 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7237 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7238 * whether the immediate mode code works
7240 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7241 hr = IDirect3DDevice9_BeginScene(device);
7242 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7243 if(SUCCEEDED(hr)) {
7244 if(dcl_color) {
7245 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7246 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7247 memcpy(data, quad1, sizeof(quad1));
7248 hr = IDirect3DVertexBuffer9_Unlock(vb);
7249 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7250 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7251 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7252 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7253 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7254 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7255 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7258 if(dcl_ubyte) {
7259 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7260 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7261 memcpy(data, quad2, sizeof(quad2));
7262 hr = IDirect3DVertexBuffer9_Unlock(vb);
7263 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7264 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7265 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7266 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7267 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7268 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7269 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7270 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7271 ub_ok = SUCCEEDED(hr);
7274 if(dcl_short) {
7275 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7276 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7277 memcpy(data, quad3, sizeof(quad3));
7278 hr = IDirect3DVertexBuffer9_Unlock(vb);
7279 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7280 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7281 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7282 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7283 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7284 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7285 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7286 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7287 s_ok = SUCCEEDED(hr);
7290 if(dcl_float) {
7291 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7292 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7293 memcpy(data, quad4, sizeof(quad4));
7294 hr = IDirect3DVertexBuffer9_Unlock(vb);
7295 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7296 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7297 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7298 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7299 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7300 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7301 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7302 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7303 f_ok = SUCCEEDED(hr);
7306 hr = IDirect3DDevice9_EndScene(device);
7307 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7310 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7311 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7312 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7313 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7315 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7316 if(dcl_short) {
7317 color = getPixelColor(device, 480, 360);
7318 ok(color == 0x000000ff || !s_ok,
7319 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7321 if(dcl_ubyte) {
7322 color = getPixelColor(device, 160, 120);
7323 ok(color == 0x0000ffff || !ub_ok,
7324 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7326 if(dcl_color) {
7327 color = getPixelColor(device, 160, 360);
7328 ok(color == 0x00ffff00,
7329 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7331 if(dcl_float) {
7332 color = getPixelColor(device, 480, 120);
7333 ok(color == 0x00ff0000 || !f_ok,
7334 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7338 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7340 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7341 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7342 memcpy(data, quad_transformed, sizeof(quad_transformed));
7343 hr = IDirect3DVertexBuffer9_Unlock(vb);
7344 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7346 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7349 hr = IDirect3DDevice9_BeginScene(device);
7350 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7351 if(SUCCEEDED(hr)) {
7352 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7353 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7354 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7355 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7357 hr = IDirect3DDevice9_EndScene(device);
7358 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7361 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7362 color = getPixelColor(device, 88, 108);
7363 ok(color == 0x000000ff,
7364 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7365 color = getPixelColor(device, 92, 108);
7366 ok(color == 0x000000ff,
7367 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7368 color = getPixelColor(device, 88, 112);
7369 ok(color == 0x000000ff,
7370 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7371 color = getPixelColor(device, 92, 112);
7372 ok(color == 0x00ffff00,
7373 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7375 color = getPixelColor(device, 568, 108);
7376 ok(color == 0x000000ff,
7377 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7378 color = getPixelColor(device, 572, 108);
7379 ok(color == 0x000000ff,
7380 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7381 color = getPixelColor(device, 568, 112);
7382 ok(color == 0x00ffff00,
7383 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7384 color = getPixelColor(device, 572, 112);
7385 ok(color == 0x000000ff,
7386 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7388 color = getPixelColor(device, 88, 298);
7389 ok(color == 0x000000ff,
7390 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7391 color = getPixelColor(device, 92, 298);
7392 ok(color == 0x00ffff00,
7393 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7394 color = getPixelColor(device, 88, 302);
7395 ok(color == 0x000000ff,
7396 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7397 color = getPixelColor(device, 92, 302);
7398 ok(color == 0x000000ff,
7399 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7401 color = getPixelColor(device, 568, 298);
7402 ok(color == 0x00ffff00,
7403 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7404 color = getPixelColor(device, 572, 298);
7405 ok(color == 0x000000ff,
7406 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7407 color = getPixelColor(device, 568, 302);
7408 ok(color == 0x000000ff,
7409 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7410 color = getPixelColor(device, 572, 302);
7411 ok(color == 0x000000ff,
7412 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7414 /* This test is pointless without those two declarations: */
7415 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7416 skip("color-ubyte switching test declarations aren't supported\n");
7417 goto out;
7420 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7421 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7422 memcpy(data, quads, sizeof(quads));
7423 hr = IDirect3DVertexBuffer9_Unlock(vb);
7424 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7425 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7426 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7427 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7428 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7429 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7430 memcpy(data, colors, sizeof(colors));
7431 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7432 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7434 for(i = 0; i < 2; i++) {
7435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7436 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7438 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7439 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7440 if(i == 0) {
7441 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7442 } else {
7443 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7445 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7447 hr = IDirect3DDevice9_BeginScene(device);
7448 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7449 ub_ok = FALSE;
7450 if(SUCCEEDED(hr)) {
7451 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7452 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7453 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7454 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7455 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7456 ub_ok = SUCCEEDED(hr);
7458 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7459 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7460 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7461 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7463 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7465 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7466 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7467 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7468 ub_ok = (SUCCEEDED(hr) && ub_ok);
7470 hr = IDirect3DDevice9_EndScene(device);
7471 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7474 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7475 if(i == 0) {
7476 color = getPixelColor(device, 480, 360);
7477 ok(color == 0x00ff0000,
7478 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7479 color = getPixelColor(device, 160, 120);
7480 ok(color == 0x00ffffff,
7481 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7482 color = getPixelColor(device, 160, 360);
7483 ok(color == 0x000000ff || !ub_ok,
7484 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7485 color = getPixelColor(device, 480, 120);
7486 ok(color == 0x000000ff || !ub_ok,
7487 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7488 } else {
7489 color = getPixelColor(device, 480, 360);
7490 ok(color == 0x000000ff,
7491 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7492 color = getPixelColor(device, 160, 120);
7493 ok(color == 0x00ffffff,
7494 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7495 color = getPixelColor(device, 160, 360);
7496 ok(color == 0x00ff0000 || !ub_ok,
7497 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7498 color = getPixelColor(device, 480, 120);
7499 ok(color == 0x00ff0000 || !ub_ok,
7500 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7504 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7505 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7506 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7507 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7508 IDirect3DVertexBuffer9_Release(vb2);
7510 out:
7511 IDirect3DVertexBuffer9_Release(vb);
7512 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7513 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7514 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7515 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7516 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7517 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7518 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7521 struct vertex_float16color {
7522 float x, y, z;
7523 DWORD c1, c2;
7526 static void test_vshader_float16(IDirect3DDevice9 *device)
7528 HRESULT hr;
7529 DWORD color;
7530 void *data;
7531 static const D3DVERTEXELEMENT9 decl_elements[] = {
7532 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7533 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7534 D3DDECL_END()
7536 IDirect3DVertexDeclaration9 *vdecl = NULL;
7537 IDirect3DVertexBuffer9 *buffer = NULL;
7538 IDirect3DVertexShader9 *shader;
7539 DWORD shader_code[] = {
7540 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7541 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7542 0x90e40001, 0x0000ffff
7544 struct vertex_float16color quad[] = {
7545 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7546 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7547 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7548 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7550 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7551 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7552 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7553 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7555 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7556 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7557 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7558 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7560 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7561 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7562 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7563 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7566 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7567 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7569 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7570 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7571 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7572 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7573 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7574 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7576 hr = IDirect3DDevice9_BeginScene(device);
7577 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7578 if(SUCCEEDED(hr)) {
7579 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7580 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7582 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7583 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7584 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7586 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7588 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7590 hr = IDirect3DDevice9_EndScene(device);
7591 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7593 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7594 color = getPixelColor(device, 480, 360);
7595 ok(color == 0x00ff0000,
7596 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7597 color = getPixelColor(device, 160, 120);
7598 ok(color == 0x00000000,
7599 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7600 color = getPixelColor(device, 160, 360);
7601 ok(color == 0x0000ff00,
7602 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7603 color = getPixelColor(device, 480, 120);
7604 ok(color == 0x000000ff,
7605 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7607 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7608 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7610 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7611 D3DPOOL_MANAGED, &buffer, NULL);
7612 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7613 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7614 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7615 memcpy(data, quad, sizeof(quad));
7616 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7617 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7618 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7619 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7621 hr = IDirect3DDevice9_BeginScene(device);
7622 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7623 if(SUCCEEDED(hr)) {
7624 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7625 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7626 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7627 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7628 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7629 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7630 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7631 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7633 hr = IDirect3DDevice9_EndScene(device);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7637 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7638 color = getPixelColor(device, 480, 360);
7639 ok(color == 0x00ff0000,
7640 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7641 color = getPixelColor(device, 160, 120);
7642 ok(color == 0x00000000,
7643 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7644 color = getPixelColor(device, 160, 360);
7645 ok(color == 0x0000ff00,
7646 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7647 color = getPixelColor(device, 480, 120);
7648 ok(color == 0x000000ff,
7649 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7651 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7652 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7653 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7654 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7655 IDirect3DDevice9_SetVertexShader(device, NULL);
7656 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7658 IDirect3DVertexDeclaration9_Release(vdecl);
7659 IDirect3DVertexShader9_Release(shader);
7660 IDirect3DVertexBuffer9_Release(buffer);
7663 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7665 D3DCAPS9 caps;
7666 IDirect3DTexture9 *texture;
7667 HRESULT hr;
7668 D3DLOCKED_RECT rect;
7669 unsigned int x, y;
7670 DWORD *dst, color;
7671 const float quad[] = {
7672 -1.0, -1.0, 0.1, -0.2, -0.2,
7673 1.0, -1.0, 0.1, 1.2, -0.2,
7674 -1.0, 1.0, 0.1, -0.2, 1.2,
7675 1.0, 1.0, 0.1, 1.2, 1.2
7677 memset(&caps, 0, sizeof(caps));
7679 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7680 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7681 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7682 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7683 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7684 "Card has conditional NP2 support without power of two restriction set\n");
7685 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7686 return;
7687 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7688 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7689 return;
7692 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7693 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7695 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7696 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7698 memset(&rect, 0, sizeof(rect));
7699 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7700 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7701 for(y = 0; y < 10; y++) {
7702 for(x = 0; x < 10; x++) {
7703 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7704 if(x == 0 || x == 9 || y == 0 || y == 9) {
7705 *dst = 0x00ff0000;
7706 } else {
7707 *dst = 0x000000ff;
7711 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7712 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7714 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7715 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7716 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7717 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7718 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7719 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7720 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7721 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7723 hr = IDirect3DDevice9_BeginScene(device);
7724 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7725 if(SUCCEEDED(hr)) {
7726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7727 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7729 hr = IDirect3DDevice9_EndScene(device);
7730 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7733 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7735 color = getPixelColor(device, 1, 1);
7736 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7737 color = getPixelColor(device, 639, 479);
7738 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7740 color = getPixelColor(device, 135, 101);
7741 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7742 color = getPixelColor(device, 140, 101);
7743 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7744 color = getPixelColor(device, 135, 105);
7745 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7746 color = getPixelColor(device, 140, 105);
7747 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7749 color = getPixelColor(device, 135, 376);
7750 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7751 color = getPixelColor(device, 140, 376);
7752 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7753 color = getPixelColor(device, 135, 379);
7754 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7755 color = getPixelColor(device, 140, 379);
7756 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7758 color = getPixelColor(device, 500, 101);
7759 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7760 color = getPixelColor(device, 504, 101);
7761 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7762 color = getPixelColor(device, 500, 105);
7763 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7764 color = getPixelColor(device, 504, 105);
7765 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7767 color = getPixelColor(device, 500, 376);
7768 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7769 color = getPixelColor(device, 504, 376);
7770 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7771 color = getPixelColor(device, 500, 380);
7772 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7773 color = getPixelColor(device, 504, 380);
7774 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7776 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7777 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7778 IDirect3DTexture9_Release(texture);
7781 static void vFace_register_test(IDirect3DDevice9 *device)
7783 HRESULT hr;
7784 DWORD color;
7785 const DWORD shader_code[] = {
7786 0xffff0300, /* ps_3_0 */
7787 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7788 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7789 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7790 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7791 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7792 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7793 0x0000ffff /* END */
7795 IDirect3DPixelShader9 *shader;
7796 IDirect3DTexture9 *texture;
7797 IDirect3DSurface9 *surface, *backbuffer;
7798 const float quad[] = {
7799 -1.0, -1.0, 0.1,
7800 1.0, -1.0, 0.1,
7801 -1.0, 0.0, 0.1,
7803 1.0, -1.0, 0.1,
7804 1.0, 0.0, 0.1,
7805 -1.0, 0.0, 0.1,
7807 -1.0, 0.0, 0.1,
7808 -1.0, 1.0, 0.1,
7809 1.0, 0.0, 0.1,
7811 1.0, 0.0, 0.1,
7812 -1.0, 1.0, 0.1,
7813 1.0, 1.0, 0.1,
7815 const float blit[] = {
7816 0.0, -1.0, 0.1, 0.0, 0.0,
7817 1.0, -1.0, 0.1, 1.0, 0.0,
7818 0.0, 1.0, 0.1, 0.0, 1.0,
7819 1.0, 1.0, 0.1, 1.0, 1.0,
7822 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7823 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7824 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7825 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7826 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7827 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7828 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7829 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7830 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7831 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7832 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7833 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7836 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7838 hr = IDirect3DDevice9_BeginScene(device);
7839 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7840 if(SUCCEEDED(hr)) {
7841 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7842 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7843 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7844 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7845 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7847 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7848 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7849 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7850 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7851 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7853 /* Blit the texture onto the back buffer to make it visible */
7854 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7855 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7856 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7857 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7858 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7859 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7860 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7861 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7862 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7863 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7865 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7866 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7868 hr = IDirect3DDevice9_EndScene(device);
7869 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7872 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7873 color = getPixelColor(device, 160, 360);
7874 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7875 color = getPixelColor(device, 160, 120);
7876 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7877 color = getPixelColor(device, 480, 360);
7878 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7879 color = getPixelColor(device, 480, 120);
7880 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7882 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7883 IDirect3DDevice9_SetTexture(device, 0, NULL);
7884 IDirect3DPixelShader9_Release(shader);
7885 IDirect3DSurface9_Release(surface);
7886 IDirect3DSurface9_Release(backbuffer);
7887 IDirect3DTexture9_Release(texture);
7890 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7892 HRESULT hr;
7893 DWORD color;
7894 int i;
7895 D3DCAPS9 caps;
7896 BOOL L6V5U5_supported = FALSE;
7897 IDirect3DTexture9 *tex1, *tex2;
7898 D3DLOCKED_RECT locked_rect;
7900 static const float quad[][7] = {
7901 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7902 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7903 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7904 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7907 static const D3DVERTEXELEMENT9 decl_elements[] = {
7908 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7909 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7910 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7911 D3DDECL_END()
7914 /* use asymmetric matrix to test loading */
7915 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7916 float scale, offset;
7918 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7919 IDirect3DTexture9 *texture = NULL;
7921 memset(&caps, 0, sizeof(caps));
7922 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7923 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7924 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7925 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7926 return;
7927 } else {
7928 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7929 * They report that it is not supported, but after that bump mapping works properly. So just test
7930 * if the format is generally supported, and check the BUMPENVMAP flag
7932 IDirect3D9 *d3d9;
7934 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7935 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7936 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7937 L6V5U5_supported = SUCCEEDED(hr);
7938 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7939 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7940 IDirect3D9_Release(d3d9);
7941 if(FAILED(hr)) {
7942 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7943 return;
7947 /* Generate the textures */
7948 generate_bumpmap_textures(device);
7950 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7951 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7952 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7953 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7954 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7955 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7957 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7959 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7960 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7961 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7962 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7963 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7964 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7966 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7967 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7968 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7969 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7970 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7971 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7973 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7974 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7976 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7977 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7979 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7980 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7983 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7984 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7985 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7986 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7988 hr = IDirect3DDevice9_BeginScene(device);
7989 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7992 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7994 hr = IDirect3DDevice9_EndScene(device);
7995 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7997 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7998 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8000 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8001 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8002 * But since testing the color match is not the purpose of the test don't be too picky
8004 color = getPixelColor(device, 320-32, 240);
8005 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8006 color = getPixelColor(device, 320+32, 240);
8007 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8008 color = getPixelColor(device, 320, 240-32);
8009 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8010 color = getPixelColor(device, 320, 240+32);
8011 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8012 color = getPixelColor(device, 320, 240);
8013 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8014 color = getPixelColor(device, 320+32, 240+32);
8015 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8016 color = getPixelColor(device, 320-32, 240+32);
8017 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8018 color = getPixelColor(device, 320+32, 240-32);
8019 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8020 color = getPixelColor(device, 320-32, 240-32);
8021 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8023 for(i = 0; i < 2; i++) {
8024 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8025 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8026 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8027 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8028 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8029 IDirect3DTexture9_Release(texture); /* To destroy it */
8032 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8033 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8034 goto cleanup;
8036 if(L6V5U5_supported == FALSE) {
8037 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8038 goto cleanup;
8041 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8042 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8043 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8044 * would only make this test more complicated
8046 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8047 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8048 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8049 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8051 memset(&locked_rect, 0, sizeof(locked_rect));
8052 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8053 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8054 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8055 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8056 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8058 memset(&locked_rect, 0, sizeof(locked_rect));
8059 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8060 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8061 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8062 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8063 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8065 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8067 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8070 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8071 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8072 scale = 2.0;
8073 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8074 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8075 offset = 0.1;
8076 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8077 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8079 hr = IDirect3DDevice9_BeginScene(device);
8080 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8081 if(SUCCEEDED(hr)) {
8082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8083 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8084 hr = IDirect3DDevice9_EndScene(device);
8085 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8088 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8089 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8090 color = getPixelColor(device, 320, 240);
8091 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8092 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8093 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8095 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8097 /* Check a result scale factor > 1.0 */
8098 scale = 10;
8099 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8100 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8101 offset = 10;
8102 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8103 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8105 hr = IDirect3DDevice9_BeginScene(device);
8106 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8107 if(SUCCEEDED(hr)) {
8108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8109 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8110 hr = IDirect3DDevice9_EndScene(device);
8111 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8113 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8114 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8115 color = getPixelColor(device, 320, 240);
8116 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8118 /* Check clamping in the scale factor calculation */
8119 scale = 1000;
8120 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8121 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8122 offset = -1;
8123 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8124 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8126 hr = IDirect3DDevice9_BeginScene(device);
8127 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8128 if(SUCCEEDED(hr)) {
8129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8131 hr = IDirect3DDevice9_EndScene(device);
8132 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8134 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8135 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8136 color = getPixelColor(device, 320, 240);
8137 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8139 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8140 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8141 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8142 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8144 IDirect3DTexture9_Release(tex1);
8145 IDirect3DTexture9_Release(tex2);
8147 cleanup:
8148 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8149 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8150 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8151 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8153 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8154 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8155 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8158 static void stencil_cull_test(IDirect3DDevice9 *device) {
8159 HRESULT hr;
8160 IDirect3DSurface9 *depthstencil = NULL;
8161 D3DSURFACE_DESC desc;
8162 float quad1[] = {
8163 -1.0, -1.0, 0.1,
8164 0.0, -1.0, 0.1,
8165 -1.0, 0.0, 0.1,
8166 0.0, 0.0, 0.1,
8168 float quad2[] = {
8169 0.0, -1.0, 0.1,
8170 1.0, -1.0, 0.1,
8171 0.0, 0.0, 0.1,
8172 1.0, 0.0, 0.1,
8174 float quad3[] = {
8175 0.0, 0.0, 0.1,
8176 1.0, 0.0, 0.1,
8177 0.0, 1.0, 0.1,
8178 1.0, 1.0, 0.1,
8180 float quad4[] = {
8181 -1.0, 0.0, 0.1,
8182 0.0, 0.0, 0.1,
8183 -1.0, 1.0, 0.1,
8184 0.0, 1.0, 0.1,
8186 struct vertex painter[] = {
8187 {-1.0, -1.0, 0.0, 0x00000000},
8188 { 1.0, -1.0, 0.0, 0x00000000},
8189 {-1.0, 1.0, 0.0, 0x00000000},
8190 { 1.0, 1.0, 0.0, 0x00000000},
8192 WORD indices_cw[] = {0, 1, 3};
8193 WORD indices_ccw[] = {0, 2, 3};
8194 unsigned int i;
8195 DWORD color;
8197 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8198 if(depthstencil == NULL) {
8199 skip("No depth stencil buffer\n");
8200 return;
8202 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8203 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8204 IDirect3DSurface9_Release(depthstencil);
8205 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8206 skip("No 4 or 8 bit stencil surface\n");
8207 return;
8210 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8211 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8212 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8215 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8217 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8219 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8221 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8224 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8226 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8228 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8231 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8232 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8233 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8235 /* First pass: Fill the stencil buffer with some values... */
8236 hr = IDirect3DDevice9_BeginScene(device);
8237 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8238 if(SUCCEEDED(hr))
8240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8242 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8243 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8244 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8245 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8246 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8247 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8249 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8250 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8252 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8253 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8254 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8255 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8256 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8257 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8258 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8263 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8264 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8265 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8266 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8267 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8271 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8272 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8273 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8274 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8275 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8276 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8278 hr = IDirect3DDevice9_EndScene(device);
8279 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8282 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8286 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8288 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8290 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8296 /* 2nd pass: Make the stencil values visible */
8297 hr = IDirect3DDevice9_BeginScene(device);
8298 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8299 if(SUCCEEDED(hr))
8301 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8302 for(i = 0; i < 16; i++) {
8303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8306 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8307 painter[1].diffuse = (i * 16);
8308 painter[2].diffuse = (i * 16);
8309 painter[3].diffuse = (i * 16);
8310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8311 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8313 hr = IDirect3DDevice9_EndScene(device);
8314 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8317 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8318 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8323 color = getPixelColor(device, 160, 420);
8324 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8325 color = getPixelColor(device, 160, 300);
8326 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8328 color = getPixelColor(device, 480, 420);
8329 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8330 color = getPixelColor(device, 480, 300);
8331 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8333 color = getPixelColor(device, 160, 180);
8334 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8335 color = getPixelColor(device, 160, 60);
8336 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8338 color = getPixelColor(device, 480, 180);
8339 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8340 color = getPixelColor(device, 480, 60);
8341 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8344 static void vpos_register_test(IDirect3DDevice9 *device)
8346 HRESULT hr;
8347 DWORD color;
8348 const DWORD shader_code[] = {
8349 0xffff0300, /* ps_3_0 */
8350 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8351 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8352 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8353 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8354 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8355 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8356 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8357 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8358 0x0000ffff /* end */
8360 const DWORD shader_frac_code[] = {
8361 0xffff0300, /* ps_3_0 */
8362 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8363 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8364 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8365 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8366 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8367 0x0000ffff /* end */
8369 IDirect3DPixelShader9 *shader, *shader_frac;
8370 IDirect3DSurface9 *surface = NULL, *backbuffer;
8371 const float quad[] = {
8372 -1.0, -1.0, 0.1, 0.0, 0.0,
8373 1.0, -1.0, 0.1, 1.0, 0.0,
8374 -1.0, 1.0, 0.1, 0.0, 1.0,
8375 1.0, 1.0, 0.1, 1.0, 1.0,
8377 D3DLOCKED_RECT lr;
8378 float constant[4] = {1.0, 0.0, 320, 240};
8379 DWORD *pos;
8381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8383 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8384 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8385 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8386 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8387 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8388 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8390 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8391 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8392 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8394 hr = IDirect3DDevice9_BeginScene(device);
8395 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8396 if(SUCCEEDED(hr)) {
8397 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8398 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8400 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8401 hr = IDirect3DDevice9_EndScene(device);
8402 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8405 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8406 /* This has to be pixel exact */
8407 color = getPixelColor(device, 319, 239);
8408 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8409 color = getPixelColor(device, 320, 239);
8410 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8411 color = getPixelColor(device, 319, 240);
8412 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8413 color = getPixelColor(device, 320, 240);
8414 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8416 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8417 &surface, NULL);
8418 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8419 hr = IDirect3DDevice9_BeginScene(device);
8420 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8421 if(SUCCEEDED(hr)) {
8422 constant[2] = 16; constant[3] = 16;
8423 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8424 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8425 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8428 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8429 hr = IDirect3DDevice9_EndScene(device);
8430 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8432 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8433 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8435 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8436 color = *pos & 0x00ffffff;
8437 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8438 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8439 color = *pos & 0x00ffffff;
8440 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8441 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8442 color = *pos & 0x00ffffff;
8443 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8444 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8445 color = *pos & 0x00ffffff;
8446 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8448 hr = IDirect3DSurface9_UnlockRect(surface);
8449 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8451 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8452 * have full control over the multisampling setting inside this test
8454 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8455 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8456 hr = IDirect3DDevice9_BeginScene(device);
8457 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8458 if(SUCCEEDED(hr)) {
8459 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8462 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463 hr = IDirect3DDevice9_EndScene(device);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8466 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8469 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8470 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8472 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8473 color = *pos & 0x00ffffff;
8474 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8476 hr = IDirect3DSurface9_UnlockRect(surface);
8477 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8479 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8480 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8481 IDirect3DPixelShader9_Release(shader);
8482 IDirect3DPixelShader9_Release(shader_frac);
8483 if(surface) IDirect3DSurface9_Release(surface);
8484 IDirect3DSurface9_Release(backbuffer);
8487 static void pointsize_test(IDirect3DDevice9 *device)
8489 HRESULT hr;
8490 D3DCAPS9 caps;
8491 D3DMATRIX matrix;
8492 D3DMATRIX identity;
8493 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8494 DWORD color;
8495 IDirect3DTexture9 *tex1, *tex2;
8496 D3DLOCKED_RECT lr;
8497 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8498 0x00000000, 0x00000000};
8499 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8500 0x00000000, 0x0000ff00};
8502 const float vertices[] = {
8503 64, 64, 0.1,
8504 128, 64, 0.1,
8505 192, 64, 0.1,
8506 256, 64, 0.1,
8507 320, 64, 0.1,
8508 384, 64, 0.1,
8509 448, 64, 0.1,
8510 512, 64, 0.1,
8511 576, 64, 0.1,
8514 /* 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 */
8515 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;
8516 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;
8517 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;
8518 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;
8520 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;
8521 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;
8522 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;
8523 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;
8525 memset(&caps, 0, sizeof(caps));
8526 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8527 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8528 if(caps.MaxPointSize < 32.0) {
8529 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8530 return;
8533 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8534 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8535 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8536 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8537 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8538 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8539 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8540 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8542 hr = IDirect3DDevice9_BeginScene(device);
8543 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8544 if(SUCCEEDED(hr)) {
8545 ptsize = 16.0;
8546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8548 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8551 ptsize = 32.0;
8552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8553 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8555 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8557 ptsize = 31.5;
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8561 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8563 if(caps.MaxPointSize >= 64.0) {
8564 ptsize = 64.0;
8565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8566 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8568 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8570 ptsize = 63.75;
8571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8572 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8574 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8577 ptsize = 1.0;
8578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8579 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8581 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8583 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8584 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8585 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8586 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8588 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8589 ptsize = 16.0;
8590 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8591 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8592 ptsize = 1.0;
8593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8596 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8598 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8599 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8601 ptsize = 4.0;
8602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8603 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8604 ptsize = 16.0;
8605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8606 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8607 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8608 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8611 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8613 /* pointsize < pointsize_min < pointsize_max?
8614 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
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 ptsize = 16.0;
8620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8621 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8623 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8628 hr = IDirect3DDevice9_EndScene(device);
8629 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8631 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8632 color = getPixelColor(device, 64-9, 64-9);
8633 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8634 color = getPixelColor(device, 64-8, 64-8);
8635 ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8636 color = getPixelColor(device, 64-7, 64-7);
8637 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8638 color = getPixelColor(device, 64+7, 64+7);
8639 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8640 color = getPixelColor(device, 64+8, 64+8);
8641 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8642 color = getPixelColor(device, 64+9, 64+9);
8643 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8645 color = getPixelColor(device, 128-17, 64-17);
8646 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8647 color = getPixelColor(device, 128-16, 64-16);
8648 ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8649 color = getPixelColor(device, 128-15, 64-15);
8650 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8651 color = getPixelColor(device, 128+15, 64+15);
8652 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8653 color = getPixelColor(device, 128+16, 64+16);
8654 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8655 color = getPixelColor(device, 128+17, 64+17);
8656 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8658 color = getPixelColor(device, 192-17, 64-17);
8659 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8660 color = getPixelColor(device, 192-16, 64-16);
8661 todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8662 color = getPixelColor(device, 192-15, 64-15);
8663 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8664 color = getPixelColor(device, 192+15, 64+15);
8665 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8666 color = getPixelColor(device, 192+16, 64+16);
8667 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8668 color = getPixelColor(device, 192+17, 64+17);
8669 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8671 if(caps.MaxPointSize >= 64.0) {
8672 color = getPixelColor(device, 256-33, 64-33);
8673 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8674 color = getPixelColor(device, 256-32, 64-32);
8675 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8676 color = getPixelColor(device, 256-31, 64-31);
8677 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8678 color = getPixelColor(device, 256+31, 64+31);
8679 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8680 color = getPixelColor(device, 256+32, 64+32);
8681 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8682 color = getPixelColor(device, 256+33, 64+33);
8683 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8685 color = getPixelColor(device, 384-33, 64-33);
8686 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8687 color = getPixelColor(device, 384-32, 64-32);
8688 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8689 color = getPixelColor(device, 384-31, 64-31);
8690 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8691 color = getPixelColor(device, 384+31, 64+31);
8692 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8693 color = getPixelColor(device, 384+32, 64+32);
8694 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8695 color = getPixelColor(device, 384+33, 64+33);
8696 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8699 color = getPixelColor(device, 320-1, 64-1);
8700 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8701 color = getPixelColor(device, 320-0, 64-0);
8702 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8703 color = getPixelColor(device, 320+1, 64+1);
8704 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8706 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8707 color = getPixelColor(device, 448-4, 64-4);
8708 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8709 color = getPixelColor(device, 448+4, 64+4);
8710 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8712 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8713 color = getPixelColor(device, 512-4, 64-4);
8714 ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8715 color = getPixelColor(device, 512+4, 64+4);
8716 ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8718 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8719 * Don't be overly picky - just show that the point is bigger than 1 pixel
8721 color = getPixelColor(device, 576-4, 64-4);
8722 ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8723 color = getPixelColor(device, 576+4, 64+4);
8724 ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8726 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8727 * generates texture coordinates for the point(result: Yes, it does)
8729 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8730 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8731 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8733 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8734 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8736 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8737 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8738 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8739 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8740 memset(&lr, 0, sizeof(lr));
8741 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8742 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8743 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8744 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8745 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8746 memset(&lr, 0, sizeof(lr));
8747 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8748 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8749 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8750 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8751 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8752 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8753 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8754 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8755 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8756 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8757 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8758 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8759 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8760 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8761 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8762 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8763 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8764 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8765 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8767 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8768 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8769 ptsize = 32.0;
8770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8771 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8773 hr = IDirect3DDevice9_BeginScene(device);
8774 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8775 if(SUCCEEDED(hr))
8777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8778 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8779 hr = IDirect3DDevice9_EndScene(device);
8780 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8783 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8784 color = getPixelColor(device, 64-4, 64-4);
8785 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8786 color = getPixelColor(device, 64-4, 64+4);
8787 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8788 color = getPixelColor(device, 64+4, 64+4);
8789 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8790 color = getPixelColor(device, 64+4, 64-4);
8791 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8793 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8794 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8795 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8796 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8797 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8798 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8799 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8800 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8801 IDirect3DTexture9_Release(tex1);
8802 IDirect3DTexture9_Release(tex2);
8804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8805 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8807 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8808 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8809 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8812 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8814 HRESULT hr;
8815 IDirect3DPixelShader9 *ps;
8816 IDirect3DTexture9 *tex1, *tex2;
8817 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8818 D3DCAPS9 caps;
8819 DWORD color;
8820 DWORD shader_code[] = {
8821 0xffff0300, /* ps_3_0 */
8822 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8823 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8824 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8825 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8826 0x0000ffff /* END */
8828 float quad[] = {
8829 -1.0, -1.0, 0.1,
8830 1.0, -1.0, 0.1,
8831 -1.0, 1.0, 0.1,
8832 1.0, 1.0, 0.1,
8834 float texquad[] = {
8835 -1.0, -1.0, 0.1, 0.0, 0.0,
8836 0.0, -1.0, 0.1, 1.0, 0.0,
8837 -1.0, 1.0, 0.1, 0.0, 1.0,
8838 0.0, 1.0, 0.1, 1.0, 1.0,
8840 0.0, -1.0, 0.1, 0.0, 0.0,
8841 1.0, -1.0, 0.1, 1.0, 0.0,
8842 0.0, 1.0, 0.1, 0.0, 1.0,
8843 1.0, 1.0, 0.1, 1.0, 1.0,
8846 memset(&caps, 0, sizeof(caps));
8847 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8848 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8849 if(caps.NumSimultaneousRTs < 2) {
8850 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8851 return;
8854 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8855 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8857 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8858 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8859 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8860 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8861 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8862 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8864 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8865 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8866 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8867 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8868 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8869 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8871 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8872 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8873 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8874 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8875 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8876 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8877 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8878 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8880 hr = IDirect3DDevice9_BeginScene(device);
8881 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8882 if(SUCCEEDED(hr)) {
8883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8884 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8886 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8887 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8888 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8890 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8892 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8893 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8895 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8896 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8898 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8900 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8901 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8903 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8905 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8906 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8908 hr = IDirect3DDevice9_EndScene(device);
8909 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8912 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8913 color = getPixelColor(device, 160, 240);
8914 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8915 color = getPixelColor(device, 480, 240);
8916 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8918 IDirect3DPixelShader9_Release(ps);
8919 IDirect3DTexture9_Release(tex1);
8920 IDirect3DTexture9_Release(tex2);
8921 IDirect3DSurface9_Release(surf1);
8922 IDirect3DSurface9_Release(surf2);
8923 IDirect3DSurface9_Release(backbuf);
8926 struct formats {
8927 const char *fmtName;
8928 D3DFORMAT textureFormat;
8929 DWORD resultColorBlending;
8930 DWORD resultColorNoBlending;
8933 const struct formats test_formats[] = {
8934 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8935 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8936 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8937 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8938 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8939 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8940 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8941 { NULL, 0 }
8944 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8946 HRESULT hr;
8947 IDirect3DTexture9 *offscreenTexture = NULL;
8948 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8949 IDirect3D9 *d3d = NULL;
8950 DWORD color;
8951 DWORD r0, g0, b0, r1, g1, b1;
8952 int fmt_index;
8954 static const float quad[][5] = {
8955 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8956 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8957 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8958 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8961 /* Quad with R=0x10, G=0x20 */
8962 static const struct vertex quad1[] = {
8963 {-1.0f, -1.0f, 0.1f, 0x80102000},
8964 {-1.0f, 1.0f, 0.1f, 0x80102000},
8965 { 1.0f, -1.0f, 0.1f, 0x80102000},
8966 { 1.0f, 1.0f, 0.1f, 0x80102000},
8969 /* Quad with R=0x20, G=0x10 */
8970 static const struct vertex quad2[] = {
8971 {-1.0f, -1.0f, 0.1f, 0x80201000},
8972 {-1.0f, 1.0f, 0.1f, 0x80201000},
8973 { 1.0f, -1.0f, 0.1f, 0x80201000},
8974 { 1.0f, 1.0f, 0.1f, 0x80201000},
8977 IDirect3DDevice9_GetDirect3D(device, &d3d);
8979 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8980 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8981 if(!backbuffer) {
8982 goto out;
8985 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8987 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8988 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8989 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8990 continue;
8993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8994 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8996 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8997 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8998 if(!offscreenTexture) {
8999 continue;
9002 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9003 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9004 if(!offscreen) {
9005 continue;
9008 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9009 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9011 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9012 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9013 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9014 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9015 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9016 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9017 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9018 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9020 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9022 /* Below we will draw two quads with different colors and try to blend them together.
9023 * The result color is compared with the expected outcome.
9025 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9026 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9027 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9029 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9034 /* Draw a quad using color 0x0010200 */
9035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9036 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9038 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9040 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9042 /* Draw a quad using color 0x0020100 */
9043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9048 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9050 /* We don't want to blend the result on the backbuffer */
9051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9052 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9054 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9055 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9056 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9057 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9058 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9060 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9061 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9063 /* This time with the texture */
9064 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9065 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9067 IDirect3DDevice9_EndScene(device);
9069 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9072 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9073 /* Compare the color of the center quad with our expectation */
9074 color = getPixelColor(device, 320, 240);
9075 r0 = (color & 0x00ff0000) >> 16;
9076 g0 = (color & 0x0000ff00) >> 8;
9077 b0 = (color & 0x000000ff) >> 0;
9079 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9080 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9081 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9083 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9084 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9085 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9086 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9087 } else {
9088 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9089 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9090 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9091 color = getPixelColor(device, 320, 240);
9092 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);
9095 IDirect3DDevice9_SetTexture(device, 0, NULL);
9096 if(offscreenTexture) {
9097 IDirect3DTexture9_Release(offscreenTexture);
9099 if(offscreen) {
9100 IDirect3DSurface9_Release(offscreen);
9104 out:
9105 /* restore things */
9106 if(backbuffer) {
9107 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9108 IDirect3DSurface9_Release(backbuffer);
9112 static void tssargtemp_test(IDirect3DDevice9 *device)
9114 HRESULT hr;
9115 DWORD color;
9116 static const struct vertex quad[] = {
9117 {-1.0, -1.0, 0.1, 0x00ff0000},
9118 { 1.0, -1.0, 0.1, 0x00ff0000},
9119 {-1.0, 1.0, 0.1, 0x00ff0000},
9120 { 1.0, 1.0, 0.1, 0x00ff0000}
9122 D3DCAPS9 caps;
9124 memset(&caps, 0, sizeof(caps));
9125 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9126 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9127 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9128 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9129 return;
9132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9133 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9135 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9136 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9137 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9138 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9140 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9141 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9142 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9143 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9144 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9145 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9147 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9148 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9149 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9150 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9151 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9152 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9154 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9155 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9158 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9159 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9160 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9162 hr = IDirect3DDevice9_BeginScene(device);
9163 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9164 if(SUCCEEDED(hr)) {
9165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9166 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9167 hr = IDirect3DDevice9_EndScene(device);
9168 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9170 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9171 color = getPixelColor(device, 320, 240);
9172 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9174 /* Set stage 1 back to default */
9175 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9176 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9178 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9179 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9180 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9181 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9182 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9183 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9184 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9187 struct testdata
9189 DWORD idxVertex; /* number of instances in the first stream */
9190 DWORD idxColor; /* number of instances in the second stream */
9191 DWORD idxInstance; /* should be 1 ?? */
9192 DWORD color1; /* color 1 instance */
9193 DWORD color2; /* color 2 instance */
9194 DWORD color3; /* color 3 instance */
9195 DWORD color4; /* color 4 instance */
9196 WORD strVertex; /* specify which stream to use 0-2*/
9197 WORD strColor;
9198 WORD strInstance;
9201 static const struct testdata testcases[]=
9203 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9204 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9205 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9206 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9207 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9208 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9209 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9210 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9211 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9212 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9213 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9214 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9215 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9216 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9217 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9219 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9220 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9224 /* Drawing Indexed Geometry with instances*/
9225 static void stream_test(IDirect3DDevice9 *device)
9227 IDirect3DVertexBuffer9 *vb = NULL;
9228 IDirect3DVertexBuffer9 *vb2 = NULL;
9229 IDirect3DVertexBuffer9 *vb3 = NULL;
9230 IDirect3DIndexBuffer9 *ib = NULL;
9231 IDirect3DVertexDeclaration9 *pDecl = NULL;
9232 IDirect3DVertexShader9 *shader = NULL;
9233 HRESULT hr;
9234 BYTE *data;
9235 DWORD color;
9236 DWORD ind;
9237 unsigned i;
9239 const DWORD shader_code[] =
9241 0xfffe0101, /* vs_1_1 */
9242 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9243 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9244 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9245 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9246 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9247 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9248 0x0000ffff
9251 const float quad[][3] =
9253 {-0.5f, -0.5f, 1.1f}, /*0 */
9254 {-0.5f, 0.5f, 1.1f}, /*1 */
9255 { 0.5f, -0.5f, 1.1f}, /*2 */
9256 { 0.5f, 0.5f, 1.1f}, /*3 */
9259 const float vertcolor[][4] =
9261 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9262 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9263 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9264 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9267 /* 4 position for 4 instances */
9268 const float instancepos[][3] =
9270 {-0.6f,-0.6f, 0.0f},
9271 { 0.6f,-0.6f, 0.0f},
9272 { 0.6f, 0.6f, 0.0f},
9273 {-0.6f, 0.6f, 0.0f},
9276 short indices[] = {0, 1, 2, 1, 2, 3};
9278 D3DVERTEXELEMENT9 decl[] =
9280 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9281 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9282 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9283 D3DDECL_END()
9286 /* set the default value because it isn't done in wine? */
9287 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9288 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9290 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9291 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9292 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9294 /* check wrong cases */
9295 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9296 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9297 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9298 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9299 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9300 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9301 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9302 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9303 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9304 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9305 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9306 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9307 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9308 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9309 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9310 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9311 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9312 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9313 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9314 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9316 /* set the default value back */
9317 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9318 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9320 /* create all VertexBuffers*/
9321 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9322 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9323 if(!vb) {
9324 skip("Failed to create a vertex buffer\n");
9325 return;
9327 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9328 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9329 if(!vb2) {
9330 skip("Failed to create a vertex buffer\n");
9331 goto out;
9333 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9334 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9335 if(!vb3) {
9336 skip("Failed to create a vertex buffer\n");
9337 goto out;
9340 /* create IndexBuffer*/
9341 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9343 if(!ib) {
9344 skip("Failed to create a index buffer\n");
9345 goto out;
9348 /* copy all Buffers (Vertex + Index)*/
9349 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9350 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9351 memcpy(data, quad, sizeof(quad));
9352 hr = IDirect3DVertexBuffer9_Unlock(vb);
9353 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9354 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9355 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9356 memcpy(data, vertcolor, sizeof(vertcolor));
9357 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9358 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9359 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9360 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9361 memcpy(data, instancepos, sizeof(instancepos));
9362 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9363 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9364 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9365 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9366 memcpy(data, indices, sizeof(indices));
9367 hr = IDirect3DIndexBuffer9_Unlock(ib);
9368 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9370 /* create VertexShader */
9371 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9372 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9373 if(!shader) {
9374 skip("Failed to create a vetex shader\n");
9375 goto out;
9378 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9379 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9381 hr = IDirect3DDevice9_SetIndices(device, ib);
9382 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9384 /* run all tests */
9385 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9387 struct testdata act = testcases[i];
9388 decl[0].Stream = act.strVertex;
9389 decl[1].Stream = act.strColor;
9390 decl[2].Stream = act.strInstance;
9391 /* create VertexDeclarations */
9392 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9393 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9395 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9396 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9398 hr = IDirect3DDevice9_BeginScene(device);
9399 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9400 if(SUCCEEDED(hr))
9402 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9403 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9405 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9406 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9407 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9408 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9410 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9411 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9412 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9413 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9415 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9416 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9417 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9418 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9420 /* don't know if this is right (1*3 and 4*1)*/
9421 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9422 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9423 hr = IDirect3DDevice9_EndScene(device);
9424 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9426 /* set all StreamSource && StreamSourceFreq back to default */
9427 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9428 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9429 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9430 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9431 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9432 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9433 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9434 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9435 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9436 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9437 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9438 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9442 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9444 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9445 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9447 color = getPixelColor(device, 160, 360);
9448 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9449 color = getPixelColor(device, 480, 360);
9450 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9451 color = getPixelColor(device, 480, 120);
9452 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9453 color = getPixelColor(device, 160, 120);
9454 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9457 hr = IDirect3DDevice9_SetIndices(device, NULL);
9458 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9460 out:
9461 if(vb) IDirect3DVertexBuffer9_Release(vb);
9462 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9463 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9464 if(ib)IDirect3DIndexBuffer9_Release(ib);
9465 if(shader)IDirect3DVertexShader9_Release(shader);
9468 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9469 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9470 IDirect3DTexture9 *dsttex = NULL;
9471 HRESULT hr;
9472 DWORD color;
9473 D3DRECT r1 = {0, 0, 50, 50 };
9474 D3DRECT r2 = {50, 0, 100, 50 };
9475 D3DRECT r3 = {50, 50, 100, 100};
9476 D3DRECT r4 = {0, 50, 50, 100};
9477 const float quad[] = {
9478 -1.0, -1.0, 0.1, 0.0, 0.0,
9479 1.0, -1.0, 0.1, 1.0, 0.0,
9480 -1.0, 1.0, 0.1, 0.0, 1.0,
9481 1.0, 1.0, 0.1, 1.0, 1.0,
9484 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9485 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9487 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9488 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9489 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9490 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9492 if(!src || !dsttex) {
9493 skip("One or more test resources could not be created\n");
9494 goto cleanup;
9497 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9498 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9500 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9501 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9503 /* Clear the StretchRect destination for debugging */
9504 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9505 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9506 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9507 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9509 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9510 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9512 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9513 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9514 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9515 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9516 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9517 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9518 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9519 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9521 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9522 * the target -> texture GL blit path
9524 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9525 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9526 IDirect3DSurface9_Release(dst);
9528 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9531 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9532 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9533 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9534 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9535 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9536 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9537 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9538 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9540 hr = IDirect3DDevice9_BeginScene(device);
9541 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9542 if(SUCCEEDED(hr)) {
9543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9544 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9545 hr = IDirect3DDevice9_EndScene(device);
9546 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9549 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9550 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9551 color = getPixelColor(device, 160, 360);
9552 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9553 color = getPixelColor(device, 480, 360);
9554 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9555 color = getPixelColor(device, 480, 120);
9556 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9557 color = getPixelColor(device, 160, 120);
9558 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9560 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9561 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9562 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9563 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9565 cleanup:
9566 if(src) IDirect3DSurface9_Release(src);
9567 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9568 if(dsttex) IDirect3DTexture9_Release(dsttex);
9571 static void texop_test(IDirect3DDevice9 *device)
9573 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9574 IDirect3DTexture9 *texture = NULL;
9575 D3DLOCKED_RECT locked_rect;
9576 D3DCOLOR color;
9577 D3DCAPS9 caps;
9578 HRESULT hr;
9579 unsigned i;
9581 static const struct {
9582 float x, y, z;
9583 float s, t;
9584 D3DCOLOR diffuse;
9585 } quad[] = {
9586 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9587 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9588 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9589 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9592 static const D3DVERTEXELEMENT9 decl_elements[] = {
9593 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9594 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9595 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9596 D3DDECL_END()
9599 static const struct {
9600 D3DTEXTUREOP op;
9601 const char *name;
9602 DWORD caps_flag;
9603 D3DCOLOR result;
9604 } test_data[] = {
9605 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9606 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9607 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9608 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9609 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9610 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9611 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9612 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9613 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9614 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9615 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9616 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9617 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9618 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9619 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9620 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9621 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9622 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9623 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9624 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9625 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9626 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9627 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9630 memset(&caps, 0, sizeof(caps));
9631 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9632 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9634 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9635 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9636 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9637 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9639 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9640 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9641 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9642 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9643 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9644 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9645 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9646 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9647 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9649 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9650 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9651 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9652 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9653 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9654 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9656 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9657 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9660 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9662 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9664 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9666 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9667 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9669 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9671 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9673 skip("tex operation %s not supported\n", test_data[i].name);
9674 continue;
9677 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9678 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9680 hr = IDirect3DDevice9_BeginScene(device);
9681 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9684 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9686 hr = IDirect3DDevice9_EndScene(device);
9687 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9689 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9690 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9692 color = getPixelColor(device, 320, 240);
9693 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9694 test_data[i].name, color, test_data[i].result);
9697 if (texture) IDirect3DTexture9_Release(texture);
9698 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9701 static void yuv_color_test(IDirect3DDevice9 *device) {
9702 HRESULT hr;
9703 IDirect3DSurface9 *surface = NULL, *target = NULL;
9704 unsigned int fmt, i;
9705 D3DFORMAT format;
9706 const char *fmt_string;
9707 D3DLOCKED_RECT lr;
9708 IDirect3D9 *d3d;
9709 HRESULT color;
9710 DWORD ref_color_left, ref_color_right;
9712 struct {
9713 DWORD in; /* The input color */
9714 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9715 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9716 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9717 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9718 } test_data[] = {
9719 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9720 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9721 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9722 * that
9724 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9725 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9726 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9727 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9728 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9729 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9730 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9731 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9732 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9733 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9734 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9735 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9736 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9737 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9739 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9740 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9741 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9742 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9745 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9746 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9747 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9748 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9750 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9751 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9753 for(fmt = 0; fmt < 2; fmt++) {
9754 if(fmt == 0) {
9755 format = D3DFMT_UYVY;
9756 fmt_string = "D3DFMT_UYVY";
9757 } else {
9758 format = D3DFMT_YUY2;
9759 fmt_string = "D3DFMT_YUY2";
9762 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9763 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9765 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9766 D3DRTYPE_SURFACE, format) != D3D_OK) {
9767 skip("%s is not supported\n", fmt_string);
9768 continue;
9771 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9772 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9775 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9776 if(fmt == 0) {
9777 ref_color_left = test_data[i].uyvy_left;
9778 ref_color_right = test_data[i].uyvy_right;
9779 } else {
9780 ref_color_left = test_data[i].yuy2_left;
9781 ref_color_right = test_data[i].yuy2_right;
9784 memset(&lr, 0, sizeof(lr));
9785 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9786 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9787 *((DWORD *) lr.pBits) = test_data[i].in;
9788 hr = IDirect3DSurface9_UnlockRect(surface);
9789 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9791 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9792 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9793 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9794 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9796 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9798 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9799 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9800 * want to add tests for the filtered pixels as well.
9802 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9803 * differently, so we need a max diff of 16
9805 color = getPixelColor(device, 40, 240);
9806 ok(color_match(color, ref_color_left, 18),
9807 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9808 test_data[i].in, color, ref_color_left, fmt_string);
9809 color = getPixelColor(device, 600, 240);
9810 ok(color_match(color, ref_color_right, 18),
9811 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9812 test_data[i].in, color, ref_color_right, fmt_string);
9814 IDirect3DSurface9_Release(surface);
9816 IDirect3DSurface9_Release(target);
9817 IDirect3D9_Release(d3d);
9820 static void texop_range_test(IDirect3DDevice9 *device)
9822 static const struct {
9823 float x, y, z;
9824 D3DCOLOR diffuse;
9825 } quad[] = {
9826 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9827 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9828 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9829 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9831 HRESULT hr;
9832 IDirect3DTexture9 *texture;
9833 D3DLOCKED_RECT locked_rect;
9834 D3DCAPS9 caps;
9835 DWORD color;
9837 /* We need ADD and SUBTRACT operations */
9838 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9839 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9840 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9841 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9842 return;
9844 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9845 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9846 return;
9849 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9850 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9851 /* Stage 1: result = diffuse(=1.0) + diffuse
9852 * stage 2: result = result - tfactor(= 0.5)
9854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9855 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9856 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9857 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9858 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9859 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9860 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9861 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9862 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9863 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9864 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9865 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9866 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9867 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9869 hr = IDirect3DDevice9_BeginScene(device);
9870 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9872 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9873 hr = IDirect3DDevice9_EndScene(device);
9874 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9875 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9876 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9878 color = getPixelColor(device, 320, 240);
9879 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9880 color);
9882 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9883 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9884 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9885 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9886 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9887 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9888 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9889 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9890 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9892 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9893 * stage 2: result = result + diffuse(1.0)
9895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9896 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9898 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9899 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9900 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9901 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9902 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9903 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9904 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9905 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9906 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9907 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9908 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9910 hr = IDirect3DDevice9_BeginScene(device);
9911 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9913 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9914 hr = IDirect3DDevice9_EndScene(device);
9915 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9916 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9917 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9919 color = getPixelColor(device, 320, 240);
9920 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9921 color);
9923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9924 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9925 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9926 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9927 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9928 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9929 IDirect3DTexture9_Release(texture);
9932 static void alphareplicate_test(IDirect3DDevice9 *device) {
9933 struct vertex quad[] = {
9934 { -1.0, -1.0, 0.1, 0x80ff00ff },
9935 { 1.0, -1.0, 0.1, 0x80ff00ff },
9936 { -1.0, 1.0, 0.1, 0x80ff00ff },
9937 { 1.0, 1.0, 0.1, 0x80ff00ff },
9939 HRESULT hr;
9940 DWORD color;
9942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9943 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9946 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9948 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9949 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9950 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9953 hr = IDirect3DDevice9_BeginScene(device);
9954 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9955 if(SUCCEEDED(hr)) {
9956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9957 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9958 hr = IDirect3DDevice9_EndScene(device);
9959 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9965 color = getPixelColor(device, 320, 240);
9966 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9967 color);
9969 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9970 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9974 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9975 HRESULT hr;
9976 D3DCAPS9 caps;
9977 DWORD color;
9978 struct vertex quad[] = {
9979 { -1.0, -1.0, 0.1, 0x408080c0 },
9980 { 1.0, -1.0, 0.1, 0x408080c0 },
9981 { -1.0, 1.0, 0.1, 0x408080c0 },
9982 { 1.0, 1.0, 0.1, 0x408080c0 },
9985 memset(&caps, 0, sizeof(caps));
9986 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9987 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9988 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9989 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9990 return;
9993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9994 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9996 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9997 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9999 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10000 * mov r0.a, diffuse.a
10001 * mov r0, r0.a
10003 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10004 * 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
10005 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10007 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10008 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10009 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10010 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10011 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10012 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10013 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10014 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10015 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10016 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10017 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10018 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10019 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10020 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10021 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10022 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10026 hr = IDirect3DDevice9_BeginScene(device);
10027 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10028 if(SUCCEEDED(hr)) {
10029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10030 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10031 hr = IDirect3DDevice9_EndScene(device);
10032 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10035 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10036 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10038 color = getPixelColor(device, 320, 240);
10039 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10040 color);
10042 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10043 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10045 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10046 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10047 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10050 static void zwriteenable_test(IDirect3DDevice9 *device) {
10051 HRESULT hr;
10052 DWORD color;
10053 struct vertex quad1[] = {
10054 { -1.0, -1.0, 0.1, 0x00ff0000},
10055 { -1.0, 1.0, 0.1, 0x00ff0000},
10056 { 1.0, -1.0, 0.1, 0x00ff0000},
10057 { 1.0, 1.0, 0.1, 0x00ff0000},
10059 struct vertex quad2[] = {
10060 { -1.0, -1.0, 0.9, 0x0000ff00},
10061 { -1.0, 1.0, 0.9, 0x0000ff00},
10062 { 1.0, -1.0, 0.9, 0x0000ff00},
10063 { 1.0, 1.0, 0.9, 0x0000ff00},
10066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10067 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10069 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10070 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10072 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10074 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10078 hr = IDirect3DDevice9_BeginScene(device);
10079 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10080 if(SUCCEEDED(hr)) {
10081 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10082 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10083 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10084 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10085 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10086 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10089 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10091 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10092 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10093 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10095 hr = IDirect3DDevice9_EndScene(device);
10096 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10100 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10101 color = getPixelColor(device, 320, 240);
10102 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10103 color);
10105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10109 static void alphatest_test(IDirect3DDevice9 *device) {
10110 #define ALPHATEST_PASSED 0x0000ff00
10111 #define ALPHATEST_FAILED 0x00ff0000
10112 struct {
10113 D3DCMPFUNC func;
10114 DWORD color_less;
10115 DWORD color_equal;
10116 DWORD color_greater;
10117 } testdata[] = {
10118 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10119 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10120 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10121 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10122 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10123 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10124 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10125 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10127 unsigned int i, j;
10128 HRESULT hr;
10129 DWORD color;
10130 struct vertex quad[] = {
10131 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10132 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10133 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10134 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10136 D3DCAPS9 caps;
10138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10140 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10141 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10143 for(j = 0; j < 2; j++) {
10144 if(j == 1) {
10145 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10146 * the alpha test either for performance reasons(floating point RTs) or to work
10147 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10148 * codepath for ffp and shader in this case, and the test should cover both
10150 IDirect3DPixelShader9 *ps;
10151 DWORD shader_code[] = {
10152 0xffff0101, /* ps_1_1 */
10153 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10154 0x0000ffff /* end */
10156 memset(&caps, 0, sizeof(caps));
10157 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10158 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10159 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10160 break;
10163 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10164 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10165 IDirect3DDevice9_SetPixelShader(device, ps);
10166 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10167 IDirect3DPixelShader9_Release(ps);
10170 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10175 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10177 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10178 hr = IDirect3DDevice9_BeginScene(device);
10179 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10180 if(SUCCEEDED(hr)) {
10181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10182 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10183 hr = IDirect3DDevice9_EndScene(device);
10184 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10186 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10187 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10188 color = getPixelColor(device, 320, 240);
10189 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10190 color, testdata[i].color_less, testdata[i].func);
10192 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10193 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10195 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10196 hr = IDirect3DDevice9_BeginScene(device);
10197 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10198 if(SUCCEEDED(hr)) {
10199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10200 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10201 hr = IDirect3DDevice9_EndScene(device);
10202 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10204 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10205 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10206 color = getPixelColor(device, 320, 240);
10207 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10208 color, testdata[i].color_equal, testdata[i].func);
10210 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10211 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10213 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10214 hr = IDirect3DDevice9_BeginScene(device);
10215 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10216 if(SUCCEEDED(hr)) {
10217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10218 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10219 hr = IDirect3DDevice9_EndScene(device);
10220 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10223 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10224 color = getPixelColor(device, 320, 240);
10225 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10226 color, testdata[i].color_greater, testdata[i].func);
10230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10231 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10232 IDirect3DDevice9_SetPixelShader(device, NULL);
10233 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10236 static void sincos_test(IDirect3DDevice9 *device) {
10237 const DWORD sin_shader_code[] = {
10238 0xfffe0200, /* vs_2_0 */
10239 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10240 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10241 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10242 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10243 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10244 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10245 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10246 0x0000ffff /* end */
10248 const DWORD cos_shader_code[] = {
10249 0xfffe0200, /* vs_2_0 */
10250 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10251 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10252 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10253 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10254 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10255 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10256 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10257 0x0000ffff /* end */
10259 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10260 HRESULT hr;
10261 struct {
10262 float x, y, z;
10263 } data[1280];
10264 unsigned int i;
10265 float sincosc1[4] = {D3DSINCOSCONST1};
10266 float sincosc2[4] = {D3DSINCOSCONST2};
10268 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10269 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10271 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10272 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10273 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10274 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10275 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10276 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10277 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10278 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10279 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10280 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10282 /* Generate a point from -1 to 1 every 0.5 pixels */
10283 for(i = 0; i < 1280; i++) {
10284 data[i].x = (-640.0 + i) / 640.0;
10285 data[i].y = 0.0;
10286 data[i].z = 0.1;
10289 hr = IDirect3DDevice9_BeginScene(device);
10290 if(SUCCEEDED(hr)) {
10291 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10292 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10294 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10296 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10297 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10299 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10301 hr = IDirect3DDevice9_EndScene(device);
10302 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10304 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10305 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10306 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10308 IDirect3DDevice9_SetVertexShader(device, NULL);
10309 IDirect3DVertexShader9_Release(sin_shader);
10310 IDirect3DVertexShader9_Release(cos_shader);
10313 static void loop_index_test(IDirect3DDevice9 *device) {
10314 const DWORD shader_code[] = {
10315 0xfffe0200, /* vs_2_0 */
10316 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10317 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10318 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10319 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10320 0x0000001d, /* endloop */
10321 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10322 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10323 0x0000ffff /* END */
10325 IDirect3DVertexShader9 *shader;
10326 HRESULT hr;
10327 DWORD color;
10328 const float quad[] = {
10329 -1.0, -1.0, 0.1,
10330 1.0, -1.0, 0.1,
10331 -1.0, 1.0, 0.1,
10332 1.0, 1.0, 0.1
10334 const float zero[4] = {0, 0, 0, 0};
10335 const float one[4] = {1, 1, 1, 1};
10336 int i0[4] = {2, 10, -3, 0};
10337 float values[4];
10339 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10340 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10341 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10343 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10344 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10345 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10346 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10348 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10349 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10350 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10351 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10352 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10353 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10354 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10355 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10356 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10357 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10358 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10359 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10360 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10361 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10362 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10363 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10364 values[0] = 1.0;
10365 values[1] = 1.0;
10366 values[2] = 0.0;
10367 values[3] = 0.0;
10368 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10369 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10370 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10371 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10372 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10373 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10374 values[0] = -1.0;
10375 values[1] = 0.0;
10376 values[2] = 0.0;
10377 values[3] = 0.0;
10378 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10379 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10380 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10381 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10382 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10384 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10385 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10386 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10387 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10389 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10390 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10392 hr = IDirect3DDevice9_BeginScene(device);
10393 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10394 if(SUCCEEDED(hr))
10396 trace("going to draw index\n");
10397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10398 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10399 hr = IDirect3DDevice9_EndScene(device);
10400 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10403 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10405 color = getPixelColor(device, 320, 240);
10406 ok(color_match(color, 0x0000ff00, 1),
10407 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10409 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10410 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10411 IDirect3DVertexShader9_Release(shader);
10414 static void sgn_test(IDirect3DDevice9 *device) {
10415 const DWORD shader_code[] = {
10416 0xfffe0200, /* vs_2_0 */
10417 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10418 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10419 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10420 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10421 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10422 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10423 0x0000ffff /* end */
10425 IDirect3DVertexShader9 *shader;
10426 HRESULT hr;
10427 DWORD color;
10428 const float quad[] = {
10429 -1.0, -1.0, 0.1,
10430 1.0, -1.0, 0.1,
10431 -1.0, 1.0, 0.1,
10432 1.0, 1.0, 0.1
10435 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10436 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10437 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10438 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10439 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10441 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10442 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10444 hr = IDirect3DDevice9_BeginScene(device);
10445 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10446 if(SUCCEEDED(hr))
10448 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10449 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10450 hr = IDirect3DDevice9_EndScene(device);
10451 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10453 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10454 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10456 color = getPixelColor(device, 320, 240);
10457 ok(color_match(color, 0x008000ff, 1),
10458 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10460 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10461 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10462 IDirect3DVertexShader9_Release(shader);
10465 static void viewport_test(IDirect3DDevice9 *device) {
10466 HRESULT hr;
10467 DWORD color;
10468 D3DVIEWPORT9 vp, old_vp;
10469 const float quad[] =
10471 -0.5, -0.5, 0.1,
10472 0.5, -0.5, 0.1,
10473 -0.5, 0.5, 0.1,
10474 0.5, 0.5, 0.1
10477 memset(&old_vp, 0, sizeof(old_vp));
10478 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10479 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10481 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10482 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10484 /* Test a viewport with Width and Height bigger than the surface dimensions
10486 * TODO: Test Width < surface.width, but X + Width > surface.width
10487 * TODO: Test Width < surface.width, what happens with the height?
10489 memset(&vp, 0, sizeof(vp));
10490 vp.X = 0;
10491 vp.Y = 0;
10492 vp.Width = 10000;
10493 vp.Height = 10000;
10494 vp.MinZ = 0.0;
10495 vp.MaxZ = 0.0;
10496 hr = IDirect3DDevice9_SetViewport(device, &vp);
10497 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10499 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10500 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10501 hr = IDirect3DDevice9_BeginScene(device);
10502 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10503 if(SUCCEEDED(hr))
10505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10506 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10507 hr = IDirect3DDevice9_EndScene(device);
10508 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10510 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10512 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10513 color = getPixelColor(device, 158, 118);
10514 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10515 color = getPixelColor(device, 162, 118);
10516 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10517 color = getPixelColor(device, 158, 122);
10518 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10519 color = getPixelColor(device, 162, 122);
10520 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10522 color = getPixelColor(device, 478, 358);
10523 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10524 color = getPixelColor(device, 482, 358);
10525 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10526 color = getPixelColor(device, 478, 362);
10527 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10528 color = getPixelColor(device, 482, 362);
10529 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10531 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10532 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10535 START_TEST(visual)
10537 IDirect3DDevice9 *device_ptr;
10538 D3DCAPS9 caps;
10539 HRESULT hr;
10540 DWORD color;
10542 d3d9_handle = LoadLibraryA("d3d9.dll");
10543 if (!d3d9_handle)
10545 skip("Could not load d3d9.dll\n");
10546 return;
10549 device_ptr = init_d3d9();
10550 if (!device_ptr)
10552 skip("Creating the device failed\n");
10553 return;
10556 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10558 /* Check for the reliability of the returned data */
10559 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10560 if(FAILED(hr))
10562 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10563 goto cleanup;
10565 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10567 color = getPixelColor(device_ptr, 1, 1);
10568 if(color !=0x00ff0000)
10570 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10571 goto cleanup;
10574 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10575 if(FAILED(hr))
10577 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10578 goto cleanup;
10580 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10582 color = getPixelColor(device_ptr, 639, 479);
10583 if(color != 0x0000ddee)
10585 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10586 goto cleanup;
10589 /* Now execute the real tests */
10590 stretchrect_test(device_ptr);
10591 lighting_test(device_ptr);
10592 clear_test(device_ptr);
10593 fog_test(device_ptr);
10594 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10596 test_cube_wrap(device_ptr);
10597 } else {
10598 skip("No cube texture support\n");
10600 z_range_test(device_ptr);
10601 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10603 maxmip_test(device_ptr);
10605 else
10607 skip("No mipmap support\n");
10609 offscreen_test(device_ptr);
10610 alpha_test(device_ptr);
10611 shademode_test(device_ptr);
10612 srgbtexture_test(device_ptr);
10613 release_buffer_test(device_ptr);
10614 float_texture_test(device_ptr);
10615 g16r16_texture_test(device_ptr);
10616 pixelshader_blending_test(device_ptr);
10617 texture_transform_flags_test(device_ptr);
10618 autogen_mipmap_test(device_ptr);
10619 fixed_function_decl_test(device_ptr);
10620 conditional_np2_repeat_test(device_ptr);
10621 fixed_function_bumpmap_test(device_ptr);
10622 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10623 stencil_cull_test(device_ptr);
10624 } else {
10625 skip("No two sided stencil support\n");
10627 pointsize_test(device_ptr);
10628 tssargtemp_test(device_ptr);
10629 np2_stretch_rect_test(device_ptr);
10630 yuv_color_test(device_ptr);
10631 zwriteenable_test(device_ptr);
10632 alphatest_test(device_ptr);
10633 viewport_test(device_ptr);
10635 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10637 test_constant_clamp_vs(device_ptr);
10638 test_compare_instructions(device_ptr);
10640 else skip("No vs_1_1 support\n");
10642 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10644 test_mova(device_ptr);
10645 loop_index_test(device_ptr);
10646 sincos_test(device_ptr);
10647 sgn_test(device_ptr);
10648 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10649 test_vshader_input(device_ptr);
10650 test_vshader_float16(device_ptr);
10651 stream_test(device_ptr);
10652 } else {
10653 skip("No vs_3_0 support\n");
10656 else skip("No vs_2_0 support\n");
10658 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10660 fog_with_shader_test(device_ptr);
10661 fog_srgbwrite_test(device_ptr);
10663 else skip("No vs_1_1 and ps_1_1 support\n");
10665 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10667 texbem_test(device_ptr);
10668 texdepth_test(device_ptr);
10669 texkill_test(device_ptr);
10670 x8l8v8u8_test(device_ptr);
10671 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10672 constant_clamp_ps_test(device_ptr);
10673 cnd_test(device_ptr);
10674 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10675 dp2add_ps_test(device_ptr);
10676 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10677 nested_loop_test(device_ptr);
10678 fixed_function_varying_test(device_ptr);
10679 vFace_register_test(device_ptr);
10680 vpos_register_test(device_ptr);
10681 multiple_rendertargets_test(device_ptr);
10682 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10683 vshader_version_varying_test(device_ptr);
10684 pshader_version_varying_test(device_ptr);
10685 } else {
10686 skip("No vs_3_0 support\n");
10688 } else {
10689 skip("No ps_3_0 support\n");
10691 } else {
10692 skip("No ps_2_0 support\n");
10696 else skip("No ps_1_1 support\n");
10698 texop_test(device_ptr);
10699 texop_range_test(device_ptr);
10700 alphareplicate_test(device_ptr);
10701 dp3_alpha_test(device_ptr);
10703 cleanup:
10704 if(device_ptr) {
10705 D3DPRESENT_PARAMETERS present_parameters;
10706 IDirect3DSwapChain9 *swapchain;
10707 ULONG ref;
10709 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10710 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10711 DestroyWindow(present_parameters.hDeviceWindow);
10712 IDirect3DSwapChain9_Release(swapchain);
10713 ref = IDirect3DDevice9_Release(device_ptr);
10714 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);