pop 85fe8f259bfd4a5f252d249d4337834986a9b632
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob1da7cca2b73980dbc1e4a7743c47c12e6e0c8768
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114 if(FAILED(hr) || !surf ) /* This is not a test */
116 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117 return 0xdeadbeef;
120 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121 if(FAILED(hr))
123 trace("Can't get the render target, hr=%08x\n", hr);
124 ret = 0xdeadbeed;
125 goto out;
128 hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129 if(FAILED(hr))
131 trace("Can't read the render target data, hr=%08x\n", hr);
132 ret = 0xdeadbeec;
133 goto out;
136 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137 if(FAILED(hr))
139 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140 ret = 0xdeadbeeb;
141 goto out;
144 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145 * really important for these tests
147 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148 hr = IDirect3DSurface9_UnlockRect(surf);
149 if(FAILED(hr))
151 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
154 out:
155 if(target) IDirect3DSurface9_Release(target);
156 if(surf) IDirect3DSurface9_Release(surf);
157 return ret;
160 static IDirect3DDevice9 *init_d3d9(void)
162 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163 IDirect3D9 *d3d9_ptr = 0;
164 IDirect3DDevice9 *device_ptr = 0;
165 D3DPRESENT_PARAMETERS present_parameters;
166 HRESULT hr;
167 D3DADAPTER_IDENTIFIER9 identifier;
169 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171 if (!d3d9_create) return NULL;
173 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174 if (!d3d9_ptr)
176 skip("could not create D3D9\n");
177 return NULL;
180 ZeroMemory(&present_parameters, sizeof(present_parameters));
181 present_parameters.Windowed = TRUE;
182 present_parameters.hDeviceWindow = create_window();
183 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184 present_parameters.BackBufferWidth = 640;
185 present_parameters.BackBufferHeight = 480;
186 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187 present_parameters.EnableAutoDepthStencil = TRUE;
188 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190 memset(&identifier, 0, sizeof(identifier));
191 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193 trace("Driver string: \"%s\"\n", identifier.Driver);
194 trace("Description string: \"%s\"\n", identifier.Description);
195 ok(identifier.Description[0] != '\0', "Empty driver description\n");
196 trace("Device name string: \"%s\"\n", identifier.DeviceName);
197 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
198 trace("Driver version %d.%d.%d.%d\n",
199 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203 if(FAILED(hr)) {
204 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206 if(FAILED(hr)) {
207 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
210 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
212 return device_ptr;
215 struct vertex
217 float x, y, z;
218 DWORD diffuse;
221 struct tvertex
223 float x, y, z, rhw;
224 DWORD diffuse;
227 struct nvertex
229 float x, y, z;
230 float nx, ny, nz;
231 DWORD diffuse;
234 static void lighting_test(IDirect3DDevice9 *device)
236 HRESULT hr;
237 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239 DWORD color;
240 D3DMATERIAL9 material, old_material;
241 DWORD cop, carg;
243 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244 0.0f, 1.0f, 0.0f, 0.0f,
245 0.0f, 0.0f, 1.0f, 0.0f,
246 0.0f, 0.0f, 0.0f, 1.0f };
248 struct vertex unlitquad[] =
250 {-1.0f, -1.0f, 0.1f, 0xffff0000},
251 {-1.0f, 0.0f, 0.1f, 0xffff0000},
252 { 0.0f, 0.0f, 0.1f, 0xffff0000},
253 { 0.0f, -1.0f, 0.1f, 0xffff0000},
255 struct vertex litquad[] =
257 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
258 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
259 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
260 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
262 struct nvertex unlitnquad[] =
264 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
265 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
267 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
269 struct nvertex litnquad[] =
271 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
272 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
274 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
276 WORD Indices[] = {0, 1, 2, 2, 3, 0};
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
281 /* Setup some states that may cause issues */
282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
307 hr = IDirect3DDevice9_SetFVF(device, 0);
308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetFVF(device, fvf);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
313 hr = IDirect3DDevice9_BeginScene(device);
314 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315 if(hr == D3D_OK)
317 /* No lights are defined... That means, lit vertices should be entirely black */
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330 hr = IDirect3DDevice9_SetFVF(device, nfvf);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345 IDirect3DDevice9_EndScene(device);
346 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
349 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
358 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
360 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362 memset(&material, 0, sizeof(material));
363 material.Diffuse.r = 0.0;
364 material.Diffuse.g = 0.0;
365 material.Diffuse.b = 0.0;
366 material.Diffuse.a = 1.0;
367 material.Ambient.r = 0.0;
368 material.Ambient.g = 0.0;
369 material.Ambient.b = 0.0;
370 material.Ambient.a = 0.0;
371 material.Specular.r = 0.0;
372 material.Specular.g = 0.0;
373 material.Specular.b = 0.0;
374 material.Specular.a = 0.0;
375 material.Emissive.r = 0.0;
376 material.Emissive.g = 0.0;
377 material.Emissive.b = 0.0;
378 material.Emissive.a = 0.0;
379 material.Power = 0.0;
380 IDirect3DDevice9_SetMaterial(device, &material);
381 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
388 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
397 hr = IDirect3DDevice9_BeginScene(device);
398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399 if(SUCCEEDED(hr)) {
400 struct vertex lighting_test[] = {
401 {-1.0, -1.0, 0.1, 0x8000ff00},
402 { 1.0, -1.0, 0.1, 0x80000000},
403 {-1.0, 1.0, 0.1, 0x8000ff00},
404 { 1.0, 1.0, 0.1, 0x80000000}
406 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
411 hr = IDirect3DDevice9_EndScene(device);
412 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
415 color = getPixelColor(device, 320, 240);
416 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
433 static void clear_test(IDirect3DDevice9 *device)
435 /* Tests the correctness of clearing parameters */
436 HRESULT hr;
437 D3DRECT rect[2];
438 D3DRECT rect_negneg;
439 DWORD color;
440 D3DVIEWPORT9 old_vp, vp;
441 RECT scissor;
442 DWORD oldColorWrite;
443 BOOL invalid_clear_failed = FALSE;
445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448 /* Positive x, negative y */
449 rect[0].x1 = 0;
450 rect[0].y1 = 480;
451 rect[0].x2 = 320;
452 rect[0].y2 = 240;
454 /* Positive x, positive y */
455 rect[1].x1 = 0;
456 rect[1].y1 = 0;
457 rect[1].x2 = 320;
458 rect[1].y2 = 240;
459 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460 * returns D3D_OK, but ignores the rectangle silently
462 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466 /* negative x, negative y */
467 rect_negneg.x1 = 640;
468 rect_negneg.y1 = 240;
469 rect_negneg.x2 = 320;
470 rect_negneg.y2 = 0;
471 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475 color = getPixelColor(device, 160, 360); /* lower left quad */
476 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477 color = getPixelColor(device, 160, 120); /* upper left quad */
478 if(invalid_clear_failed) {
479 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481 } else {
482 /* If the negative rectangle was dropped silently, the correct ones are cleared */
483 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485 color = getPixelColor(device, 480, 360); /* lower right quad */
486 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487 color = getPixelColor(device, 480, 120); /* upper right quad */
488 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492 /* Test how the viewport affects clears */
493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
498 vp.X = 160;
499 vp.Y = 120;
500 vp.Width = 160;
501 vp.Height = 120;
502 vp.MinZ = 0.0;
503 vp.MaxZ = 1.0;
504 hr = IDirect3DDevice9_SetViewport(device, &vp);
505 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509 vp.X = 320;
510 vp.Y = 240;
511 vp.Width = 320;
512 vp.Height = 240;
513 vp.MinZ = 0.0;
514 vp.MaxZ = 1.0;
515 hr = IDirect3DDevice9_SetViewport(device, &vp);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 rect[0].x1 = 160;
518 rect[0].y1 = 120;
519 rect[0].x2 = 480;
520 rect[0].y2 = 360;
521 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
524 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
527 color = getPixelColor(device, 158, 118);
528 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529 color = getPixelColor(device, 162, 118);
530 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531 color = getPixelColor(device, 158, 122);
532 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533 color = getPixelColor(device, 162, 122);
534 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
536 color = getPixelColor(device, 318, 238);
537 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538 color = getPixelColor(device, 322, 238);
539 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540 color = getPixelColor(device, 318, 242);
541 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542 color = getPixelColor(device, 322, 242);
543 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
545 color = getPixelColor(device, 478, 358);
546 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547 color = getPixelColor(device, 482, 358);
548 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549 color = getPixelColor(device, 478, 362);
550 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551 color = getPixelColor(device, 482, 362);
552 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
554 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 scissor.left = 160;
560 scissor.right = 480;
561 scissor.top = 120;
562 scissor.bottom = 360;
563 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576 color = getPixelColor(device, 158, 118);
577 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578 color = getPixelColor(device, 162, 118);
579 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580 color = getPixelColor(device, 158, 122);
581 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582 color = getPixelColor(device, 162, 122);
583 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
585 color = getPixelColor(device, 158, 358);
586 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587 color = getPixelColor(device, 162, 358);
588 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589 color = getPixelColor(device, 158, 358);
590 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591 color = getPixelColor(device, 162, 362);
592 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
594 color = getPixelColor(device, 478, 118);
595 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596 color = getPixelColor(device, 478, 122);
597 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598 color = getPixelColor(device, 482, 122);
599 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600 color = getPixelColor(device, 482, 358);
601 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
603 color = getPixelColor(device, 478, 358);
604 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605 color = getPixelColor(device, 478, 362);
606 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607 color = getPixelColor(device, 482, 358);
608 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609 color = getPixelColor(device, 482, 362);
610 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612 color = getPixelColor(device, 318, 238);
613 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614 color = getPixelColor(device, 318, 242);
615 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616 color = getPixelColor(device, 322, 238);
617 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618 color = getPixelColor(device, 322, 242);
619 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
621 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
634 /* Colorwriteenable does not affect the clear */
635 color = getPixelColor(device, 320, 240);
636 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
638 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
641 static void color_fill_test(IDirect3DDevice9 *device)
643 HRESULT hr;
644 IDirect3DSurface9 *backbuffer = NULL;
645 IDirect3DSurface9 *rt_surface = NULL;
646 IDirect3DSurface9 *offscreen_surface = NULL;
647 DWORD fill_color, color;
649 /* Test ColorFill on a the backbuffer (should pass) */
650 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652 if(backbuffer)
654 fill_color = 0x112233;
655 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
657 color = getPixelColor(device, 0, 0);
658 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
660 IDirect3DSurface9_Release(backbuffer);
663 /* Test ColorFill on a render target surface (should pass) */
664 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666 if(rt_surface)
668 fill_color = 0x445566;
669 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
671 color = getPixelColorFromSurface(rt_surface, 0, 0);
672 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
674 IDirect3DSurface9_Release(rt_surface);
677 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681 if(offscreen_surface)
683 fill_color = 0x778899;
684 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
686 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
689 IDirect3DSurface9_Release(offscreen_surface);
692 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693 offscreen_surface = NULL;
694 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697 if(offscreen_surface)
699 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
702 IDirect3DSurface9_Release(offscreen_surface);
706 typedef struct {
707 float in[4];
708 DWORD out;
709 } test_data_t;
712 * c7 mova ARGB mov ARGB
713 * -2.4 -2 0x00ffff00 -3 0x00ff0000
714 * -1.6 -2 0x00ffff00 -2 0x00ffff00
715 * -0.4 0 0x0000ffff -1 0x0000ff00
716 * 0.4 0 0x0000ffff 0 0x0000ffff
717 * 1.6 2 0x00ff00ff 1 0x000000ff
718 * 2.4 2 0x00ff00ff 2 0x00ff00ff
720 static void test_mova(IDirect3DDevice9 *device)
722 static const DWORD mova_test[] = {
723 0xfffe0200, /* vs_2_0 */
724 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
725 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
726 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
727 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
728 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
729 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
730 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
731 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
732 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
733 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
734 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
735 0x0000ffff /* END */
737 static const DWORD mov_test[] = {
738 0xfffe0101, /* vs_1_1 */
739 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
740 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
741 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
742 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
743 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
744 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
745 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
746 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
747 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
748 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
749 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
750 0x0000ffff /* END */
753 static const test_data_t test_data[2][6] = {
755 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
763 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
772 static const float quad[][3] = {
773 {-1.0f, -1.0f, 0.0f},
774 {-1.0f, 1.0f, 0.0f},
775 { 1.0f, -1.0f, 0.0f},
776 { 1.0f, 1.0f, 0.0f},
779 static const D3DVERTEXELEMENT9 decl_elements[] = {
780 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781 D3DDECL_END()
784 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785 IDirect3DVertexShader9 *mova_shader = NULL;
786 IDirect3DVertexShader9 *mov_shader = NULL;
787 HRESULT hr;
788 UINT i, j;
790 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
799 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801 for(j = 0; j < 2; ++j)
803 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
805 DWORD color;
807 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
810 hr = IDirect3DDevice9_BeginScene(device);
811 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
816 hr = IDirect3DDevice9_EndScene(device);
817 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
819 color = getPixelColor(device, 320, 240);
820 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
823 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
829 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
833 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836 IDirect3DVertexDeclaration9_Release(vertex_declaration);
837 IDirect3DVertexShader9_Release(mova_shader);
838 IDirect3DVertexShader9_Release(mov_shader);
841 struct sVertex {
842 float x, y, z;
843 DWORD diffuse;
844 DWORD specular;
847 struct sVertexT {
848 float x, y, z, rhw;
849 DWORD diffuse;
850 DWORD specular;
853 static void fog_test(IDirect3DDevice9 *device)
855 HRESULT hr;
856 D3DCOLOR color;
857 float start = 0.0f, end = 1.0f;
858 D3DCAPS9 caps;
859 int i;
861 /* Gets full z based fog with linear fog, no fog with specular color */
862 struct sVertex unstransformed_1[] = {
863 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
864 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
865 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
866 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
868 /* Ok, I am too lazy to deal with transform matrices */
869 struct sVertex unstransformed_2[] = {
870 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
871 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
872 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
873 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
875 /* Untransformed ones. Give them a different diffuse color to make the test look
876 * nicer. It also makes making sure that they are drawn correctly easier.
878 struct sVertexT transformed_1[] = {
879 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
880 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
881 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
882 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
884 struct sVertexT transformed_2[] = {
885 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
886 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
887 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
888 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
890 struct vertex rev_fog_quads[] = {
891 {-1.0, -1.0, 0.1, 0x000000ff},
892 {-1.0, 0.0, 0.1, 0x000000ff},
893 { 0.0, 0.0, 0.1, 0x000000ff},
894 { 0.0, -1.0, 0.1, 0x000000ff},
896 { 0.0, -1.0, 0.9, 0x000000ff},
897 { 0.0, 0.0, 0.9, 0x000000ff},
898 { 1.0, 0.0, 0.9, 0x000000ff},
899 { 1.0, -1.0, 0.9, 0x000000ff},
901 { 0.0, 0.0, 0.4, 0x000000ff},
902 { 0.0, 1.0, 0.4, 0x000000ff},
903 { 1.0, 1.0, 0.4, 0x000000ff},
904 { 1.0, 0.0, 0.4, 0x000000ff},
906 {-1.0, 0.0, 0.7, 0x000000ff},
907 {-1.0, 1.0, 0.7, 0x000000ff},
908 { 0.0, 1.0, 0.7, 0x000000ff},
909 { 0.0, 0.0, 0.7, 0x000000ff},
911 WORD Indices[] = {0, 1, 2, 2, 3, 0};
913 memset(&caps, 0, sizeof(caps));
914 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
919 /* Setup initial states: No lighting, fog on, fog color */
920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
927 /* First test: Both table fog and vertex fog off */
928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
933 /* Start = 0, end = 1. Should be default, but set them */
934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
939 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
941 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946 sizeof(unstransformed_1[0]));
947 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
949 /* That makes it use the Z value */
950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952 /* Untransformed, vertex fog != none (or table fog != none):
953 * Use the Z value as input into the equation
955 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957 sizeof(unstransformed_1[0]));
958 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960 /* transformed verts */
961 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966 sizeof(transformed_1[0]));
967 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972 * equation
974 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976 sizeof(transformed_2[0]));
977 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
979 hr = IDirect3DDevice9_EndScene(device);
980 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
982 else
984 ok(FALSE, "BeginScene failed\n");
987 color = getPixelColor(device, 160, 360);
988 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989 color = getPixelColor(device, 160, 120);
990 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991 color = getPixelColor(device, 480, 120);
992 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
995 color = getPixelColor(device, 480, 360);
996 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
998 else
1000 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001 * The settings above result in no fogging with vertex fog
1003 color = getPixelColor(device, 480, 120);
1004 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005 trace("Info: Table fog not supported by this device\n");
1007 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1009 /* Now test the special case fogstart == fogend */
1010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1013 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1015 start = 512;
1016 end = 512;
1017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1022 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1029 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033 * color and has fixed fogstart and fogend.
1035 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037 sizeof(unstransformed_1[0]));
1038 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041 sizeof(unstransformed_1[0]));
1042 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049 sizeof(transformed_1[0]));
1050 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1052 hr = IDirect3DDevice9_EndScene(device);
1053 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1055 else
1057 ok(FALSE, "BeginScene failed\n");
1059 color = getPixelColor(device, 160, 360);
1060 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061 color = getPixelColor(device, 160, 120);
1062 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063 color = getPixelColor(device, 480, 120);
1064 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1067 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068 * but without shaders it seems to work everywhere
1070 end = 0.2;
1071 start = 0.8;
1072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1079 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081 * so skip this for now
1083 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084 const char *mode = (i ? "table" : "vertex");
1085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091 hr = IDirect3DDevice9_BeginScene(device);
1092 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093 if(SUCCEEDED(hr)) {
1094 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1095 4, 5, 6, 6, 7, 4,
1096 8, 9, 10, 10, 11, 8,
1097 12, 13, 14, 14, 15, 12};
1099 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101 sizeof(rev_fog_quads[0]));
1102 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1104 hr = IDirect3DDevice9_EndScene(device);
1105 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1107 color = getPixelColor(device, 160, 360);
1108 ok(color_match(color, 0x0000ff00, 1),
1109 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1111 color = getPixelColor(device, 160, 120);
1112 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1115 color = getPixelColor(device, 480, 120);
1116 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1119 color = getPixelColor(device, 480, 360);
1120 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126 break;
1129 /* Turn off the fog master switch to avoid confusing other tests */
1130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132 start = 0.0;
1133 end = 1.0;
1134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146 * regardless of the actual addressing mode set. The way this test works is
1147 * that we sample in one of the corners of the cubemap with filtering enabled,
1148 * and check the interpolated color. There are essentially two reasonable
1149 * things an implementation can do: Either pick one of the faces and
1150 * interpolate the edge texel with itself (i.e., clamp within the face), or
1151 * interpolate between the edge texels of the three involved faces. It should
1152 * never involve the border color or the other side (texcoord wrapping) of a
1153 * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1156 static const float quad[][6] = {
1157 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1163 static const D3DVERTEXELEMENT9 decl_elements[] = {
1164 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166 D3DDECL_END()
1169 static const struct {
1170 D3DTEXTUREADDRESS mode;
1171 const char *name;
1172 } address_modes[] = {
1173 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1180 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181 IDirect3DCubeTexture9 *texture = NULL;
1182 IDirect3DSurface9 *surface = NULL;
1183 IDirect3DSurface9 *face_surface;
1184 D3DLOCKED_RECT locked_rect;
1185 HRESULT hr;
1186 UINT x;
1187 INT y, face;
1189 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1194 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1198 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199 D3DPOOL_DEFAULT, &texture, NULL);
1200 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1202 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1205 for (y = 0; y < 128; ++y)
1207 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208 for (x = 0; x < 64; ++x)
1210 *ptr++ = 0xff0000ff;
1212 for (x = 64; x < 128; ++x)
1214 *ptr++ = 0xffff0000;
1218 hr = IDirect3DSurface9_UnlockRect(surface);
1219 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1221 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1224 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1227 IDirect3DSurface9_Release(face_surface);
1229 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1232 for (y = 0; y < 128; ++y)
1234 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235 for (x = 0; x < 64; ++x)
1237 *ptr++ = 0xffff0000;
1239 for (x = 64; x < 128; ++x)
1241 *ptr++ = 0xff0000ff;
1245 hr = IDirect3DSurface9_UnlockRect(surface);
1246 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1248 /* Create cube faces */
1249 for (face = 1; face < 6; ++face)
1251 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1254 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1257 IDirect3DSurface9_Release(face_surface);
1260 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1263 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1273 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1275 DWORD color;
1277 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1282 hr = IDirect3DDevice9_BeginScene(device);
1283 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1288 hr = IDirect3DDevice9_EndScene(device);
1289 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1291 color = getPixelColor(device, 320, 240);
1292 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294 color, address_modes[x].name);
1296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1303 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1306 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307 IDirect3DCubeTexture9_Release(texture);
1308 IDirect3DSurface9_Release(surface);
1311 static void offscreen_test(IDirect3DDevice9 *device)
1313 HRESULT hr;
1314 IDirect3DTexture9 *offscreenTexture = NULL;
1315 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316 DWORD color;
1318 static const float quad[][5] = {
1319 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1321 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1325 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1328 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330 if(!offscreenTexture) {
1331 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334 if(!offscreenTexture) {
1335 skip("Cannot create an offscreen render target\n");
1336 goto out;
1340 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342 if(!backbuffer) {
1343 goto out;
1346 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348 if(!offscreen) {
1349 goto out;
1352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1366 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1372 /* Draw without textures - Should result in a white quad */
1373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1376 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1381 /* This time with the texture */
1382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1385 IDirect3DDevice9_EndScene(device);
1388 /* Center quad - should be white */
1389 color = getPixelColor(device, 320, 240);
1390 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391 /* Some quad in the cleared part of the texture */
1392 color = getPixelColor(device, 170, 240);
1393 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394 /* Part of the originally cleared back buffer */
1395 color = getPixelColor(device, 10, 10);
1396 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397 if(0) {
1398 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400 * the offscreen rendering mode this test would succeed or fail
1402 color = getPixelColor(device, 10, 470);
1403 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1406 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1408 out:
1409 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1412 /* restore things */
1413 if(backbuffer) {
1414 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416 IDirect3DSurface9_Release(backbuffer);
1418 if(offscreenTexture) {
1419 IDirect3DTexture9_Release(offscreenTexture);
1421 if(offscreen) {
1422 IDirect3DSurface9_Release(offscreen);
1426 /* This test tests fog in combination with shaders.
1427 * What's tested: linear fog (vertex and table) with pixel shader
1428 * linear table fog with non foggy vertex shader
1429 * vertex fog with foggy vertex shader, non-linear
1430 * fog with shader, non-linear fog with foggy shader,
1431 * linear table fog with foggy shader
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1435 HRESULT hr;
1436 DWORD color;
1437 union {
1438 float f;
1439 DWORD i;
1440 } start, end;
1441 unsigned int i, j;
1443 /* basic vertex shader without fog computation ("non foggy") */
1444 static const DWORD vertex_shader_code1[] = {
1445 0xfffe0101, /* vs_1_1 */
1446 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1447 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1448 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1449 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1450 0x0000ffff
1452 /* basic vertex shader with reversed fog computation ("foggy") */
1453 static const DWORD vertex_shader_code2[] = {
1454 0xfffe0101, /* vs_1_1 */
1455 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1456 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1457 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1459 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1460 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1461 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1462 0x0000ffff
1464 /* basic pixel shader */
1465 static const DWORD pixel_shader_code[] = {
1466 0xffff0101, /* ps_1_1 */
1467 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1468 0x0000ffff
1471 static struct vertex quad[] = {
1472 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1473 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1474 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1475 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1478 static const D3DVERTEXELEMENT9 decl_elements[] = {
1479 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1481 D3DDECL_END()
1484 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1486 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1488 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489 static const struct test_data_t {
1490 int vshader;
1491 int pshader;
1492 D3DFOGMODE vfog;
1493 D3DFOGMODE tfog;
1494 unsigned int color[11];
1495 } test_data[] = {
1496 /* only pixel shader: */
1497 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1513 /* vertex shader */
1514 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1531 /* vertex shader and pixel shader */
1532 /* The next 4 tests would read the fog coord output, but it isn't available.
1533 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535 * These tests should be disabled if some other hardware behaves differently
1537 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1550 /* These use the Z coordinate with linear table fog */
1551 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1564 /* Non-linear table fog without fog coord */
1565 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1572 #if 0 /* FIXME: these fail on GeForce 8500 */
1573 /* foggy vertex shader */
1574 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1588 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589 * all using the fixed fog-coord linear fog
1591 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 /* These use table fog. Here the shader-provided fog coordinate is
1605 * ignored and the z coordinate used instead
1607 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1618 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619 start.f=0.1f;
1620 end.f=0.9f;
1622 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1631 /* Setup initial states: No lighting, fog on, fog color */
1632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1646 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1652 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1654 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1663 for(j=0; j < 11; j++)
1665 /* Don't use the whole zrange to prevent rounding errors */
1666 quad[0].z = 0.001f + (float)j / 10.02f;
1667 quad[1].z = 0.001f + (float)j / 10.02f;
1668 quad[2].z = 0.001f + (float)j / 10.02f;
1669 quad[3].z = 0.001f + (float)j / 10.02f;
1671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1674 hr = IDirect3DDevice9_BeginScene(device);
1675 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1680 hr = IDirect3DDevice9_EndScene(device);
1681 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1683 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684 color = getPixelColor(device, 128, 240);
1685 ok(color_match(color, test_data[i].color[j], 13),
1686 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1689 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1693 /* reset states */
1694 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1703 IDirect3DVertexShader9_Release(vertex_shader[1]);
1704 IDirect3DVertexShader9_Release(vertex_shader[2]);
1705 IDirect3DPixelShader9_Release(pixel_shader[1]);
1706 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710 unsigned int i, x, y;
1711 HRESULT hr;
1712 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713 D3DLOCKED_RECT locked_rect;
1715 /* Generate the textures */
1716 for(i=0; i<2; i++)
1718 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719 D3DPOOL_MANAGED, &texture[i], NULL);
1720 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1722 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724 for (y = 0; y < 128; ++y)
1726 if(i)
1727 { /* Set up black texture with 2x2 texel white spot in the middle */
1728 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729 for (x = 0; x < 128; ++x)
1731 if(y>62 && y<66 && x>62 && x<66)
1732 *ptr++ = 0xffffffff;
1733 else
1734 *ptr++ = 0xff000000;
1737 else
1738 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739 * (if multiplied with bumpenvmat)
1741 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742 for (x = 0; x < 128; ++x)
1744 if(abs(x-64)>abs(y-64))
1746 if(x < 64)
1747 *ptr++ = 0xc000;
1748 else
1749 *ptr++ = 0x4000;
1751 else
1753 if(y < 64)
1754 *ptr++ = 0x0040;
1755 else
1756 *ptr++ = 0x00c0;
1761 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1764 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1767 /* Disable texture filtering */
1768 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1773 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1780 /* test the behavior of the texbem instruction
1781 * with normal 2D and projective 2D textures
1783 static void texbem_test(IDirect3DDevice9 *device)
1785 HRESULT hr;
1786 DWORD color;
1787 int i;
1789 static const DWORD pixel_shader_code[] = {
1790 0xffff0101, /* ps_1_1*/
1791 0x00000042, 0xb00f0000, /* tex t0*/
1792 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794 0x0000ffff
1796 static const DWORD double_texbem_code[] = {
1797 0xffff0103, /* ps_1_3 */
1798 0x00000042, 0xb00f0000, /* tex t0 */
1799 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1800 0x00000042, 0xb00f0002, /* tex t2 */
1801 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1802 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1803 0x0000ffff /* end */
1807 static const float quad[][7] = {
1808 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1813 static const float quad_proj[][9] = {
1814 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1815 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1816 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1817 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1820 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824 D3DDECL_END()
1826 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829 D3DDECL_END()
1830 } };
1832 /* use asymmetric matrix to test loading */
1833 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1835 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836 IDirect3DPixelShader9 *pixel_shader = NULL;
1837 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1838 D3DLOCKED_RECT locked_rect;
1840 generate_bumpmap_textures(device);
1842 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1848 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1854 for(i=0; i<2; i++)
1856 if(i)
1858 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1862 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1867 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1872 hr = IDirect3DDevice9_BeginScene(device);
1873 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1875 if(!i)
1876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877 else
1878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1881 hr = IDirect3DDevice9_EndScene(device);
1882 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1884 color = getPixelColor(device, 320-32, 240);
1885 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886 color = getPixelColor(device, 320+32, 240);
1887 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888 color = getPixelColor(device, 320, 240-32);
1889 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890 color = getPixelColor(device, 320, 240+32);
1891 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1896 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898 IDirect3DPixelShader9_Release(pixel_shader);
1900 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1905 /* clean up */
1906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1909 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1912 for(i=0; i<2; i++)
1914 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919 IDirect3DTexture9_Release(texture);
1922 /* Test double texbem */
1923 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1932 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1937 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1940 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1948 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex 0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952 static const DWORD pixel_data[] = {
1953 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1958 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1966 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968 for(i = 0; i < 8; i++) {
1969 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1971 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1975 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1988 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1989 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1990 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1999 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2000 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2001 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2027 hr = IDirect3DDevice9_BeginScene(device);
2028 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029 if(SUCCEEDED(hr)) {
2030 static const float double_quad[] = {
2031 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2032 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2033 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2034 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039 hr = IDirect3DDevice9_EndScene(device);
2040 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2042 color = getPixelColor(device, 320, 240);
2043 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2045 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2056 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2059 IDirect3DPixelShader9_Release(pixel_shader);
2060 IDirect3DTexture9_Release(texture);
2061 IDirect3DTexture9_Release(texture1);
2062 IDirect3DTexture9_Release(texture2);
2065 static void z_range_test(IDirect3DDevice9 *device)
2067 const struct vertex quad[] =
2069 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2070 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2071 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2072 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2074 const struct vertex quad2[] =
2076 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2077 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2078 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2079 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2082 const struct tvertex quad3[] =
2084 { 0, 240, 1.1f, 1.0, 0xffffff00},
2085 { 0, 480, 1.1f, 1.0, 0xffffff00},
2086 { 640, 240, -1.1f, 1.0, 0xffffff00},
2087 { 640, 480, -1.1f, 1.0, 0xffffff00},
2089 const struct tvertex quad4[] =
2091 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2092 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2093 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2094 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2096 HRESULT hr;
2097 DWORD color;
2098 IDirect3DVertexShader9 *shader;
2099 IDirect3DVertexDeclaration9 *decl;
2100 D3DCAPS9 caps;
2101 const DWORD shader_code[] = {
2102 0xfffe0101, /* vs_1_1 */
2103 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2104 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2105 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2106 0x0000ffff /* end */
2108 static const D3DVERTEXELEMENT9 decl_elements[] = {
2109 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110 D3DDECL_END()
2112 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113 * then call Present. Then clear the color buffer to make sure it has some defined content
2114 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115 * by the depth value.
2117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2135 hr = IDirect3DDevice9_BeginScene(device);
2136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137 if(hr == D3D_OK)
2139 /* Test the untransformed vertex path */
2140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2147 /* Test the transformed vertex path */
2148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2158 hr = IDirect3DDevice9_EndScene(device);
2159 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2162 /* Do not test the exact corner pixels, but go pretty close to them */
2164 /* Clipped because z > 1.0 */
2165 color = getPixelColor(device, 28, 238);
2166 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167 color = getPixelColor(device, 28, 241);
2168 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2170 /* Not clipped, > z buffer clear value(0.75) */
2171 color = getPixelColor(device, 31, 238);
2172 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173 color = getPixelColor(device, 31, 241);
2174 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175 color = getPixelColor(device, 100, 238);
2176 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177 color = getPixelColor(device, 100, 241);
2178 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2180 /* Not clipped, < z buffer clear value */
2181 color = getPixelColor(device, 104, 238);
2182 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183 color = getPixelColor(device, 104, 241);
2184 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185 color = getPixelColor(device, 318, 238);
2186 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187 color = getPixelColor(device, 318, 241);
2188 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2190 /* Clipped because z < 0.0 */
2191 color = getPixelColor(device, 321, 238);
2192 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193 color = getPixelColor(device, 321, 241);
2194 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2199 /* Test the shader path */
2200 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202 skip("Vertex shaders not supported\n");
2203 goto out;
2205 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2210 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2212 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214 IDirect3DDevice9_SetVertexShader(device, shader);
2215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2217 hr = IDirect3DDevice9_BeginScene(device);
2218 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219 if(hr == D3D_OK)
2221 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2232 hr = IDirect3DDevice9_EndScene(device);
2233 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2236 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238 IDirect3DDevice9_SetVertexShader(device, NULL);
2239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2241 IDirect3DVertexDeclaration9_Release(decl);
2242 IDirect3DVertexShader9_Release(shader);
2244 /* Z < 1.0 */
2245 color = getPixelColor(device, 28, 238);
2246 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2248 /* 1.0 < z < 0.75 */
2249 color = getPixelColor(device, 31, 238);
2250 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251 color = getPixelColor(device, 100, 238);
2252 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2254 /* 0.75 < z < 0.0 */
2255 color = getPixelColor(device, 104, 238);
2256 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257 color = getPixelColor(device, 318, 238);
2258 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2260 /* 0.0 < z */
2261 color = getPixelColor(device, 321, 238);
2262 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2264 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2267 out:
2268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2278 D3DSURFACE_DESC desc;
2279 D3DLOCKED_RECT l;
2280 HRESULT hr;
2281 unsigned int x, y;
2282 DWORD *mem;
2284 memset(&desc, 0, sizeof(desc));
2285 memset(&l, 0, sizeof(l));
2286 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290 if(FAILED(hr)) return;
2292 for(y = 0; y < desc.Height; y++)
2294 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2297 mem[x] = color;
2300 hr = IDirect3DSurface9_UnlockRect(surface);
2301 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2307 HRESULT hr;
2308 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315 IDirect3DSurface9 *orig_rt = NULL;
2316 IDirect3DSurface9 *backbuffer = NULL;
2317 DWORD color;
2319 RECT src_rect64 = {0, 0, 64, 64};
2320 RECT src_rect64_flipy = {0, 64, 64, 0};
2321 RECT dst_rect64 = {0, 0, 64, 64};
2322 RECT dst_rect64_flipy = {0, 64, 64, 0};
2324 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326 if(!orig_rt) {
2327 goto out;
2330 /* Create our temporary surfaces in system memory */
2331 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2336 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2344 /* Create render target surfaces */
2345 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2354 /* Create render target textures */
2355 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363 if (tex_rt32) {
2364 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2367 if (tex_rt64) {
2368 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2371 if (tex_rt_dest64) {
2372 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2375 if (tex_rt_dest64) {
2376 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2380 /* Create regular textures in D3DPOOL_DEFAULT */
2381 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387 if (tex32) {
2388 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2391 if (tex64) {
2392 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2395 if (tex_dest64) {
2396 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2400 /*********************************************************************
2401 * Tests for when the source parameter is an offscreen plain surface *
2402 *********************************************************************/
2404 /* Fill the offscreen 64x64 surface with green */
2405 if (surf_offscreen64)
2406 fill_surface(surf_offscreen64, 0xff00ff00);
2408 /* offscreenplain ==> offscreenplain, same size */
2409 if(surf_offscreen64 && surf_offscreen_dest64) {
2410 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2413 if (hr == D3D_OK) {
2414 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2418 /* Blit without scaling */
2419 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2422 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2426 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2431 /* offscreenplain ==> rendertarget texture, same size */
2432 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2436 /* We can't lock rendertarget textures, so copy to our temp surface first */
2437 if (hr == D3D_OK) {
2438 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2442 if (hr == D3D_OK) {
2443 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2447 /* Blit without scaling */
2448 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2451 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2455 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460 /* offscreenplain ==> rendertarget surface, same size */
2461 if(surf_offscreen64 && surf_rt_dest64) {
2462 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2465 if (hr == D3D_OK) {
2466 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2470 /* Blit without scaling */
2471 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2474 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2478 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2483 /* offscreenplain ==> texture, same size (should fail) */
2484 if(surf_offscreen64 && surf_tex_dest64) {
2485 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2489 /* Fill the smaller offscreen surface with red */
2490 fill_surface(surf_offscreen32, 0xffff0000);
2492 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493 if(surf_offscreen32 && surf_offscreen64) {
2494 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2498 /* offscreenplain ==> rendertarget texture, scaling */
2499 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2503 /* We can't lock rendertarget textures, so copy to our temp surface first */
2504 if (hr == D3D_OK) {
2505 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2509 if (hr == D3D_OK) {
2510 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2515 /* offscreenplain ==> rendertarget surface, scaling */
2516 if(surf_offscreen32 && surf_rt_dest64) {
2517 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2520 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2524 /* offscreenplain ==> texture, scaling (should fail) */
2525 if(surf_offscreen32 && surf_tex_dest64) {
2526 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2530 /************************************************************
2531 * Tests for when the source parameter is a regular texture *
2532 ************************************************************/
2534 /* Fill the surface of the regular texture with blue */
2535 if (surf_tex64 && surf_temp64) {
2536 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537 fill_surface(surf_temp64, 0xff0000ff);
2538 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2542 /* texture ==> offscreenplain, same size */
2543 if(surf_tex64 && surf_offscreen64) {
2544 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2548 /* texture ==> rendertarget texture, same size */
2549 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553 /* We can't lock rendertarget textures, so copy to our temp surface first */
2554 if (hr == D3D_OK) {
2555 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2559 if (hr == D3D_OK) {
2560 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2564 /* Blit without scaling */
2565 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2568 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2572 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2577 /* texture ==> rendertarget surface, same size */
2578 if(surf_tex64 && surf_rt_dest64) {
2579 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2582 if (hr == D3D_OK) {
2583 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2587 /* Blit without scaling */
2588 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2591 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2595 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2600 /* texture ==> texture, same size (should fail) */
2601 if(surf_tex64 && surf_tex_dest64) {
2602 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2606 /* Fill the surface of the smaller regular texture with red */
2607 if (surf_tex32 && surf_temp32) {
2608 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609 fill_surface(surf_temp32, 0xffff0000);
2610 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2614 /* texture ==> offscreenplain, scaling (should fail) */
2615 if(surf_tex32 && surf_offscreen64) {
2616 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2620 /* texture ==> rendertarget texture, scaling */
2621 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625 /* We can't lock rendertarget textures, so copy to our temp surface first */
2626 if (hr == D3D_OK) {
2627 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2631 if (hr == D3D_OK) {
2632 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2637 /* texture ==> rendertarget surface, scaling */
2638 if(surf_tex32 && surf_rt_dest64) {
2639 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2646 /* texture ==> texture, scaling (should fail) */
2647 if(surf_tex32 && surf_tex_dest64) {
2648 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2652 /*****************************************************************
2653 * Tests for when the source parameter is a rendertarget texture *
2654 *****************************************************************/
2656 /* Fill the surface of the rendertarget texture with white */
2657 if (surf_tex_rt64 && surf_temp64) {
2658 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659 fill_surface(surf_temp64, 0xffffffff);
2660 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2664 /* rendertarget texture ==> offscreenplain, same size */
2665 if(surf_tex_rt64 && surf_offscreen64) {
2666 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2670 /* rendertarget texture ==> rendertarget texture, same size */
2671 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2675 /* We can't lock rendertarget textures, so copy to our temp surface first */
2676 if (hr == D3D_OK) {
2677 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2681 if (hr == D3D_OK) {
2682 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2686 /* Blit without scaling */
2687 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2690 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2694 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2699 /* rendertarget texture ==> rendertarget surface, same size */
2700 if(surf_tex_rt64 && surf_rt_dest64) {
2701 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2704 if (hr == D3D_OK) {
2705 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2709 /* Blit without scaling */
2710 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2713 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2717 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2722 /* rendertarget texture ==> texture, same size (should fail) */
2723 if(surf_tex_rt64 && surf_tex_dest64) {
2724 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2728 /* Fill the surface of the smaller rendertarget texture with red */
2729 if (surf_tex_rt32 && surf_temp32) {
2730 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731 fill_surface(surf_temp32, 0xffff0000);
2732 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2736 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737 if(surf_tex_rt32 && surf_offscreen64) {
2738 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2742 /* rendertarget texture ==> rendertarget texture, scaling */
2743 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2747 /* We can't lock rendertarget textures, so copy to our temp surface first */
2748 if (hr == D3D_OK) {
2749 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2753 if (hr == D3D_OK) {
2754 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2759 /* rendertarget texture ==> rendertarget surface, scaling */
2760 if(surf_tex_rt32 && surf_rt_dest64) {
2761 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2768 /* rendertarget texture ==> texture, scaling (should fail) */
2769 if(surf_tex_rt32 && surf_tex_dest64) {
2770 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2774 /*****************************************************************
2775 * Tests for when the source parameter is a rendertarget surface *
2776 *****************************************************************/
2778 /* Fill the surface of the rendertarget surface with black */
2779 if (surf_rt64)
2780 fill_surface(surf_rt64, 0xff000000);
2782 /* rendertarget texture ==> offscreenplain, same size */
2783 if(surf_rt64 && surf_offscreen64) {
2784 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2788 /* rendertarget surface ==> rendertarget texture, same size */
2789 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793 /* We can't lock rendertarget textures, so copy to our temp surface first */
2794 if (hr == D3D_OK) {
2795 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2799 if (hr == D3D_OK) {
2800 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2804 /* Blit without scaling */
2805 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2812 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2817 /* rendertarget surface ==> rendertarget surface, same size */
2818 if(surf_rt64 && surf_rt_dest64) {
2819 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2822 if (hr == D3D_OK) {
2823 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2827 /* Blit without scaling */
2828 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2831 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2840 /* rendertarget surface ==> texture, same size (should fail) */
2841 if(surf_rt64 && surf_tex_dest64) {
2842 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2846 /* Fill the surface of the smaller rendertarget texture with red */
2847 if (surf_rt32)
2848 fill_surface(surf_rt32, 0xffff0000);
2850 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851 if(surf_rt32 && surf_offscreen64) {
2852 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2856 /* rendertarget surface ==> rendertarget texture, scaling */
2857 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861 /* We can't lock rendertarget textures, so copy to our temp surface first */
2862 if (hr == D3D_OK) {
2863 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2867 if (hr == D3D_OK) {
2868 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2873 /* rendertarget surface ==> rendertarget surface, scaling */
2874 if(surf_rt32 && surf_rt_dest64) {
2875 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2882 /* rendertarget surface ==> texture, scaling (should fail) */
2883 if(surf_rt32 && surf_tex_dest64) {
2884 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2888 /* backbuffer ==> surface tests (no scaling) */
2889 if(backbuffer && surf_tex_rt_dest640_480)
2891 RECT src_rect = {0, 0, 640, 480};
2892 RECT src_rect_flipy = {0, 480, 640, 0};
2893 RECT dst_rect = {0, 0, 640, 480};
2894 RECT dst_rect_flipy = {0, 480, 640, 0};
2896 /* Blit with NULL rectangles */
2897 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2900 /* Blit without scaling */
2901 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2913 /* TODO: Test format conversions */
2916 out:
2917 /* Clean up */
2918 if (backbuffer)
2919 IDirect3DSurface9_Release(backbuffer);
2920 if (surf_rt32)
2921 IDirect3DSurface9_Release(surf_rt32);
2922 if (surf_rt64)
2923 IDirect3DSurface9_Release(surf_rt64);
2924 if (surf_rt_dest64)
2925 IDirect3DSurface9_Release(surf_rt_dest64);
2926 if (surf_temp32)
2927 IDirect3DSurface9_Release(surf_temp32);
2928 if (surf_temp64)
2929 IDirect3DSurface9_Release(surf_temp64);
2930 if (surf_offscreen32)
2931 IDirect3DSurface9_Release(surf_offscreen32);
2932 if (surf_offscreen64)
2933 IDirect3DSurface9_Release(surf_offscreen64);
2934 if (surf_offscreen_dest64)
2935 IDirect3DSurface9_Release(surf_offscreen_dest64);
2937 if (tex_rt32) {
2938 if (surf_tex_rt32)
2939 IDirect3DSurface9_Release(surf_tex_rt32);
2940 IDirect3DTexture9_Release(tex_rt32);
2942 if (tex_rt64) {
2943 if (surf_tex_rt64)
2944 IDirect3DSurface9_Release(surf_tex_rt64);
2945 IDirect3DTexture9_Release(tex_rt64);
2947 if (tex_rt_dest64) {
2948 if (surf_tex_rt_dest64)
2949 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950 IDirect3DTexture9_Release(tex_rt_dest64);
2952 if (tex_rt_dest640_480) {
2953 if (surf_tex_rt_dest640_480)
2954 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955 IDirect3DTexture9_Release(tex_rt_dest640_480);
2957 if (tex32) {
2958 if (surf_tex32)
2959 IDirect3DSurface9_Release(surf_tex32);
2960 IDirect3DTexture9_Release(tex32);
2962 if (tex64) {
2963 if (surf_tex64)
2964 IDirect3DSurface9_Release(surf_tex64);
2965 IDirect3DTexture9_Release(tex64);
2967 if (tex_dest64) {
2968 if (surf_tex_dest64)
2969 IDirect3DSurface9_Release(surf_tex_dest64);
2970 IDirect3DTexture9_Release(tex_dest64);
2973 if (orig_rt) {
2974 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976 IDirect3DSurface9_Release(orig_rt);
2980 static void maxmip_test(IDirect3DDevice9 *device)
2982 IDirect3DTexture9 *texture = NULL;
2983 IDirect3DSurface9 *surface = NULL;
2984 HRESULT hr;
2985 DWORD color;
2986 const float quads[] = {
2987 -1.0, -1.0, 0.0, 0.0, 0.0,
2988 -1.0, 0.0, 0.0, 0.0, 1.0,
2989 0.0, -1.0, 0.0, 1.0, 0.0,
2990 0.0, 0.0, 0.0, 1.0, 1.0,
2992 0.0, -1.0, 0.0, 0.0, 0.0,
2993 0.0, 0.0, 0.0, 0.0, 1.0,
2994 1.0, -1.0, 0.0, 1.0, 0.0,
2995 1.0, 0.0, 0.0, 1.0, 1.0,
2997 0.0, 0.0, 0.0, 0.0, 0.0,
2998 0.0, 1.0, 0.0, 0.0, 1.0,
2999 1.0, 0.0, 0.0, 1.0, 0.0,
3000 1.0, 1.0, 0.0, 1.0, 1.0,
3002 -1.0, 0.0, 0.0, 0.0, 0.0,
3003 -1.0, 1.0, 0.0, 0.0, 1.0,
3004 0.0, 0.0, 0.0, 1.0, 0.0,
3005 0.0, 1.0, 0.0, 1.0, 1.0,
3008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3011 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012 &texture, NULL);
3013 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014 if(!texture)
3016 skip("Failed to create test texture\n");
3017 return;
3020 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022 fill_surface(surface, 0xffff0000);
3023 IDirect3DSurface9_Release(surface);
3024 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026 fill_surface(surface, 0xff00ff00);
3027 IDirect3DSurface9_Release(surface);
3028 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030 fill_surface(surface, 0xff0000ff);
3031 IDirect3DSurface9_Release(surface);
3033 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3035 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3038 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3041 hr = IDirect3DDevice9_BeginScene(device);
3042 if(SUCCEEDED(hr))
3044 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3049 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3054 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3059 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063 hr = IDirect3DDevice9_EndScene(device);
3064 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3067 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068 color = getPixelColor(device, 160, 360);
3069 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070 color = getPixelColor(device, 160, 120);
3071 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072 color = getPixelColor(device, 480, 120);
3073 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074 color = getPixelColor(device, 480, 360);
3075 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3082 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3085 hr = IDirect3DDevice9_BeginScene(device);
3086 if(SUCCEEDED(hr))
3088 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3093 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3098 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3103 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107 hr = IDirect3DDevice9_EndScene(device);
3108 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3111 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112 * samples from the highest level in the texture(level 2)
3114 color = getPixelColor(device, 160, 360);
3115 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116 color = getPixelColor(device, 160, 120);
3117 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118 color = getPixelColor(device, 480, 120);
3119 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120 color = getPixelColor(device, 480, 360);
3121 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3125 hr = IDirect3DDevice9_BeginScene(device);
3126 if(SUCCEEDED(hr))
3128 DWORD ret;
3130 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3131 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3134 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135 ret = IDirect3DTexture9_SetLOD(texture, 1);
3136 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3140 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145 ret = IDirect3DTexture9_SetLOD(texture, 2);
3146 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3150 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153 ret = IDirect3DTexture9_SetLOD(texture, 1);
3154 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3158 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163 ret = IDirect3DTexture9_SetLOD(texture, 1);
3164 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167 hr = IDirect3DDevice9_EndScene(device);
3170 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171 * samples from the highest level in the texture(level 2)
3173 color = getPixelColor(device, 160, 360);
3174 ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175 color = getPixelColor(device, 160, 120);
3176 ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177 color = getPixelColor(device, 480, 120);
3178 ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179 color = getPixelColor(device, 480, 360);
3180 ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3184 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190 IDirect3DTexture9_Release(texture);
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3195 IDirect3DVertexBuffer9 *vb = NULL;
3196 IDirect3DIndexBuffer9 *ib = NULL;
3197 HRESULT hr;
3198 BYTE *data;
3199 LONG ref;
3201 static const struct vertex quad[] = {
3202 {-1.0, -1.0, 0.1, 0xffff0000},
3203 {-1.0, 1.0, 0.1, 0xffff0000},
3204 { 1.0, 1.0, 0.1, 0xffff0000},
3206 {-1.0, -1.0, 0.1, 0xff00ff00},
3207 {-1.0, 1.0, 0.1, 0xff00ff00},
3208 { 1.0, 1.0, 0.1, 0xff00ff00}
3210 short indices[] = {3, 4, 5};
3212 /* Index and vertex buffers should always be creatable */
3213 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214 D3DPOOL_MANAGED, &vb, NULL);
3215 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216 if(!vb) {
3217 skip("Failed to create a vertex buffer\n");
3218 return;
3220 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222 if(!ib) {
3223 skip("Failed to create an index buffer\n");
3224 return;
3227 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229 memcpy(data, quad, sizeof(quad));
3230 hr = IDirect3DVertexBuffer9_Unlock(vb);
3231 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3233 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235 memcpy(data, indices, sizeof(indices));
3236 hr = IDirect3DIndexBuffer9_Unlock(ib);
3237 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3239 hr = IDirect3DDevice9_SetIndices(device, ib);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3246 /* Now destroy the bound index buffer and draw again */
3247 ref = IDirect3DIndexBuffer9_Release(ib);
3248 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3253 hr = IDirect3DDevice9_BeginScene(device);
3254 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255 if(SUCCEEDED(hr))
3257 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258 * making assumptions about the indices or vertices
3260 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262 hr = IDirect3DDevice9_EndScene(device);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3266 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3269 hr = IDirect3DDevice9_SetIndices(device, NULL);
3270 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3274 /* Index buffer was already destroyed as part of the test */
3275 IDirect3DVertexBuffer9_Release(vb);
3278 static void float_texture_test(IDirect3DDevice9 *device)
3280 IDirect3D9 *d3d = NULL;
3281 HRESULT hr;
3282 IDirect3DTexture9 *texture = NULL;
3283 D3DLOCKED_RECT lr;
3284 float *data;
3285 DWORD color;
3286 float quad[] = {
3287 -1.0, -1.0, 0.1, 0.0, 0.0,
3288 -1.0, 1.0, 0.1, 0.0, 1.0,
3289 1.0, -1.0, 0.1, 1.0, 0.0,
3290 1.0, 1.0, 0.1, 1.0, 1.0,
3293 memset(&lr, 0, sizeof(lr));
3294 IDirect3DDevice9_GetDirect3D(device, &d3d);
3295 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297 skip("D3DFMT_R32F textures not supported\n");
3298 goto out;
3301 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302 D3DPOOL_MANAGED, &texture, NULL);
3303 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304 if(!texture) {
3305 skip("Failed to create R32F texture\n");
3306 goto out;
3309 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311 data = lr.pBits;
3312 *data = 0.0;
3313 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3316 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3319 hr = IDirect3DDevice9_BeginScene(device);
3320 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321 if(SUCCEEDED(hr))
3323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3329 hr = IDirect3DDevice9_EndScene(device);
3330 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3332 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3335 color = getPixelColor(device, 240, 320);
3336 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3338 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3341 out:
3342 if(texture) IDirect3DTexture9_Release(texture);
3343 IDirect3D9_Release(d3d);
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3348 IDirect3D9 *d3d = NULL;
3349 HRESULT hr;
3350 IDirect3DTexture9 *texture = NULL;
3351 D3DLOCKED_RECT lr;
3352 DWORD *data;
3353 DWORD color;
3354 float quad[] = {
3355 -1.0, -1.0, 0.1, 0.0, 0.0,
3356 -1.0, 1.0, 0.1, 0.0, 1.0,
3357 1.0, -1.0, 0.1, 1.0, 0.0,
3358 1.0, 1.0, 0.1, 1.0, 1.0,
3361 memset(&lr, 0, sizeof(lr));
3362 IDirect3DDevice9_GetDirect3D(device, &d3d);
3363 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365 skip("D3DFMT_G16R16 textures not supported\n");
3366 goto out;
3369 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370 D3DPOOL_MANAGED, &texture, NULL);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372 if(!texture) {
3373 skip("Failed to create D3DFMT_G16R16 texture\n");
3374 goto out;
3377 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379 data = lr.pBits;
3380 *data = 0x0f00f000;
3381 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3384 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3387 hr = IDirect3DDevice9_BeginScene(device);
3388 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389 if(SUCCEEDED(hr))
3391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3397 hr = IDirect3DDevice9_EndScene(device);
3398 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3400 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3403 color = getPixelColor(device, 240, 320);
3404 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3410 out:
3411 if(texture) IDirect3DTexture9_Release(texture);
3412 IDirect3D9_Release(d3d);
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3417 HRESULT hr;
3418 IDirect3D9 *d3d;
3419 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420 D3DCAPS9 caps;
3421 IDirect3DTexture9 *texture = NULL;
3422 IDirect3DVolumeTexture9 *volume = NULL;
3423 unsigned int x, y, z;
3424 D3DLOCKED_RECT lr;
3425 D3DLOCKED_BOX lb;
3426 DWORD color;
3427 UINT w, h;
3428 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430 0.0, 1.0, 0.0, 0.0,
3431 0.0, 0.0, 1.0, 0.0,
3432 0.0, 0.0, 0.0, 1.0};
3433 static const D3DVERTEXELEMENT9 decl_elements[] = {
3434 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436 D3DDECL_END()
3438 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441 D3DDECL_END()
3443 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446 D3DDECL_END()
3448 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449 0x00, 0xff, 0x00, 0x00,
3450 0x00, 0x00, 0x00, 0x00,
3451 0x00, 0x00, 0x00, 0x00};
3453 memset(&lr, 0, sizeof(lr));
3454 memset(&lb, 0, sizeof(lb));
3455 IDirect3DDevice9_GetDirect3D(device, &d3d);
3456 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458 fmt = D3DFMT_A16B16G16R16;
3460 IDirect3D9_Release(d3d);
3462 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3487 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489 w = min(1024, caps.MaxTextureWidth);
3490 h = min(1024, caps.MaxTextureHeight);
3491 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494 if(!texture) {
3495 skip("Failed to create the test texture\n");
3496 return;
3499 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501 * 1.0 in red and green for the x and y coords
3503 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505 for(y = 0; y < h; y++) {
3506 for(x = 0; x < w; x++) {
3507 double r_f = (double) y / (double) h;
3508 double g_f = (double) x / (double) w;
3509 if(fmt == D3DFMT_A16B16G16R16) {
3510 unsigned short r, g;
3511 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512 r = (unsigned short) (r_f * 65536.0);
3513 g = (unsigned short) (g_f * 65536.0);
3514 dst[0] = r;
3515 dst[1] = g;
3516 dst[2] = 0;
3517 dst[3] = 65535;
3518 } else {
3519 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520 unsigned char r = (unsigned char) (r_f * 255.0);
3521 unsigned char g = (unsigned char) (g_f * 255.0);
3522 dst[0] = 0;
3523 dst[1] = g;
3524 dst[2] = r;
3525 dst[3] = 255;
3529 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3534 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536 hr = IDirect3DDevice9_BeginScene(device);
3537 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538 if(SUCCEEDED(hr))
3540 float quad1[] = {
3541 -1.0, -1.0, 0.1, 1.0, 1.0,
3542 -1.0, 0.0, 0.1, 1.0, 1.0,
3543 0.0, -1.0, 0.1, 1.0, 1.0,
3544 0.0, 0.0, 0.1, 1.0, 1.0,
3546 float quad2[] = {
3547 -1.0, 0.0, 0.1, 1.0, 1.0,
3548 -1.0, 1.0, 0.1, 1.0, 1.0,
3549 0.0, 0.0, 0.1, 1.0, 1.0,
3550 0.0, 1.0, 0.1, 1.0, 1.0,
3552 float quad3[] = {
3553 0.0, 0.0, 0.1, 0.5, 0.5,
3554 0.0, 1.0, 0.1, 0.5, 0.5,
3555 1.0, 0.0, 0.1, 0.5, 0.5,
3556 1.0, 1.0, 0.1, 0.5, 0.5,
3558 float quad4[] = {
3559 320, 480, 0.1, 1.0, 0.0, 1.0,
3560 320, 240, 0.1, 1.0, 0.0, 1.0,
3561 640, 480, 0.1, 1.0, 0.0, 1.0,
3562 640, 240, 0.1, 1.0, 0.0, 1.0,
3564 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565 0.0, 0.0, 0.0, 0.0,
3566 0.0, 0.0, 0.0, 0.0,
3567 0.0, 0.0, 0.0, 0.0};
3569 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3575 /* What happens with transforms enabled? */
3576 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3581 /* What happens if 4 coords are used, but only 2 given ?*/
3582 mat[8] = 1.0;
3583 mat[13] = 1.0;
3584 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3591 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593 * due to the coords in the vertices. (turns out red, indeed)
3595 memset(mat, 0, sizeof(mat));
3596 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3605 hr = IDirect3DDevice9_EndScene(device);
3606 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3608 color = getPixelColor(device, 160, 360);
3609 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610 color = getPixelColor(device, 160, 120);
3611 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612 color = getPixelColor(device, 480, 120);
3613 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614 color = getPixelColor(device, 480, 360);
3615 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3619 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3622 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624 hr = IDirect3DDevice9_BeginScene(device);
3625 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626 if(SUCCEEDED(hr))
3628 float quad1[] = {
3629 -1.0, -1.0, 0.1, 0.8, 0.2,
3630 -1.0, 0.0, 0.1, 0.8, 0.2,
3631 0.0, -1.0, 0.1, 0.8, 0.2,
3632 0.0, 0.0, 0.1, 0.8, 0.2,
3634 float quad2[] = {
3635 -1.0, 0.0, 0.1, 0.5, 1.0,
3636 -1.0, 1.0, 0.1, 0.5, 1.0,
3637 0.0, 0.0, 0.1, 0.5, 1.0,
3638 0.0, 1.0, 0.1, 0.5, 1.0,
3640 float quad3[] = {
3641 0.0, 0.0, 0.1, 0.5, 1.0,
3642 0.0, 1.0, 0.1, 0.5, 1.0,
3643 1.0, 0.0, 0.1, 0.5, 1.0,
3644 1.0, 1.0, 0.1, 0.5, 1.0,
3646 float quad4[] = {
3647 0.0, -1.0, 0.1, 0.8, 0.2,
3648 0.0, 0.0, 0.1, 0.8, 0.2,
3649 1.0, -1.0, 0.1, 0.8, 0.2,
3650 1.0, 0.0, 0.1, 0.8, 0.2,
3652 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653 0.0, 0.0, 0.0, 0.0,
3654 0.0, 1.0, 0.0, 0.0,
3655 0.0, 0.0, 0.0, 0.0};
3657 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3659 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3667 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668 * it behaves like COUNT2 because normal textures require 2 coords
3670 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3675 /* Just to be sure, the same as quad2 above */
3676 memset(mat, 0, sizeof(mat));
3677 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3684 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685 * used? And what happens to the first?
3687 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3692 hr = IDirect3DDevice9_EndScene(device);
3693 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3695 color = getPixelColor(device, 160, 360);
3696 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697 color = getPixelColor(device, 160, 120);
3698 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699 color = getPixelColor(device, 480, 120);
3700 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702 color = getPixelColor(device, 480, 360);
3703 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3708 IDirect3DTexture9_Release(texture);
3710 /* Test projected textures, without any fancy matrices */
3711 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3720 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722 for(x = 0; x < 4; x++) {
3723 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3725 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3730 hr = IDirect3DDevice9_BeginScene(device);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732 if(SUCCEEDED(hr))
3734 const float proj_quads[] = {
3735 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3736 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3737 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3738 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3739 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3740 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3741 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3742 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3745 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3750 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3755 hr = IDirect3DDevice9_EndScene(device);
3756 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3759 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761 IDirect3DTexture9_Release(texture);
3763 color = getPixelColor(device, 158, 118);
3764 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765 color = getPixelColor(device, 162, 118);
3766 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767 color = getPixelColor(device, 158, 122);
3768 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769 color = getPixelColor(device, 162, 122);
3770 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3772 color = getPixelColor(device, 158, 178);
3773 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774 color = getPixelColor(device, 162, 178);
3775 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776 color = getPixelColor(device, 158, 182);
3777 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778 color = getPixelColor(device, 162, 182);
3779 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3781 color = getPixelColor(device, 318, 118);
3782 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783 color = getPixelColor(device, 322, 118);
3784 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785 color = getPixelColor(device, 318, 122);
3786 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787 color = getPixelColor(device, 322, 122);
3788 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3790 color = getPixelColor(device, 318, 178);
3791 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792 color = getPixelColor(device, 322, 178);
3793 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794 color = getPixelColor(device, 318, 182);
3795 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796 color = getPixelColor(device, 322, 182);
3797 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3799 color = getPixelColor(device, 238, 298);
3800 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801 color = getPixelColor(device, 242, 298);
3802 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803 color = getPixelColor(device, 238, 302);
3804 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805 color = getPixelColor(device, 242, 302);
3806 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3808 color = getPixelColor(device, 238, 388);
3809 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810 color = getPixelColor(device, 242, 388);
3811 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812 color = getPixelColor(device, 238, 392);
3813 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814 color = getPixelColor(device, 242, 392);
3815 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3817 color = getPixelColor(device, 478, 298);
3818 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819 color = getPixelColor(device, 482, 298);
3820 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821 color = getPixelColor(device, 478, 302);
3822 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823 color = getPixelColor(device, 482, 302);
3824 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3826 color = getPixelColor(device, 478, 388);
3827 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828 color = getPixelColor(device, 482, 388);
3829 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830 color = getPixelColor(device, 478, 392);
3831 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832 color = getPixelColor(device, 482, 392);
3833 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3835 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841 * Thus watch out if sampling from texels between 0 and 1.
3843 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846 if(!volume) {
3847 skip("Failed to create a volume texture\n");
3848 goto out;
3851 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853 for(z = 0; z < 32; z++) {
3854 for(y = 0; y < 32; y++) {
3855 for(x = 0; x < 32; x++) {
3856 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858 float r_f = (float) x / 31.0;
3859 float g_f = (float) y / 31.0;
3860 float b_f = (float) z / 31.0;
3862 if(fmt == D3DFMT_A16B16G16R16) {
3863 unsigned short *mem_s = mem;
3864 mem_s[0] = r_f * 65535.0;
3865 mem_s[1] = g_f * 65535.0;
3866 mem_s[2] = b_f * 65535.0;
3867 mem_s[3] = 65535;
3868 } else {
3869 unsigned char *mem_c = mem;
3870 mem_c[0] = b_f * 255.0;
3871 mem_c[1] = g_f * 255.0;
3872 mem_c[2] = r_f * 255.0;
3873 mem_c[3] = 255;
3878 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3881 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3884 hr = IDirect3DDevice9_BeginScene(device);
3885 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886 if(SUCCEEDED(hr))
3888 float quad1[] = {
3889 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3890 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3891 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3892 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3894 float quad2[] = {
3895 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3896 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3897 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3898 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3900 float quad3[] = {
3901 0.0, 0.0, 0.1, 0.0, 0.0,
3902 0.0, 1.0, 0.1, 0.0, 0.0,
3903 1.0, 0.0, 0.1, 0.0, 0.0,
3904 1.0, 1.0, 0.1, 0.0, 0.0
3906 float quad4[] = {
3907 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3908 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3909 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3910 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3912 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913 0.0, 0.0, 1.0, 0.0,
3914 0.0, 1.0, 0.0, 0.0,
3915 0.0, 0.0, 0.0, 1.0};
3916 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3919 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920 * values
3922 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3929 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931 * otherwise the w will be missing(blue).
3932 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3935 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3940 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3941 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3950 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951 * disable. ATI extends it up to the amount of values needed for the volume texture
3953 memset(mat, 0, sizeof(mat));
3954 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3963 hr = IDirect3DDevice9_EndScene(device);
3964 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3967 color = getPixelColor(device, 160, 360);
3968 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969 color = getPixelColor(device, 160, 120);
3970 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972 color = getPixelColor(device, 480, 120);
3973 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974 color = getPixelColor(device, 480, 360);
3975 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982 hr = IDirect3DDevice9_BeginScene(device);
3983 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984 if(SUCCEEDED(hr))
3986 float quad1[] = {
3987 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3988 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3989 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3990 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3992 float quad2[] = {
3993 -1.0, 0.0, 0.1,
3994 -1.0, 1.0, 0.1,
3995 0.0, 0.0, 0.1,
3996 0.0, 1.0, 0.1,
3998 float quad3[] = {
3999 0.0, 0.0, 0.1, 1.0,
4000 0.0, 1.0, 0.1, 1.0,
4001 1.0, 0.0, 0.1, 1.0,
4002 1.0, 1.0, 0.1, 1.0
4004 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4005 0.0, 0.0, 0.0, 0.0,
4006 0.0, 0.0, 0.0, 0.0,
4007 0.0, 1.0, 0.0, 0.0};
4008 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009 1.0, 0.0, 0.0, 0.0,
4010 0.0, 1.0, 0.0, 0.0,
4011 0.0, 0.0, 1.0, 0.0};
4012 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4015 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4017 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4019 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4020 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4021 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4022 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4024 /* None passed */
4025 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4026 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4027 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4028 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4030 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4032 /* 4 used, 1 passed */
4033 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4034 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4035 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4036 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4038 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4040 hr = IDirect3DDevice9_EndScene(device);
4041 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4043 color = getPixelColor(device, 160, 360);
4044 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4045 color = getPixelColor(device, 160, 120);
4046 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4047 color = getPixelColor(device, 480, 120);
4048 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4049 /* Quad4: unused */
4051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4052 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4054 IDirect3DVolumeTexture9_Release(volume);
4056 out:
4057 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4058 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4059 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4060 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4061 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4062 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4063 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4064 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4065 IDirect3DVertexDeclaration9_Release(decl);
4066 IDirect3DVertexDeclaration9_Release(decl2);
4067 IDirect3DVertexDeclaration9_Release(decl3);
4070 static void texdepth_test(IDirect3DDevice9 *device)
4072 IDirect3DPixelShader9 *shader;
4073 HRESULT hr;
4074 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4075 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4076 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4077 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4078 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4079 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4080 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4081 DWORD shader_code[] = {
4082 0xffff0104, /* ps_1_4 */
4083 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4084 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4085 0x0000fffd, /* phase */
4086 0x00000057, 0x800f0005, /* texdepth r5 */
4087 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4088 0x0000ffff /* end */
4090 DWORD color;
4091 float vertex[] = {
4092 -1.0, -1.0, 0.0,
4093 1.0, -1.0, 1.0,
4094 -1.0, 1.0, 0.0,
4095 1.0, 1.0, 1.0
4098 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4099 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4101 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4102 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4104 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4108 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4110 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4112 /* Fill the depth buffer with a gradient */
4113 hr = IDirect3DDevice9_BeginScene(device);
4114 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4115 if(SUCCEEDED(hr))
4117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4118 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4119 hr = IDirect3DDevice9_EndScene(device);
4120 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4123 /* Now perform the actual tests. Same geometry, but with the shader */
4124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4128 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4129 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4131 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4132 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4133 hr = IDirect3DDevice9_BeginScene(device);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4135 if(SUCCEEDED(hr))
4137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4138 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4140 hr = IDirect3DDevice9_EndScene(device);
4141 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4144 color = getPixelColor(device, 158, 240);
4145 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4146 color = getPixelColor(device, 162, 240);
4147 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4149 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4152 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4153 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4155 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4156 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4157 hr = IDirect3DDevice9_BeginScene(device);
4158 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4159 if(SUCCEEDED(hr))
4161 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4162 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4164 hr = IDirect3DDevice9_EndScene(device);
4165 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4168 color = getPixelColor(device, 318, 240);
4169 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4170 color = getPixelColor(device, 322, 240);
4171 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4174 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4176 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4177 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4179 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4180 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4181 hr = IDirect3DDevice9_BeginScene(device);
4182 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4183 if(SUCCEEDED(hr))
4185 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4186 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4188 hr = IDirect3DDevice9_EndScene(device);
4189 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4192 color = getPixelColor(device, 1, 240);
4193 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4195 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4196 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4198 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4199 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4201 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4202 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4203 hr = IDirect3DDevice9_BeginScene(device);
4204 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4205 if(SUCCEEDED(hr))
4207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4208 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4210 hr = IDirect3DDevice9_EndScene(device);
4211 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4213 color = getPixelColor(device, 318, 240);
4214 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4215 color = getPixelColor(device, 322, 240);
4216 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4218 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4222 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4224 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4225 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4226 hr = IDirect3DDevice9_BeginScene(device);
4227 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4228 if(SUCCEEDED(hr))
4230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4231 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4233 hr = IDirect3DDevice9_EndScene(device);
4234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4237 color = getPixelColor(device, 1, 240);
4238 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4240 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4241 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4243 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4244 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4246 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4247 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4248 hr = IDirect3DDevice9_BeginScene(device);
4249 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4250 if(SUCCEEDED(hr))
4252 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4253 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4255 hr = IDirect3DDevice9_EndScene(device);
4256 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4259 color = getPixelColor(device, 638, 240);
4260 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4262 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4266 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4268 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4269 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4270 hr = IDirect3DDevice9_BeginScene(device);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4272 if(SUCCEEDED(hr))
4274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4275 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4277 hr = IDirect3DDevice9_EndScene(device);
4278 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4281 color = getPixelColor(device, 638, 240);
4282 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4285 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4287 /* Cleanup */
4288 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4290 IDirect3DPixelShader9_Release(shader);
4292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4298 static void texkill_test(IDirect3DDevice9 *device)
4300 IDirect3DPixelShader9 *shader;
4301 HRESULT hr;
4302 DWORD color;
4304 const float vertex[] = {
4305 /* bottom top right left */
4306 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4307 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4308 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4309 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4312 DWORD shader_code_11[] = {
4313 0xffff0101, /* ps_1_1 */
4314 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4315 0x00000041, 0xb00f0000, /* texkill t0 */
4316 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4317 0x0000ffff /* end */
4319 DWORD shader_code_20[] = {
4320 0xffff0200, /* ps_2_0 */
4321 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4322 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4323 0x01000041, 0xb00f0000, /* texkill t0 */
4324 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4325 0x0000ffff /* end */
4328 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4329 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4330 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4331 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4333 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4334 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4335 hr = IDirect3DDevice9_BeginScene(device);
4336 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4337 if(SUCCEEDED(hr))
4339 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4340 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4341 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4342 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4343 hr = IDirect3DDevice9_EndScene(device);
4344 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4346 color = getPixelColor(device, 63, 46);
4347 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4348 color = getPixelColor(device, 66, 46);
4349 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4350 color = getPixelColor(device, 63, 49);
4351 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4352 color = getPixelColor(device, 66, 49);
4353 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4355 color = getPixelColor(device, 578, 46);
4356 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4357 color = getPixelColor(device, 575, 46);
4358 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4359 color = getPixelColor(device, 578, 49);
4360 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4361 color = getPixelColor(device, 575, 49);
4362 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4364 color = getPixelColor(device, 63, 430);
4365 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4366 color = getPixelColor(device, 63, 433);
4367 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4368 color = getPixelColor(device, 66, 433);
4369 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4370 color = getPixelColor(device, 66, 430);
4371 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4373 color = getPixelColor(device, 578, 430);
4374 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4375 color = getPixelColor(device, 578, 433);
4376 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4377 color = getPixelColor(device, 575, 433);
4378 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4379 color = getPixelColor(device, 575, 430);
4380 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4382 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4383 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4385 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4387 IDirect3DPixelShader9_Release(shader);
4389 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4391 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4392 if(FAILED(hr)) {
4393 skip("Failed to create 2.0 test shader, most likely not supported\n");
4394 return;
4397 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4398 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4399 hr = IDirect3DDevice9_BeginScene(device);
4400 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4401 if(SUCCEEDED(hr))
4403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4404 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4405 hr = IDirect3DDevice9_EndScene(device);
4406 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4409 color = getPixelColor(device, 63, 46);
4410 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4411 color = getPixelColor(device, 66, 46);
4412 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4413 color = getPixelColor(device, 63, 49);
4414 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4415 color = getPixelColor(device, 66, 49);
4416 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4418 color = getPixelColor(device, 578, 46);
4419 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4420 color = getPixelColor(device, 575, 46);
4421 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4422 color = getPixelColor(device, 578, 49);
4423 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4424 color = getPixelColor(device, 575, 49);
4425 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4427 color = getPixelColor(device, 63, 430);
4428 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4429 color = getPixelColor(device, 63, 433);
4430 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4431 color = getPixelColor(device, 66, 433);
4432 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4433 color = getPixelColor(device, 66, 430);
4434 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4436 color = getPixelColor(device, 578, 430);
4437 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4438 color = getPixelColor(device, 578, 433);
4439 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4440 color = getPixelColor(device, 575, 433);
4441 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4442 color = getPixelColor(device, 575, 430);
4443 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4448 /* Cleanup */
4449 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4450 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4451 IDirect3DPixelShader9_Release(shader);
4454 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4456 IDirect3D9 *d3d9;
4457 HRESULT hr;
4458 IDirect3DTexture9 *texture;
4459 IDirect3DPixelShader9 *shader;
4460 IDirect3DPixelShader9 *shader2;
4461 D3DLOCKED_RECT lr;
4462 DWORD color;
4463 DWORD shader_code[] = {
4464 0xffff0101, /* ps_1_1 */
4465 0x00000042, 0xb00f0000, /* tex t0 */
4466 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4467 0x0000ffff /* end */
4469 DWORD shader_code2[] = {
4470 0xffff0101, /* ps_1_1 */
4471 0x00000042, 0xb00f0000, /* tex t0 */
4472 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4473 0x0000ffff /* end */
4476 float quad[] = {
4477 -1.0, -1.0, 0.1, 0.5, 0.5,
4478 1.0, -1.0, 0.1, 0.5, 0.5,
4479 -1.0, 1.0, 0.1, 0.5, 0.5,
4480 1.0, 1.0, 0.1, 0.5, 0.5,
4483 memset(&lr, 0, sizeof(lr));
4484 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4485 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4486 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4487 IDirect3D9_Release(d3d9);
4488 if(FAILED(hr)) {
4489 skip("No D3DFMT_X8L8V8U8 support\n");
4490 return;
4493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4496 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4497 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4498 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4499 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4500 *((DWORD *) lr.pBits) = 0x11ca3141;
4501 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4502 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4504 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4505 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4506 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4507 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4509 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4510 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4511 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4512 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4513 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4514 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4516 hr = IDirect3DDevice9_BeginScene(device);
4517 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4518 if(SUCCEEDED(hr))
4520 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4521 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4523 hr = IDirect3DDevice9_EndScene(device);
4524 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4526 color = getPixelColor(device, 578, 430);
4527 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4528 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4529 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4532 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4534 hr = IDirect3DDevice9_BeginScene(device);
4535 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4536 if(SUCCEEDED(hr))
4538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4539 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4541 hr = IDirect3DDevice9_EndScene(device);
4542 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4544 color = getPixelColor(device, 578, 430);
4545 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4546 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4549 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4550 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4551 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4553 IDirect3DPixelShader9_Release(shader);
4554 IDirect3DPixelShader9_Release(shader2);
4555 IDirect3DTexture9_Release(texture);
4558 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4560 HRESULT hr;
4561 IDirect3D9 *d3d;
4562 IDirect3DTexture9 *texture = NULL;
4563 IDirect3DSurface9 *surface;
4564 DWORD color;
4565 const RECT r1 = {256, 256, 512, 512};
4566 const RECT r2 = {512, 256, 768, 512};
4567 const RECT r3 = {256, 512, 512, 768};
4568 const RECT r4 = {512, 512, 768, 768};
4569 unsigned int x, y;
4570 D3DLOCKED_RECT lr;
4571 memset(&lr, 0, sizeof(lr));
4573 IDirect3DDevice9_GetDirect3D(device, &d3d);
4574 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4575 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4576 skip("No autogenmipmap support\n");
4577 IDirect3D9_Release(d3d);
4578 return;
4580 IDirect3D9_Release(d3d);
4582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4583 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4585 /* Make the mipmap big, so that a smaller mipmap is used
4587 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4588 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4589 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4591 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4592 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4593 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4594 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4595 for(y = 0; y < 1024; y++) {
4596 for(x = 0; x < 1024; x++) {
4597 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4598 POINT pt;
4600 pt.x = x;
4601 pt.y = y;
4602 if(PtInRect(&r1, pt)) {
4603 *dst = 0xffff0000;
4604 } else if(PtInRect(&r2, pt)) {
4605 *dst = 0xff00ff00;
4606 } else if(PtInRect(&r3, pt)) {
4607 *dst = 0xff0000ff;
4608 } else if(PtInRect(&r4, pt)) {
4609 *dst = 0xff000000;
4610 } else {
4611 *dst = 0xffffffff;
4615 hr = IDirect3DSurface9_UnlockRect(surface);
4616 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4617 IDirect3DSurface9_Release(surface);
4619 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4620 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4621 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4622 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4624 hr = IDirect3DDevice9_BeginScene(device);
4625 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4626 if(SUCCEEDED(hr)) {
4627 const float quad[] = {
4628 -0.5, -0.5, 0.1, 0.0, 0.0,
4629 -0.5, 0.5, 0.1, 0.0, 1.0,
4630 0.5, -0.5, 0.1, 1.0, 0.0,
4631 0.5, 0.5, 0.1, 1.0, 1.0
4634 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4635 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4637 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4638 hr = IDirect3DDevice9_EndScene(device);
4639 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4641 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4642 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4643 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4644 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4645 IDirect3DTexture9_Release(texture);
4647 color = getPixelColor(device, 200, 200);
4648 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4649 color = getPixelColor(device, 280, 200);
4650 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4651 color = getPixelColor(device, 360, 200);
4652 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4653 color = getPixelColor(device, 440, 200);
4654 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4655 color = getPixelColor(device, 200, 270);
4656 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4657 color = getPixelColor(device, 280, 270);
4658 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4659 color = getPixelColor(device, 360, 270);
4660 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4661 color = getPixelColor(device, 440, 270);
4662 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4663 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4664 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4667 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4669 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4670 IDirect3DVertexDeclaration9 *decl;
4671 HRESULT hr;
4672 DWORD color;
4673 DWORD shader_code_11[] = {
4674 0xfffe0101, /* vs_1_1 */
4675 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4676 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4677 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4678 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4679 0x0000ffff /* end */
4681 DWORD shader_code_11_2[] = {
4682 0xfffe0101, /* vs_1_1 */
4683 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4684 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4685 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4686 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4687 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4688 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4689 0x0000ffff /* end */
4691 DWORD shader_code_20[] = {
4692 0xfffe0200, /* vs_2_0 */
4693 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4694 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4695 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4696 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4697 0x0000ffff /* end */
4699 DWORD shader_code_20_2[] = {
4700 0xfffe0200, /* vs_2_0 */
4701 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4702 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4703 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4704 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4705 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4706 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4707 0x0000ffff /* end */
4709 static const D3DVERTEXELEMENT9 decl_elements[] = {
4710 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4711 D3DDECL_END()
4713 float quad1[] = {
4714 -1.0, -1.0, 0.1,
4715 0.0, -1.0, 0.1,
4716 -1.0, 0.0, 0.1,
4717 0.0, 0.0, 0.1
4719 float quad2[] = {
4720 0.0, -1.0, 0.1,
4721 1.0, -1.0, 0.1,
4722 0.0, 0.0, 0.1,
4723 1.0, 0.0, 0.1
4725 float quad3[] = {
4726 0.0, 0.0, 0.1,
4727 1.0, 0.0, 0.1,
4728 0.0, 1.0, 0.1,
4729 1.0, 1.0, 0.1
4731 float quad4[] = {
4732 -1.0, 0.0, 0.1,
4733 0.0, 0.0, 0.1,
4734 -1.0, 1.0, 0.1,
4735 0.0, 1.0, 0.1
4737 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4738 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4740 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4741 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4743 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4744 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4745 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4746 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4747 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4748 if(FAILED(hr)) shader_20 = NULL;
4749 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4750 if(FAILED(hr)) shader_20_2 = NULL;
4751 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4754 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4755 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4756 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4757 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4758 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4761 hr = IDirect3DDevice9_BeginScene(device);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4763 if(SUCCEEDED(hr))
4765 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4766 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4768 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4770 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4773 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4775 if(shader_20) {
4776 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4777 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4779 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4782 if(shader_20_2) {
4783 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4784 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4786 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4789 hr = IDirect3DDevice9_EndScene(device);
4790 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4793 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4795 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4798 color = getPixelColor(device, 160, 360);
4799 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4800 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4801 color = getPixelColor(device, 480, 360);
4802 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4803 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4804 if(shader_20) {
4805 color = getPixelColor(device, 160, 120);
4806 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4809 if(shader_20_2) {
4810 color = getPixelColor(device, 480, 120);
4811 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4812 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4814 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4815 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4817 IDirect3DVertexDeclaration9_Release(decl);
4818 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4819 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4820 IDirect3DVertexShader9_Release(shader_11_2);
4821 IDirect3DVertexShader9_Release(shader_11);
4824 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4826 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4827 HRESULT hr;
4828 DWORD color;
4829 DWORD shader_code_11[] = {
4830 0xffff0101, /* ps_1_1 */
4831 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4832 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4833 0x0000ffff /* end */
4835 DWORD shader_code_12[] = {
4836 0xffff0102, /* ps_1_2 */
4837 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4838 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4839 0x0000ffff /* end */
4841 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4842 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4843 * During development of this test, 1.3 shaders were verified too
4845 DWORD shader_code_14[] = {
4846 0xffff0104, /* ps_1_4 */
4847 /* Try to make one constant local. It gets clamped too, although the binary contains
4848 * the bigger numbers
4850 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4851 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4852 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4853 0x0000ffff /* end */
4855 DWORD shader_code_20[] = {
4856 0xffff0200, /* ps_2_0 */
4857 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4858 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4859 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4860 0x0000ffff /* end */
4862 float quad1[] = {
4863 -1.0, -1.0, 0.1,
4864 0.0, -1.0, 0.1,
4865 -1.0, 0.0, 0.1,
4866 0.0, 0.0, 0.1
4868 float quad2[] = {
4869 0.0, -1.0, 0.1,
4870 1.0, -1.0, 0.1,
4871 0.0, 0.0, 0.1,
4872 1.0, 0.0, 0.1
4874 float quad3[] = {
4875 0.0, 0.0, 0.1,
4876 1.0, 0.0, 0.1,
4877 0.0, 1.0, 0.1,
4878 1.0, 1.0, 0.1
4880 float quad4[] = {
4881 -1.0, 0.0, 0.1,
4882 0.0, 0.0, 0.1,
4883 -1.0, 1.0, 0.1,
4884 0.0, 1.0, 0.1
4886 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4887 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4889 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4890 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4892 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4893 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4894 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4895 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4896 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4897 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4899 if(FAILED(hr)) shader_20 = NULL;
4901 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4902 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4903 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4904 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4905 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4906 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4908 hr = IDirect3DDevice9_BeginScene(device);
4909 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4910 if(SUCCEEDED(hr))
4912 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4915 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4917 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4918 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4920 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4922 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4923 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4925 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4927 if(shader_20) {
4928 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4929 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4931 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4934 hr = IDirect3DDevice9_EndScene(device);
4935 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4937 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4938 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4940 color = getPixelColor(device, 160, 360);
4941 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4942 "quad 1 has color %08x, expected 0x00808000\n", color);
4943 color = getPixelColor(device, 480, 360);
4944 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4945 "quad 2 has color %08x, expected 0x00808000\n", color);
4946 color = getPixelColor(device, 480, 120);
4947 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4948 "quad 3 has color %08x, expected 0x00808000\n", color);
4949 if(shader_20) {
4950 color = getPixelColor(device, 160, 120);
4951 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4952 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4954 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4957 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4958 IDirect3DPixelShader9_Release(shader_14);
4959 IDirect3DPixelShader9_Release(shader_12);
4960 IDirect3DPixelShader9_Release(shader_11);
4963 static void dp2add_ps_test(IDirect3DDevice9 *device)
4965 IDirect3DPixelShader9 *shader_dp2add = NULL;
4966 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4967 HRESULT hr;
4968 DWORD color;
4970 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4971 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4972 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4973 * r0 first.
4974 * The result here for the r,g,b components should be roughly 0.5:
4975 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4976 static const DWORD shader_code_dp2add[] = {
4977 0xffff0200, /* ps_2_0 */
4978 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4980 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4981 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4983 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4984 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4985 0x0000ffff /* end */
4988 /* Test the _sat modifier, too. Result here should be:
4989 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4990 * _SAT: ==> 1.0
4991 * ADD: (1.0 + -0.5) = 0.5
4993 static const DWORD shader_code_dp2add_sat[] = {
4994 0xffff0200, /* ps_2_0 */
4995 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4997 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4998 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4999 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5001 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5002 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5003 0x0000ffff /* end */
5006 const float quad[] = {
5007 -1.0, -1.0, 0.1,
5008 1.0, -1.0, 0.1,
5009 -1.0, 1.0, 0.1,
5010 1.0, 1.0, 0.1
5014 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5015 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5017 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5018 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5020 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5021 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5023 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5024 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5026 if (shader_dp2add) {
5028 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5029 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5031 hr = IDirect3DDevice9_BeginScene(device);
5032 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5033 if(SUCCEEDED(hr))
5035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5036 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5038 hr = IDirect3DDevice9_EndScene(device);
5039 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5042 color = getPixelColor(device, 360, 240);
5043 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5044 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5046 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5047 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5049 IDirect3DPixelShader9_Release(shader_dp2add);
5050 } else {
5051 skip("dp2add shader creation failed\n");
5054 if (shader_dp2add_sat) {
5056 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5057 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5059 hr = IDirect3DDevice9_BeginScene(device);
5060 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5061 if(SUCCEEDED(hr))
5063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5064 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5066 hr = IDirect3DDevice9_EndScene(device);
5067 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5070 color = getPixelColor(device, 360, 240);
5071 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5072 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5075 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5077 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5078 } else {
5079 skip("dp2add shader creation failed\n");
5082 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5083 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5086 static void cnd_test(IDirect3DDevice9 *device)
5088 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5089 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5090 HRESULT hr;
5091 DWORD color;
5092 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5093 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5094 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5096 DWORD shader_code_11[] = {
5097 0xffff0101, /* ps_1_1 */
5098 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5099 0x00000040, 0xb00f0000, /* texcoord t0 */
5100 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5101 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5102 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5103 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5104 0x0000ffff /* end */
5106 DWORD shader_code_12[] = {
5107 0xffff0102, /* ps_1_2 */
5108 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5109 0x00000040, 0xb00f0000, /* texcoord t0 */
5110 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5111 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5112 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5113 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5114 0x0000ffff /* end */
5116 DWORD shader_code_13[] = {
5117 0xffff0103, /* ps_1_3 */
5118 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5119 0x00000040, 0xb00f0000, /* texcoord t0 */
5120 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5121 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5122 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5123 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5124 0x0000ffff /* end */
5126 DWORD shader_code_14[] = {
5127 0xffff0104, /* ps_1_3 */
5128 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5129 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5130 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5131 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5132 0x0000ffff /* end */
5135 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5136 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5137 * set by the compiler, it was added manually after compilation. It isn't always allowed,
5138 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
5139 * native CreatePixelShader returns an error.
5141 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5142 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5143 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5144 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5146 DWORD shader_code_11_coissue[] = {
5147 0xffff0101, /* ps_1_1 */
5148 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5149 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5150 0x00000040, 0xb00f0000, /* texcoord t0 */
5151 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5152 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5153 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5154 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5155 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5156 /* 0x40000000 = D3DSI_COISSUE */
5157 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5158 0x0000ffff /* end */
5160 DWORD shader_code_12_coissue[] = {
5161 0xffff0102, /* ps_1_2 */
5162 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5163 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5164 0x00000040, 0xb00f0000, /* texcoord t0 */
5165 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5166 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5167 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5168 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5169 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5170 /* 0x40000000 = D3DSI_COISSUE */
5171 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5172 0x0000ffff /* end */
5174 DWORD shader_code_13_coissue[] = {
5175 0xffff0103, /* ps_1_3 */
5176 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5177 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5178 0x00000040, 0xb00f0000, /* texcoord t0 */
5179 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5180 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5181 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5182 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5183 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5184 /* 0x40000000 = D3DSI_COISSUE */
5185 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5186 0x0000ffff /* end */
5188 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5189 * compare against 0.5
5191 DWORD shader_code_14_coissue[] = {
5192 0xffff0104, /* ps_1_4 */
5193 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5194 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5195 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5196 /* 0x40000000 = D3DSI_COISSUE */
5197 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5198 0x0000ffff /* end */
5200 float quad1[] = {
5201 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5202 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5203 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5204 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5206 float quad2[] = {
5207 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5208 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5209 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5210 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5212 float quad3[] = {
5213 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5214 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5215 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5216 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5218 float quad4[] = {
5219 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5220 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5221 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5222 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5224 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5225 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5226 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5227 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5230 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5232 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5233 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5234 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5235 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5236 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5237 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5238 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5240 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5241 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5242 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5243 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5244 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5245 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5246 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5249 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5250 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5251 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5253 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5254 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5256 hr = IDirect3DDevice9_BeginScene(device);
5257 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5258 if(SUCCEEDED(hr))
5260 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5261 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5263 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5265 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5266 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5268 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5270 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5271 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5273 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5275 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5276 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5278 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5280 hr = IDirect3DDevice9_EndScene(device);
5281 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5284 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5287 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5288 color = getPixelColor(device, 158, 118);
5289 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5290 color = getPixelColor(device, 162, 118);
5291 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5292 color = getPixelColor(device, 158, 122);
5293 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5294 color = getPixelColor(device, 162, 122);
5295 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5297 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5298 color = getPixelColor(device, 158, 358);
5299 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5300 color = getPixelColor(device, 162, 358);
5301 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5302 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5303 color = getPixelColor(device, 158, 362);
5304 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5305 color = getPixelColor(device, 162, 362);
5306 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5307 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5309 /* 1.2 shader */
5310 color = getPixelColor(device, 478, 358);
5311 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5312 color = getPixelColor(device, 482, 358);
5313 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5314 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5315 color = getPixelColor(device, 478, 362);
5316 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5317 color = getPixelColor(device, 482, 362);
5318 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5319 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5321 /* 1.3 shader */
5322 color = getPixelColor(device, 478, 118);
5323 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5324 color = getPixelColor(device, 482, 118);
5325 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5326 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5327 color = getPixelColor(device, 478, 122);
5328 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5329 color = getPixelColor(device, 482, 122);
5330 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5333 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5334 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5337 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5338 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5340 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5343 hr = IDirect3DDevice9_BeginScene(device);
5344 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5345 if(SUCCEEDED(hr))
5347 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5349 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5350 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5352 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5353 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5355 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5357 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5358 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5360 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5362 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5363 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5365 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5367 hr = IDirect3DDevice9_EndScene(device);
5368 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5371 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5372 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5374 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5375 * that we swapped the values in c1 and c2 to make the other tests return some color
5377 color = getPixelColor(device, 158, 118);
5378 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5379 color = getPixelColor(device, 162, 118);
5380 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5381 color = getPixelColor(device, 158, 122);
5382 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5383 color = getPixelColor(device, 162, 122);
5384 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5386 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5387 color = getPixelColor(device, 158, 358);
5388 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5389 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5390 color = getPixelColor(device, 162, 358);
5391 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5392 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5393 color = getPixelColor(device, 158, 362);
5394 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5395 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5396 color = getPixelColor(device, 162, 362);
5397 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5398 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5400 /* 1.2 shader */
5401 color = getPixelColor(device, 478, 358);
5402 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5403 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5404 color = getPixelColor(device, 482, 358);
5405 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5406 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5407 color = getPixelColor(device, 478, 362);
5408 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5409 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5410 color = getPixelColor(device, 482, 362);
5411 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5412 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5414 /* 1.3 shader */
5415 color = getPixelColor(device, 478, 118);
5416 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5417 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5418 color = getPixelColor(device, 482, 118);
5419 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5420 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5421 color = getPixelColor(device, 478, 122);
5422 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5423 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5424 color = getPixelColor(device, 482, 122);
5425 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5426 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5428 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5429 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5431 IDirect3DPixelShader9_Release(shader_14_coissue);
5432 IDirect3DPixelShader9_Release(shader_13_coissue);
5433 IDirect3DPixelShader9_Release(shader_12_coissue);
5434 IDirect3DPixelShader9_Release(shader_11_coissue);
5435 IDirect3DPixelShader9_Release(shader_14);
5436 IDirect3DPixelShader9_Release(shader_13);
5437 IDirect3DPixelShader9_Release(shader_12);
5438 IDirect3DPixelShader9_Release(shader_11);
5441 static void nested_loop_test(IDirect3DDevice9 *device) {
5442 const DWORD shader_code[] = {
5443 0xffff0300, /* ps_3_0 */
5444 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5445 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5446 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5447 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5448 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5449 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5450 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5451 0x0000001d, /* endloop */
5452 0x0000001d, /* endloop */
5453 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5454 0x0000ffff /* end */
5456 IDirect3DPixelShader9 *shader;
5457 HRESULT hr;
5458 DWORD color;
5459 const float quad[] = {
5460 -1.0, -1.0, 0.1,
5461 1.0, -1.0, 0.1,
5462 -1.0, 1.0, 0.1,
5463 1.0, 1.0, 0.1
5466 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5467 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5468 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5469 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5470 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5471 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5473 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5475 hr = IDirect3DDevice9_BeginScene(device);
5476 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5477 if(SUCCEEDED(hr))
5479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5480 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5481 hr = IDirect3DDevice9_EndScene(device);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5485 color = getPixelColor(device, 360, 240);
5486 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5487 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5489 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5490 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5492 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5493 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5494 IDirect3DPixelShader9_Release(shader);
5497 struct varying_test_struct
5499 const DWORD *shader_code;
5500 IDirect3DPixelShader9 *shader;
5501 DWORD color, color_rhw;
5502 const char *name;
5503 BOOL todo, todo_rhw;
5506 struct hugeVertex
5508 float pos_x, pos_y, pos_z, rhw;
5509 float weight_1, weight_2, weight_3, weight_4;
5510 float index_1, index_2, index_3, index_4;
5511 float normal_1, normal_2, normal_3, normal_4;
5512 float fog_1, fog_2, fog_3, fog_4;
5513 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5514 float tangent_1, tangent_2, tangent_3, tangent_4;
5515 float binormal_1, binormal_2, binormal_3, binormal_4;
5516 float depth_1, depth_2, depth_3, depth_4;
5517 DWORD diffuse, specular;
5520 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5521 /* dcl_position: fails to compile */
5522 const DWORD blendweight_code[] = {
5523 0xffff0300, /* ps_3_0 */
5524 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5525 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5526 0x0000ffff /* end */
5528 const DWORD blendindices_code[] = {
5529 0xffff0300, /* ps_3_0 */
5530 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5531 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5532 0x0000ffff /* end */
5534 const DWORD normal_code[] = {
5535 0xffff0300, /* ps_3_0 */
5536 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5537 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5538 0x0000ffff /* end */
5540 /* psize: fails? */
5541 const DWORD texcoord0_code[] = {
5542 0xffff0300, /* ps_3_0 */
5543 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5544 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5545 0x0000ffff /* end */
5547 const DWORD tangent_code[] = {
5548 0xffff0300, /* ps_3_0 */
5549 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5550 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5551 0x0000ffff /* end */
5553 const DWORD binormal_code[] = {
5554 0xffff0300, /* ps_3_0 */
5555 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5556 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5557 0x0000ffff /* end */
5559 /* tessfactor: fails */
5560 /* positiont: fails */
5561 const DWORD color_code[] = {
5562 0xffff0300, /* ps_3_0 */
5563 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5564 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5565 0x0000ffff /* end */
5567 const DWORD fog_code[] = {
5568 0xffff0300, /* ps_3_0 */
5569 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5570 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5571 0x0000ffff /* end */
5573 const DWORD depth_code[] = {
5574 0xffff0300, /* ps_3_0 */
5575 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5576 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5577 0x0000ffff /* end */
5579 const DWORD specular_code[] = {
5580 0xffff0300, /* ps_3_0 */
5581 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5582 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5583 0x0000ffff /* end */
5585 /* sample: fails */
5587 struct varying_test_struct tests[] = {
5588 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5589 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5590 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5591 /* Why does dx not forward the texcoord? */
5592 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5593 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5594 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5595 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5596 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5597 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5598 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5600 /* Declare a monster vertex type :-) */
5601 static const D3DVERTEXELEMENT9 decl_elements[] = {
5602 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5603 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5604 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5605 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5606 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5607 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5608 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5609 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5610 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5611 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5612 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5613 D3DDECL_END()
5615 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5616 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5617 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5618 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5619 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5620 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5621 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5622 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5623 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5624 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5625 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5626 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5627 D3DDECL_END()
5629 struct hugeVertex data[4] = {
5631 -1.0, -1.0, 0.1, 1.0,
5632 0.1, 0.1, 0.1, 0.1,
5633 0.2, 0.2, 0.2, 0.2,
5634 0.3, 0.3, 0.3, 0.3,
5635 0.4, 0.4, 0.4, 0.4,
5636 0.50, 0.55, 0.55, 0.55,
5637 0.6, 0.6, 0.6, 0.7,
5638 0.7, 0.7, 0.7, 0.6,
5639 0.8, 0.8, 0.8, 0.8,
5640 0xe6e6e6e6, /* 0.9 * 256 */
5641 0x224488ff /* Nothing special */
5644 1.0, -1.0, 0.1, 1.0,
5645 0.1, 0.1, 0.1, 0.1,
5646 0.2, 0.2, 0.2, 0.2,
5647 0.3, 0.3, 0.3, 0.3,
5648 0.4, 0.4, 0.4, 0.4,
5649 0.50, 0.55, 0.55, 0.55,
5650 0.6, 0.6, 0.6, 0.7,
5651 0.7, 0.7, 0.7, 0.6,
5652 0.8, 0.8, 0.8, 0.8,
5653 0xe6e6e6e6, /* 0.9 * 256 */
5654 0x224488ff /* Nothing special */
5657 -1.0, 1.0, 0.1, 1.0,
5658 0.1, 0.1, 0.1, 0.1,
5659 0.2, 0.2, 0.2, 0.2,
5660 0.3, 0.3, 0.3, 0.3,
5661 0.4, 0.4, 0.4, 0.4,
5662 0.50, 0.55, 0.55, 0.55,
5663 0.6, 0.6, 0.6, 0.7,
5664 0.7, 0.7, 0.7, 0.6,
5665 0.8, 0.8, 0.8, 0.8,
5666 0xe6e6e6e6, /* 0.9 * 256 */
5667 0x224488ff /* Nothing special */
5670 1.0, 1.0, 0.1, 1.0,
5671 0.1, 0.1, 0.1, 0.1,
5672 0.2, 0.2, 0.2, 0.2,
5673 0.3, 0.3, 0.3, 0.3,
5674 0.4, 0.4, 0.4, 0.4,
5675 0.50, 0.55, 0.55, 0.55,
5676 0.6, 0.6, 0.6, 0.7,
5677 0.7, 0.7, 0.7, 0.6,
5678 0.8, 0.8, 0.8, 0.8,
5679 0xe6e6e6e6, /* 0.9 * 256 */
5680 0x224488ff /* Nothing special */
5683 struct hugeVertex data2[4];
5684 IDirect3DVertexDeclaration9 *decl;
5685 IDirect3DVertexDeclaration9 *decl2;
5686 HRESULT hr;
5687 unsigned int i;
5688 DWORD color, r, g, b, r_e, g_e, b_e;
5689 BOOL drawok;
5691 memcpy(data2, data, sizeof(data2));
5692 data2[0].pos_x = 0; data2[0].pos_y = 0;
5693 data2[1].pos_x = 640; data2[1].pos_y = 0;
5694 data2[2].pos_x = 0; data2[2].pos_y = 480;
5695 data2[3].pos_x = 640; data2[3].pos_y = 480;
5697 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5698 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5699 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5700 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5701 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5702 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5704 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5706 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5707 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5708 tests[i].name, hr);
5711 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5713 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5714 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5716 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5719 hr = IDirect3DDevice9_BeginScene(device);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5721 drawok = FALSE;
5722 if(SUCCEEDED(hr))
5724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5725 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5726 drawok = SUCCEEDED(hr);
5727 hr = IDirect3DDevice9_EndScene(device);
5728 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5731 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5732 * the failure and do not check the color if it failed
5734 if(!drawok) {
5735 continue;
5738 color = getPixelColor(device, 360, 240);
5739 r = color & 0x00ff0000 >> 16;
5740 g = color & 0x0000ff00 >> 8;
5741 b = color & 0x000000ff;
5742 r_e = tests[i].color & 0x00ff0000 >> 16;
5743 g_e = tests[i].color & 0x0000ff00 >> 8;
5744 b_e = tests[i].color & 0x000000ff;
5746 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5747 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5749 if(tests[i].todo) {
5750 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5751 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5752 tests[i].name, color, tests[i].color);
5753 } else {
5754 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5755 "Test %s returned color 0x%08x, expected 0x%08x\n",
5756 tests[i].name, color, tests[i].color);
5760 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5761 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5762 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5764 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5765 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5767 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5768 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5770 hr = IDirect3DDevice9_BeginScene(device);
5771 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5772 if(SUCCEEDED(hr))
5774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5775 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5776 hr = IDirect3DDevice9_EndScene(device);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5780 color = getPixelColor(device, 360, 240);
5781 r = color & 0x00ff0000 >> 16;
5782 g = color & 0x0000ff00 >> 8;
5783 b = color & 0x000000ff;
5784 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5785 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5786 b_e = tests[i].color_rhw & 0x000000ff;
5788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5791 if(tests[i].todo_rhw) {
5792 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5793 * pipeline
5795 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5796 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5797 tests[i].name, color, tests[i].color_rhw);
5798 } else {
5799 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800 "Test %s returned color 0x%08x, expected 0x%08x\n",
5801 tests[i].name, color, tests[i].color_rhw);
5805 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5807 IDirect3DPixelShader9_Release(tests[i].shader);
5810 IDirect3DVertexDeclaration9_Release(decl2);
5811 IDirect3DVertexDeclaration9_Release(decl);
5814 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5815 static const DWORD ps_code[] = {
5816 0xffff0300, /* ps_3_0 */
5817 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5818 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5819 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5820 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5821 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5822 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5823 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5824 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5825 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5827 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5828 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5829 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5830 0x0000001d, /* endloop */
5831 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5832 0x0000ffff /* end */
5834 static const DWORD vs_1_code[] = {
5835 0xfffe0101, /* vs_1_1 */
5836 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5837 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5838 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5839 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5840 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5841 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5842 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5843 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5844 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5845 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5846 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5847 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5848 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5849 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5850 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5851 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5852 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5853 0x0000ffff
5855 DWORD vs_2_code[] = {
5856 0xfffe0200, /* vs_2_0 */
5857 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5858 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5859 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5860 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5861 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5862 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5863 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5864 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5865 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5866 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5867 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5868 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5869 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5870 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5871 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5872 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5873 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5874 0x0000ffff /* end */
5876 /* TODO: Define normal, tangent, blendweight and depth here */
5877 static const DWORD vs_3_code[] = {
5878 0xfffe0300, /* vs_3_0 */
5879 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5880 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5881 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5882 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5883 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5884 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5885 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5886 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5887 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5888 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5889 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5890 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5891 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5892 0x0000ffff /* end */
5894 float quad1[] = {
5895 -1.0, -1.0, 0.1,
5896 0.0, -1.0, 0.1,
5897 -1.0, 0.0, 0.1,
5898 0.0, 0.0, 0.1
5900 float quad2[] = {
5901 0.0, -1.0, 0.1,
5902 1.0, -1.0, 0.1,
5903 0.0, 0.0, 0.1,
5904 1.0, 0.0, 0.1
5906 float quad3[] = {
5907 -1.0, 0.0, 0.1,
5908 0.0, 0.0, 0.1,
5909 -1.0, 1.0, 0.1,
5910 0.0, 1.0, 0.1
5913 HRESULT hr;
5914 DWORD color;
5915 IDirect3DPixelShader9 *pixelshader = NULL;
5916 IDirect3DVertexShader9 *vs_1_shader = NULL;
5917 IDirect3DVertexShader9 *vs_2_shader = NULL;
5918 IDirect3DVertexShader9 *vs_3_shader = NULL;
5920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5921 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5923 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5924 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5925 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5926 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5927 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5928 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5929 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5930 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5931 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5932 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5933 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5935 hr = IDirect3DDevice9_BeginScene(device);
5936 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5937 if(SUCCEEDED(hr))
5939 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5940 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5942 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5944 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5945 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5947 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5949 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5950 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5952 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5954 hr = IDirect3DDevice9_EndScene(device);
5955 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5958 color = getPixelColor(device, 160, 120);
5959 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5960 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5961 /* Accept two ways of oFog handling:
5963 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5964 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5966 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5967 * This happens with software vertex processing and on Intel cards
5969 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5970 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5972 color = getPixelColor(device, 160, 360);
5973 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5974 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5975 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5976 color = getPixelColor(device, 480, 360);
5977 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5978 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5979 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5981 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5982 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5984 /* cleanup */
5985 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5986 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5987 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5989 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5990 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5991 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5992 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5995 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5996 static const DWORD vs_code[] = {
5997 0xfffe0300, /* vs_3_0 */
5998 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5999 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6000 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
6001 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
6002 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
6003 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
6004 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
6005 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
6006 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
6007 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
6008 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
6009 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
6010 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
6012 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6013 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
6014 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
6015 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
6016 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
6017 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
6018 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
6019 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
6020 0x0000ffff /* end */
6022 static const DWORD ps_1_code[] = {
6023 0xffff0104, /* ps_1_4 */
6024 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6025 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
6026 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
6027 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
6028 0x0000ffff /* end */
6030 static const DWORD ps_2_code[] = {
6031 0xffff0200, /* ps_2_0 */
6032 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
6033 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
6034 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
6036 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
6037 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
6038 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6039 0x0000ffff /* end */
6041 static const DWORD ps_3_code[] = {
6042 0xffff0300, /* ps_3_0 */
6043 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
6044 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
6045 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
6047 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
6048 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
6049 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
6050 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6051 0x0000ffff /* end */
6054 float quad1[] = {
6055 -1.0, -1.0, 0.1,
6056 0.0, -1.0, 0.1,
6057 -1.0, 0.0, 0.1,
6058 0.0, 0.0, 0.1
6060 float quad2[] = {
6061 0.0, -1.0, 0.1,
6062 1.0, -1.0, 0.1,
6063 0.0, 0.0, 0.1,
6064 1.0, 0.0, 0.1
6066 float quad3[] = {
6067 -1.0, 0.0, 0.1,
6068 0.0, 0.0, 0.1,
6069 -1.0, 1.0, 0.1,
6070 0.0, 1.0, 0.1
6072 float quad4[] = {
6073 0.0, 0.0, 0.1,
6074 1.0, 0.0, 0.1,
6075 0.0, 1.0, 0.1,
6076 1.0, 1.0, 0.1
6079 HRESULT hr;
6080 DWORD color;
6081 IDirect3DVertexShader9 *vertexshader = NULL;
6082 IDirect3DPixelShader9 *ps_1_shader = NULL;
6083 IDirect3DPixelShader9 *ps_2_shader = NULL;
6084 IDirect3DPixelShader9 *ps_3_shader = NULL;
6085 IDirect3DTexture9 *texture = NULL;
6086 D3DLOCKED_RECT lr;
6087 unsigned int x, y;
6089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6090 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6092 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6093 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6094 if(FAILED(hr)) {
6095 skip("D3DFMT_A16B16G16R16 textures not supported\n");
6096 return;
6098 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6099 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6100 for(y = 0; y < 512; y++) {
6101 for(x = 0; x < 512; x++) {
6102 double r_f = (double) x / (double) 512;
6103 double g_f = (double) y / (double) 512;
6104 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6105 unsigned short r = (unsigned short) (r_f * 65535.0);
6106 unsigned short g = (unsigned short) (g_f * 65535.0);
6107 dst[0] = r;
6108 dst[1] = g;
6109 dst[2] = 0;
6110 dst[3] = 65535;
6113 hr = IDirect3DTexture9_UnlockRect(texture, 0);
6114 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6116 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6117 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6118 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6119 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6120 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6121 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6122 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6123 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6124 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6125 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6126 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6128 hr = IDirect3DDevice9_BeginScene(device);
6129 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6130 if(SUCCEEDED(hr))
6132 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6133 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6135 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6137 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6138 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6140 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6142 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6143 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6145 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6147 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6148 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6149 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6150 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6151 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6152 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6153 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6154 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6155 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6156 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6157 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6158 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6160 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6162 hr = IDirect3DDevice9_EndScene(device);
6163 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6166 color = getPixelColor(device, 160, 120);
6167 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6168 (color & 0x0000ff00) == 0x0000ff00 &&
6169 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6170 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6171 color = getPixelColor(device, 160, 360);
6172 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6173 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6174 (color & 0x000000ff) == 0x00000000,
6175 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6176 color = getPixelColor(device, 480, 360);
6177 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6178 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6179 (color & 0x000000ff) == 0x00000000,
6180 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6181 color = getPixelColor(device, 480, 160);
6182 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6183 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6184 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6185 (color & 0x000000ff) == 0x00000000),
6186 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6188 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6189 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6191 /* cleanup */
6192 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6193 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6194 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6195 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6196 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6197 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6198 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6199 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6200 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6201 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6202 if(texture) IDirect3DTexture9_Release(texture);
6205 static void test_compare_instructions(IDirect3DDevice9 *device)
6207 DWORD shader_sge_vec_code[] = {
6208 0xfffe0101, /* vs_1_1 */
6209 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6210 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6211 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6212 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6213 0x0000ffff /* end */
6215 DWORD shader_slt_vec_code[] = {
6216 0xfffe0101, /* vs_1_1 */
6217 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6218 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6219 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6220 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6221 0x0000ffff /* end */
6223 DWORD shader_sge_scalar_code[] = {
6224 0xfffe0101, /* vs_1_1 */
6225 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6226 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6227 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6228 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6229 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6230 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6231 0x0000ffff /* end */
6233 DWORD shader_slt_scalar_code[] = {
6234 0xfffe0101, /* vs_1_1 */
6235 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6236 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6237 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6238 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6239 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6240 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6241 0x0000ffff /* end */
6243 IDirect3DVertexShader9 *shader_sge_vec;
6244 IDirect3DVertexShader9 *shader_slt_vec;
6245 IDirect3DVertexShader9 *shader_sge_scalar;
6246 IDirect3DVertexShader9 *shader_slt_scalar;
6247 HRESULT hr, color;
6248 float quad1[] = {
6249 -1.0, -1.0, 0.1,
6250 0.0, -1.0, 0.1,
6251 -1.0, 0.0, 0.1,
6252 0.0, 0.0, 0.1
6254 float quad2[] = {
6255 0.0, -1.0, 0.1,
6256 1.0, -1.0, 0.1,
6257 0.0, 0.0, 0.1,
6258 1.0, 0.0, 0.1
6260 float quad3[] = {
6261 -1.0, 0.0, 0.1,
6262 0.0, 0.0, 0.1,
6263 -1.0, 1.0, 0.1,
6264 0.0, 1.0, 0.1
6266 float quad4[] = {
6267 0.0, 0.0, 0.1,
6268 1.0, 0.0, 0.1,
6269 0.0, 1.0, 0.1,
6270 1.0, 1.0, 0.1
6272 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6273 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6276 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6278 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6279 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6280 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6281 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6282 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6283 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6285 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6287 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6288 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6289 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6290 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6293 hr = IDirect3DDevice9_BeginScene(device);
6294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295 if(SUCCEEDED(hr))
6297 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6300 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6302 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6305 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6307 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6310 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6312 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6313 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6315 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6316 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6318 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6320 hr = IDirect3DDevice9_EndScene(device);
6321 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6324 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6327 color = getPixelColor(device, 160, 360);
6328 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6329 color = getPixelColor(device, 480, 360);
6330 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6331 color = getPixelColor(device, 160, 120);
6332 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6333 color = getPixelColor(device, 480, 160);
6334 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6336 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6337 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6339 IDirect3DVertexShader9_Release(shader_sge_vec);
6340 IDirect3DVertexShader9_Release(shader_slt_vec);
6341 IDirect3DVertexShader9_Release(shader_sge_scalar);
6342 IDirect3DVertexShader9_Release(shader_slt_scalar);
6345 static void test_vshader_input(IDirect3DDevice9 *device)
6347 DWORD swapped_shader_code_3[] = {
6348 0xfffe0300, /* vs_3_0 */
6349 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6350 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6351 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6352 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6353 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6354 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6355 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6356 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6357 0x0000ffff /* end */
6359 DWORD swapped_shader_code_1[] = {
6360 0xfffe0101, /* vs_1_1 */
6361 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6362 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6363 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6364 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6365 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6366 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6367 0x0000ffff /* end */
6369 DWORD swapped_shader_code_2[] = {
6370 0xfffe0200, /* vs_2_0 */
6371 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6372 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6373 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6374 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6375 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6376 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6377 0x0000ffff /* end */
6379 DWORD texcoord_color_shader_code_3[] = {
6380 0xfffe0300, /* vs_3_0 */
6381 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6382 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6383 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6384 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6385 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6386 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6387 0x0000ffff /* end */
6389 DWORD texcoord_color_shader_code_2[] = {
6390 0xfffe0200, /* vs_2_0 */
6391 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6392 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6393 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6394 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6395 0x0000ffff /* end */
6397 DWORD texcoord_color_shader_code_1[] = {
6398 0xfffe0101, /* vs_1_1 */
6399 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6400 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6401 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6402 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6403 0x0000ffff /* end */
6405 DWORD color_color_shader_code_3[] = {
6406 0xfffe0300, /* vs_3_0 */
6407 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6408 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6409 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6410 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6411 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6412 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6413 0x0000ffff /* end */
6415 DWORD color_color_shader_code_2[] = {
6416 0xfffe0200, /* vs_2_0 */
6417 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6418 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6419 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6420 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6421 0x0000ffff /* end */
6423 DWORD color_color_shader_code_1[] = {
6424 0xfffe0101, /* vs_1_1 */
6425 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6426 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6427 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6428 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6429 0x0000ffff /* end */
6431 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6432 HRESULT hr;
6433 DWORD color;
6434 float quad1[] = {
6435 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6436 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6437 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6438 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6440 float quad2[] = {
6441 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6442 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6443 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6444 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6446 float quad3[] = {
6447 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6448 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6449 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6450 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6452 float quad4[] = {
6453 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6454 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6455 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6456 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6458 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6459 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6460 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6461 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6462 D3DDECL_END()
6464 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6465 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6466 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6467 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6468 D3DDECL_END()
6470 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6471 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6472 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6473 D3DDECL_END()
6475 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6476 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6477 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6478 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6479 D3DDECL_END()
6481 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6482 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6483 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6484 D3DDECL_END()
6486 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6487 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6488 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6489 D3DDECL_END()
6491 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6492 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6493 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6494 D3DDECL_END()
6496 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6497 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6498 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6499 D3DDECL_END()
6501 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6502 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6503 unsigned int i;
6504 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6505 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6507 struct vertex quad1_color[] = {
6508 {-1.0, -1.0, 0.1, 0x00ff8040},
6509 { 0.0, -1.0, 0.1, 0x00ff8040},
6510 {-1.0, 0.0, 0.1, 0x00ff8040},
6511 { 0.0, 0.0, 0.1, 0x00ff8040}
6513 struct vertex quad2_color[] = {
6514 { 0.0, -1.0, 0.1, 0x00ff8040},
6515 { 1.0, -1.0, 0.1, 0x00ff8040},
6516 { 0.0, 0.0, 0.1, 0x00ff8040},
6517 { 1.0, 0.0, 0.1, 0x00ff8040}
6519 struct vertex quad3_color[] = {
6520 {-1.0, 0.0, 0.1, 0x00ff8040},
6521 { 0.0, 0.0, 0.1, 0x00ff8040},
6522 {-1.0, 1.0, 0.1, 0x00ff8040},
6523 { 0.0, 1.0, 0.1, 0x00ff8040}
6525 float quad4_color[] = {
6526 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6527 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6528 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6529 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6532 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6533 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6534 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6535 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6536 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6537 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6538 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6539 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6541 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6542 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6543 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6544 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6545 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6546 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6547 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6548 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6550 for(i = 1; i <= 3; i++) {
6551 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6552 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6553 if(i == 3) {
6554 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6555 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6556 } else if(i == 2){
6557 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6558 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6559 } else if(i == 1) {
6560 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6561 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6564 hr = IDirect3DDevice9_BeginScene(device);
6565 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6566 if(SUCCEEDED(hr))
6568 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6571 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6572 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6574 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6576 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6577 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6579 if(i == 3 || i == 2) {
6580 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6581 } else if(i == 1) {
6582 /* Succeeds or fails, depending on SW or HW vertex processing */
6583 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6586 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6589 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6591 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6594 if(i == 3 || i == 2) {
6595 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6596 } else if(i == 1) {
6597 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6600 hr = IDirect3DDevice9_EndScene(device);
6601 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6604 if(i == 3 || i == 2) {
6605 color = getPixelColor(device, 160, 360);
6606 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6607 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6609 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6610 color = getPixelColor(device, 480, 360);
6611 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6612 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6613 color = getPixelColor(device, 160, 120);
6614 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6615 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6616 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6618 color = getPixelColor(device, 480, 160);
6619 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6620 } else if(i == 1) {
6621 color = getPixelColor(device, 160, 360);
6622 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6623 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6624 color = getPixelColor(device, 480, 360);
6625 /* Accept the clear color as well in this case, since SW VP returns an error */
6626 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6627 color = getPixelColor(device, 160, 120);
6628 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6629 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6630 color = getPixelColor(device, 480, 160);
6631 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6634 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6635 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6638 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6640 /* Now find out if the whole streams are re-read, or just the last active value for the
6641 * vertices is used.
6643 hr = IDirect3DDevice9_BeginScene(device);
6644 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6645 if(SUCCEEDED(hr))
6647 float quad1_modified[] = {
6648 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6649 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6650 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6651 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6653 float quad2_modified[] = {
6654 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6655 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6656 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6657 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6660 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6661 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6663 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6666 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6668 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6669 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6671 if(i == 3 || i == 2) {
6672 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6673 } else if(i == 1) {
6674 /* Succeeds or fails, depending on SW or HW vertex processing */
6675 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6678 hr = IDirect3DDevice9_EndScene(device);
6679 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6682 color = getPixelColor(device, 480, 350);
6683 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6684 * as well.
6686 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6687 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6688 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6689 * refrast's result.
6691 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6693 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6694 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6696 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6697 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6699 IDirect3DDevice9_SetVertexShader(device, NULL);
6700 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6702 IDirect3DVertexShader9_Release(swapped_shader);
6705 for(i = 1; i <= 3; i++) {
6706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6707 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6708 if(i == 3) {
6709 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6710 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6711 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6713 } else if(i == 2){
6714 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6715 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6716 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6718 } else if(i == 1) {
6719 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6720 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6721 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6722 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6725 hr = IDirect3DDevice9_BeginScene(device);
6726 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6727 if(SUCCEEDED(hr))
6729 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6731 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6732 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6733 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6734 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6736 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6737 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6739 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6741 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6742 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6744 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6746 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6747 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6748 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6749 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6751 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6753 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6754 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6755 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6756 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6758 hr = IDirect3DDevice9_EndScene(device);
6759 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6761 IDirect3DDevice9_SetVertexShader(device, NULL);
6762 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6764 color = getPixelColor(device, 160, 360);
6765 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6766 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6767 color = getPixelColor(device, 480, 360);
6768 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6769 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6770 color = getPixelColor(device, 160, 120);
6771 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6772 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6773 color = getPixelColor(device, 480, 160);
6774 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6775 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6777 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6778 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6780 IDirect3DVertexShader9_Release(texcoord_color_shader);
6781 IDirect3DVertexShader9_Release(color_color_shader);
6784 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6785 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6786 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6787 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6789 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6790 IDirect3DVertexDeclaration9_Release(decl_color_color);
6791 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6792 IDirect3DVertexDeclaration9_Release(decl_color_float);
6795 static void srgbtexture_test(IDirect3DDevice9 *device)
6797 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6798 * texture stage state to render a quad using that texture. The resulting
6799 * color components should be 0x36 (~ 0.21), per this formula:
6800 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6801 * This is true where srgb_color > 0.04045.
6803 IDirect3D9 *d3d = NULL;
6804 HRESULT hr;
6805 LPDIRECT3DTEXTURE9 texture = NULL;
6806 LPDIRECT3DSURFACE9 surface = NULL;
6807 D3DLOCKED_RECT lr;
6808 DWORD color;
6809 float quad[] = {
6810 -1.0, 1.0, 0.0, 0.0, 0.0,
6811 1.0, 1.0, 0.0, 1.0, 0.0,
6812 -1.0, -1.0, 0.0, 0.0, 1.0,
6813 1.0, -1.0, 0.0, 1.0, 1.0,
6817 memset(&lr, 0, sizeof(lr));
6818 IDirect3DDevice9_GetDirect3D(device, &d3d);
6819 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6820 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6821 D3DFMT_A8R8G8B8) != D3D_OK) {
6822 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6823 goto out;
6826 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6827 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6828 &texture, NULL);
6829 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6830 if(!texture) {
6831 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6832 goto out;
6834 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6835 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6837 fill_surface(surface, 0xff7f7f7f);
6838 IDirect3DSurface9_Release(surface);
6840 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6841 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6842 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6843 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6845 hr = IDirect3DDevice9_BeginScene(device);
6846 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6847 if(SUCCEEDED(hr))
6849 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6850 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6852 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6853 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6857 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6859 hr = IDirect3DDevice9_EndScene(device);
6860 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6863 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6864 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6865 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6866 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6868 color = getPixelColor(device, 320, 240);
6869 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6872 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6874 out:
6875 if(texture) IDirect3DTexture9_Release(texture);
6876 IDirect3D9_Release(d3d);
6879 static void shademode_test(IDirect3DDevice9 *device)
6881 /* Render a quad and try all of the different fixed function shading models. */
6882 HRESULT hr;
6883 DWORD color0, color1;
6884 DWORD color0_gouraud = 0, color1_gouraud = 0;
6885 DWORD shademode = D3DSHADE_FLAT;
6886 DWORD primtype = D3DPT_TRIANGLESTRIP;
6887 LPVOID data = NULL;
6888 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6889 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6890 UINT i, j;
6891 struct vertex quad_strip[] =
6893 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6894 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6895 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6896 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6898 struct vertex quad_list[] =
6900 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6901 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6902 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6904 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6905 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6906 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6909 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6910 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6911 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6912 if (FAILED(hr)) goto bail;
6914 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6915 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6916 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6917 if (FAILED(hr)) goto bail;
6919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6920 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6922 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6923 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6925 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6926 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6927 memcpy(data, quad_strip, sizeof(quad_strip));
6928 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6929 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6931 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6932 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6933 memcpy(data, quad_list, sizeof(quad_list));
6934 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6935 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6937 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6938 * the color fixups we have to do for FLAT shading will be dependent on that. */
6939 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6940 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6942 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6943 for (j=0; j<2; j++) {
6945 /* Inner loop just changes the D3DRS_SHADEMODE */
6946 for (i=0; i<3; i++) {
6947 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6948 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6951 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6953 hr = IDirect3DDevice9_BeginScene(device);
6954 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6955 if(SUCCEEDED(hr))
6957 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6958 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6960 hr = IDirect3DDevice9_EndScene(device);
6961 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6964 /* Sample two spots from the output */
6965 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6966 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6967 switch(shademode) {
6968 case D3DSHADE_FLAT:
6969 /* Should take the color of the first vertex of each triangle */
6970 if (0)
6972 /* This test depends on EXT_provoking_vertex being
6973 * available. This extension is currently (20090810)
6974 * not common enough to let the test fail if it isn't
6975 * present. */
6976 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6977 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6979 shademode = D3DSHADE_GOURAUD;
6980 break;
6981 case D3DSHADE_GOURAUD:
6982 /* Should be an interpolated blend */
6984 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6985 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6986 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6987 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6989 color0_gouraud = color0;
6990 color1_gouraud = color1;
6992 shademode = D3DSHADE_PHONG;
6993 break;
6994 case D3DSHADE_PHONG:
6995 /* Should be the same as GOURAUD, since no hardware implements this */
6996 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6997 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6998 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6999 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7001 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7002 color0_gouraud, color0);
7003 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7004 color1_gouraud, color1);
7005 break;
7009 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7010 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7012 /* Now, do it all over again with a TRIANGLELIST */
7013 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7014 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7015 primtype = D3DPT_TRIANGLELIST;
7016 shademode = D3DSHADE_FLAT;
7019 bail:
7020 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7021 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7023 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7025 if (vb_strip)
7026 IDirect3DVertexBuffer9_Release(vb_strip);
7027 if (vb_list)
7028 IDirect3DVertexBuffer9_Release(vb_list);
7032 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
7034 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
7035 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
7036 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
7037 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
7038 * 0.73
7040 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
7041 * so use shaders for this task
7043 IDirect3DPixelShader9 *pshader;
7044 IDirect3DVertexShader9 *vshader;
7045 IDirect3D9 *d3d;
7046 DWORD vshader_code[] = {
7047 0xfffe0101, /* vs_1_1 */
7048 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7049 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
7050 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7051 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
7052 0x0000ffff /* end */
7054 DWORD pshader_code[] = {
7055 0xffff0101, /* ps_1_1 */
7056 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
7057 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7058 0x0000ffff /* end */
7060 const float quad[] = {
7061 -1.0, -1.0, 0.1,
7062 1.0, -1.0, 0.1,
7063 -1.0, 1.0, 0.1,
7064 1.0, 1.0, 0.1
7066 HRESULT hr;
7067 D3DCOLOR color;
7069 IDirect3DDevice9_GetDirect3D(device, &d3d);
7070 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
7071 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
7072 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
7073 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
7074 * works
7076 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7077 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
7078 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
7079 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
7080 IDirect3D9_Release(d3d);
7081 return;
7083 IDirect3D9_Release(d3d);
7085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
7086 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
7089 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
7091 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
7093 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
7095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7099 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7100 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7101 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
7102 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7103 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7104 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
7105 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7107 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
7108 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7110 hr = IDirect3DDevice9_BeginScene(device);
7111 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7112 if(SUCCEEDED(hr)) {
7113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
7114 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7116 hr = IDirect3DDevice9_EndScene(device);
7117 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7120 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7121 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7122 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7123 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7124 IDirect3DPixelShader9_Release(pshader);
7125 IDirect3DVertexShader9_Release(vshader);
7127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
7128 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
7130 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7132 color = getPixelColor(device, 160, 360);
7133 ok(color_match(color, 0x00808080, 1),
7134 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
7135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7136 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7139 static void alpha_test(IDirect3DDevice9 *device)
7141 HRESULT hr;
7142 IDirect3DTexture9 *offscreenTexture;
7143 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7144 DWORD color;
7146 struct vertex quad1[] =
7148 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7149 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7150 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7151 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7153 struct vertex quad2[] =
7155 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7156 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7157 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7158 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7160 static const float composite_quad[][5] = {
7161 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7162 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7163 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7164 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7167 /* Clear the render target with alpha = 0.5 */
7168 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7169 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7171 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7172 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7174 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7175 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7176 if(!backbuffer) {
7177 goto out;
7180 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7181 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7182 if(!offscreen) {
7183 goto out;
7186 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7187 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7189 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7190 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7191 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7192 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7193 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7194 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7195 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7196 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7198 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7201 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7202 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7204 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7210 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7213 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7215 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7217 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7219 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7220 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7221 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7222 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7223 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7224 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7225 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7228 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7230 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7232 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7235 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7238 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7239 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7241 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7242 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7244 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7245 * Disable alpha blending for the final composition
7247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7248 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7249 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7250 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7252 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7253 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7254 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7255 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7256 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7259 hr = IDirect3DDevice9_EndScene(device);
7260 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7263 color = getPixelColor(device, 160, 360);
7264 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7265 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7267 color = getPixelColor(device, 160, 120);
7268 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7269 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7271 color = getPixelColor(device, 480, 360);
7272 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7273 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7275 color = getPixelColor(device, 480, 120);
7276 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7277 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7279 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7281 out:
7282 /* restore things */
7283 if(backbuffer) {
7284 IDirect3DSurface9_Release(backbuffer);
7286 if(offscreenTexture) {
7287 IDirect3DTexture9_Release(offscreenTexture);
7289 if(offscreen) {
7290 IDirect3DSurface9_Release(offscreen);
7294 struct vertex_shortcolor {
7295 float x, y, z;
7296 unsigned short r, g, b, a;
7298 struct vertex_floatcolor {
7299 float x, y, z;
7300 float r, g, b, a;
7303 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7305 HRESULT hr;
7306 BOOL s_ok, ub_ok, f_ok;
7307 DWORD color, size, i;
7308 void *data;
7309 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7310 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7311 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7312 D3DDECL_END()
7314 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7315 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7316 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7317 D3DDECL_END()
7319 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7320 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7321 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7322 D3DDECL_END()
7324 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7325 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7326 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7327 D3DDECL_END()
7329 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7330 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7331 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7332 D3DDECL_END()
7334 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7335 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7336 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7337 D3DDECL_END()
7339 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7340 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7341 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7342 D3DDECL_END()
7344 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7345 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7346 IDirect3DVertexBuffer9 *vb, *vb2;
7347 struct vertex quad1[] = /* D3DCOLOR */
7349 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7350 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7351 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7352 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7354 struct vertex quad2[] = /* UBYTE4N */
7356 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7357 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7358 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7359 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7361 struct vertex_shortcolor quad3[] = /* short */
7363 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7364 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7365 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7366 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7368 struct vertex_floatcolor quad4[] =
7370 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7371 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7372 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7373 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7375 DWORD colors[] = {
7376 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7377 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7378 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7379 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7380 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7381 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7382 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7383 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7384 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7385 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7386 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7387 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7388 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7389 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7390 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7391 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7393 float quads[] = {
7394 -1.0, -1.0, 0.1,
7395 -1.0, 0.0, 0.1,
7396 0.0, -1.0, 0.1,
7397 0.0, 0.0, 0.1,
7399 0.0, -1.0, 0.1,
7400 0.0, 0.0, 0.1,
7401 1.0, -1.0, 0.1,
7402 1.0, 0.0, 0.1,
7404 0.0, 0.0, 0.1,
7405 0.0, 1.0, 0.1,
7406 1.0, 0.0, 0.1,
7407 1.0, 1.0, 0.1,
7409 -1.0, 0.0, 0.1,
7410 -1.0, 1.0, 0.1,
7411 0.0, 0.0, 0.1,
7412 0.0, 1.0, 0.1
7414 struct tvertex quad_transformed[] = {
7415 { 90, 110, 0.1, 2.0, 0x00ffff00},
7416 { 570, 110, 0.1, 2.0, 0x00ffff00},
7417 { 90, 300, 0.1, 2.0, 0x00ffff00},
7418 { 570, 300, 0.1, 2.0, 0x00ffff00}
7420 D3DCAPS9 caps;
7422 memset(&caps, 0, sizeof(caps));
7423 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7424 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7427 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7429 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7430 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7431 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7432 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7433 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7434 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7435 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7436 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7437 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7438 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7439 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7440 } else {
7441 trace("D3DDTCAPS_UBYTE4N not supported\n");
7442 dcl_ubyte_2 = NULL;
7443 dcl_ubyte = NULL;
7445 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7446 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7447 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7448 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7450 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7451 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7452 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7453 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7455 hr = IDirect3DDevice9_BeginScene(device);
7456 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7457 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7458 if(SUCCEEDED(hr)) {
7459 if(dcl_color) {
7460 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7461 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7463 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7466 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7467 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7468 * using software vertex processing. Doh!
7470 if(dcl_ubyte) {
7471 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7472 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7474 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7475 ub_ok = SUCCEEDED(hr);
7478 if(dcl_short) {
7479 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7480 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7482 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7483 s_ok = SUCCEEDED(hr);
7486 if(dcl_float) {
7487 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7490 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7491 f_ok = SUCCEEDED(hr);
7494 hr = IDirect3DDevice9_EndScene(device);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7498 if(dcl_short) {
7499 color = getPixelColor(device, 480, 360);
7500 ok(color == 0x000000ff || !s_ok,
7501 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7503 if(dcl_ubyte) {
7504 color = getPixelColor(device, 160, 120);
7505 ok(color == 0x0000ffff || !ub_ok,
7506 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7508 if(dcl_color) {
7509 color = getPixelColor(device, 160, 360);
7510 ok(color == 0x00ffff00,
7511 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7513 if(dcl_float) {
7514 color = getPixelColor(device, 480, 120);
7515 ok(color == 0x00ff0000 || !f_ok,
7516 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7518 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7520 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7521 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7522 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7523 * whether the immediate mode code works
7525 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7526 hr = IDirect3DDevice9_BeginScene(device);
7527 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7528 if(SUCCEEDED(hr)) {
7529 if(dcl_color) {
7530 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7531 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7532 memcpy(data, quad1, sizeof(quad1));
7533 hr = IDirect3DVertexBuffer9_Unlock(vb);
7534 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7535 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7536 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7537 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7538 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7539 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7540 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7543 if(dcl_ubyte) {
7544 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7545 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7546 memcpy(data, quad2, sizeof(quad2));
7547 hr = IDirect3DVertexBuffer9_Unlock(vb);
7548 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7549 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7550 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7551 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7552 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7553 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7554 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7555 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7556 ub_ok = SUCCEEDED(hr);
7559 if(dcl_short) {
7560 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7561 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7562 memcpy(data, quad3, sizeof(quad3));
7563 hr = IDirect3DVertexBuffer9_Unlock(vb);
7564 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7565 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7566 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7567 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7568 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7569 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7570 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7571 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7572 s_ok = SUCCEEDED(hr);
7575 if(dcl_float) {
7576 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7577 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7578 memcpy(data, quad4, sizeof(quad4));
7579 hr = IDirect3DVertexBuffer9_Unlock(vb);
7580 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7581 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7582 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7583 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7584 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7585 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7586 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7587 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7588 f_ok = SUCCEEDED(hr);
7591 hr = IDirect3DDevice9_EndScene(device);
7592 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7595 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7596 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7597 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7598 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7600 if(dcl_short) {
7601 color = getPixelColor(device, 480, 360);
7602 ok(color == 0x000000ff || !s_ok,
7603 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7605 if(dcl_ubyte) {
7606 color = getPixelColor(device, 160, 120);
7607 ok(color == 0x0000ffff || !ub_ok,
7608 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7610 if(dcl_color) {
7611 color = getPixelColor(device, 160, 360);
7612 ok(color == 0x00ffff00,
7613 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7615 if(dcl_float) {
7616 color = getPixelColor(device, 480, 120);
7617 ok(color == 0x00ff0000 || !f_ok,
7618 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7620 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7622 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7623 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7625 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7626 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7627 memcpy(data, quad_transformed, sizeof(quad_transformed));
7628 hr = IDirect3DVertexBuffer9_Unlock(vb);
7629 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7631 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7632 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7634 hr = IDirect3DDevice9_BeginScene(device);
7635 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7636 if(SUCCEEDED(hr)) {
7637 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7638 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7639 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7640 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7642 hr = IDirect3DDevice9_EndScene(device);
7643 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7646 color = getPixelColor(device, 88, 108);
7647 ok(color == 0x000000ff,
7648 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7649 color = getPixelColor(device, 92, 108);
7650 ok(color == 0x000000ff,
7651 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7652 color = getPixelColor(device, 88, 112);
7653 ok(color == 0x000000ff,
7654 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7655 color = getPixelColor(device, 92, 112);
7656 ok(color == 0x00ffff00,
7657 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7659 color = getPixelColor(device, 568, 108);
7660 ok(color == 0x000000ff,
7661 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7662 color = getPixelColor(device, 572, 108);
7663 ok(color == 0x000000ff,
7664 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7665 color = getPixelColor(device, 568, 112);
7666 ok(color == 0x00ffff00,
7667 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7668 color = getPixelColor(device, 572, 112);
7669 ok(color == 0x000000ff,
7670 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7672 color = getPixelColor(device, 88, 298);
7673 ok(color == 0x000000ff,
7674 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7675 color = getPixelColor(device, 92, 298);
7676 ok(color == 0x00ffff00,
7677 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7678 color = getPixelColor(device, 88, 302);
7679 ok(color == 0x000000ff,
7680 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7681 color = getPixelColor(device, 92, 302);
7682 ok(color == 0x000000ff,
7683 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7685 color = getPixelColor(device, 568, 298);
7686 ok(color == 0x00ffff00,
7687 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7688 color = getPixelColor(device, 572, 298);
7689 ok(color == 0x000000ff,
7690 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7691 color = getPixelColor(device, 568, 302);
7692 ok(color == 0x000000ff,
7693 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7694 color = getPixelColor(device, 572, 302);
7695 ok(color == 0x000000ff,
7696 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7698 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7700 /* This test is pointless without those two declarations: */
7701 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7702 skip("color-ubyte switching test declarations aren't supported\n");
7703 goto out;
7706 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7707 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7708 memcpy(data, quads, sizeof(quads));
7709 hr = IDirect3DVertexBuffer9_Unlock(vb);
7710 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7711 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7712 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7713 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7714 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7715 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7716 memcpy(data, colors, sizeof(colors));
7717 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7718 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7720 for(i = 0; i < 2; i++) {
7721 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7722 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7724 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7725 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7726 if(i == 0) {
7727 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7728 } else {
7729 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7731 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7733 hr = IDirect3DDevice9_BeginScene(device);
7734 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7735 ub_ok = FALSE;
7736 if(SUCCEEDED(hr)) {
7737 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7738 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7739 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7740 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7741 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7742 ub_ok = SUCCEEDED(hr);
7744 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7745 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7746 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7747 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7749 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7750 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7751 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7752 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7753 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7754 ub_ok = (SUCCEEDED(hr) && ub_ok);
7756 hr = IDirect3DDevice9_EndScene(device);
7757 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7760 if(i == 0) {
7761 color = getPixelColor(device, 480, 360);
7762 ok(color == 0x00ff0000,
7763 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7764 color = getPixelColor(device, 160, 120);
7765 ok(color == 0x00ffffff,
7766 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7767 color = getPixelColor(device, 160, 360);
7768 ok(color == 0x000000ff || !ub_ok,
7769 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7770 color = getPixelColor(device, 480, 120);
7771 ok(color == 0x000000ff || !ub_ok,
7772 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7773 } else {
7774 color = getPixelColor(device, 480, 360);
7775 ok(color == 0x000000ff,
7776 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7777 color = getPixelColor(device, 160, 120);
7778 ok(color == 0x00ffffff,
7779 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7780 color = getPixelColor(device, 160, 360);
7781 ok(color == 0x00ff0000 || !ub_ok,
7782 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7783 color = getPixelColor(device, 480, 120);
7784 ok(color == 0x00ff0000 || !ub_ok,
7785 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7787 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7790 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7791 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7792 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7793 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7794 IDirect3DVertexBuffer9_Release(vb2);
7796 out:
7797 IDirect3DVertexBuffer9_Release(vb);
7798 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7799 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7800 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7801 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7802 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7803 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7804 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7807 struct vertex_float16color {
7808 float x, y, z;
7809 DWORD c1, c2;
7812 static void test_vshader_float16(IDirect3DDevice9 *device)
7814 HRESULT hr;
7815 DWORD color;
7816 void *data;
7817 static const D3DVERTEXELEMENT9 decl_elements[] = {
7818 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7819 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7820 D3DDECL_END()
7822 IDirect3DVertexDeclaration9 *vdecl = NULL;
7823 IDirect3DVertexBuffer9 *buffer = NULL;
7824 IDirect3DVertexShader9 *shader;
7825 DWORD shader_code[] = {
7826 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7827 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7828 0x90e40001, 0x0000ffff
7830 struct vertex_float16color quad[] = {
7831 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7832 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7833 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7834 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7836 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7837 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7838 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7839 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7841 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7842 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7843 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7844 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7846 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7847 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7848 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7849 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7853 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7855 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7856 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7857 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7858 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7859 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7860 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7862 hr = IDirect3DDevice9_BeginScene(device);
7863 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7864 if(SUCCEEDED(hr)) {
7865 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7866 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7868 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7870 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7872 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7874 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7876 hr = IDirect3DDevice9_EndScene(device);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7879 color = getPixelColor(device, 480, 360);
7880 ok(color == 0x00ff0000,
7881 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7882 color = getPixelColor(device, 160, 120);
7883 ok(color == 0x00000000,
7884 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7885 color = getPixelColor(device, 160, 360);
7886 ok(color == 0x0000ff00,
7887 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7888 color = getPixelColor(device, 480, 120);
7889 ok(color == 0x000000ff,
7890 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7891 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7896 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7897 D3DPOOL_MANAGED, &buffer, NULL);
7898 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7899 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7900 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7901 memcpy(data, quad, sizeof(quad));
7902 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7903 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7904 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7905 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7907 hr = IDirect3DDevice9_BeginScene(device);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7909 if(SUCCEEDED(hr)) {
7910 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7911 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7912 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7913 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7914 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7915 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7916 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7919 hr = IDirect3DDevice9_EndScene(device);
7920 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7923 color = getPixelColor(device, 480, 360);
7924 ok(color == 0x00ff0000,
7925 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7926 color = getPixelColor(device, 160, 120);
7927 ok(color == 0x00000000,
7928 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7929 color = getPixelColor(device, 160, 360);
7930 ok(color == 0x0000ff00,
7931 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7932 color = getPixelColor(device, 480, 120);
7933 ok(color == 0x000000ff,
7934 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7935 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7937 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7938 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7939 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7940 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7941 IDirect3DDevice9_SetVertexShader(device, NULL);
7942 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7944 IDirect3DVertexDeclaration9_Release(vdecl);
7945 IDirect3DVertexShader9_Release(shader);
7946 IDirect3DVertexBuffer9_Release(buffer);
7949 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7951 D3DCAPS9 caps;
7952 IDirect3DTexture9 *texture;
7953 HRESULT hr;
7954 D3DLOCKED_RECT rect;
7955 unsigned int x, y;
7956 DWORD *dst, color;
7957 const float quad[] = {
7958 -1.0, -1.0, 0.1, -0.2, -0.2,
7959 1.0, -1.0, 0.1, 1.2, -0.2,
7960 -1.0, 1.0, 0.1, -0.2, 1.2,
7961 1.0, 1.0, 0.1, 1.2, 1.2
7963 memset(&caps, 0, sizeof(caps));
7965 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7966 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7967 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7968 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7969 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7970 "Card has conditional NP2 support without power of two restriction set\n");
7971 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7972 return;
7973 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7974 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7975 return;
7978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7979 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7981 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7982 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7984 memset(&rect, 0, sizeof(rect));
7985 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7986 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7987 for(y = 0; y < 10; y++) {
7988 for(x = 0; x < 10; x++) {
7989 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7990 if(x == 0 || x == 9 || y == 0 || y == 9) {
7991 *dst = 0x00ff0000;
7992 } else {
7993 *dst = 0x000000ff;
7997 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7998 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8000 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8001 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8002 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8003 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8004 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8005 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8006 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8007 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8009 hr = IDirect3DDevice9_BeginScene(device);
8010 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8011 if(SUCCEEDED(hr)) {
8012 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8013 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8015 hr = IDirect3DDevice9_EndScene(device);
8016 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8019 color = getPixelColor(device, 1, 1);
8020 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8021 color = getPixelColor(device, 639, 479);
8022 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8024 color = getPixelColor(device, 135, 101);
8025 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8026 color = getPixelColor(device, 140, 101);
8027 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8028 color = getPixelColor(device, 135, 105);
8029 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8030 color = getPixelColor(device, 140, 105);
8031 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8033 color = getPixelColor(device, 135, 376);
8034 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8035 color = getPixelColor(device, 140, 376);
8036 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8037 color = getPixelColor(device, 135, 379);
8038 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8039 color = getPixelColor(device, 140, 379);
8040 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8042 color = getPixelColor(device, 500, 101);
8043 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8044 color = getPixelColor(device, 504, 101);
8045 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8046 color = getPixelColor(device, 500, 105);
8047 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8048 color = getPixelColor(device, 504, 105);
8049 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8051 color = getPixelColor(device, 500, 376);
8052 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8053 color = getPixelColor(device, 504, 376);
8054 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8055 color = getPixelColor(device, 500, 380);
8056 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8057 color = getPixelColor(device, 504, 380);
8058 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8060 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8062 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8064 IDirect3DTexture9_Release(texture);
8067 static void vFace_register_test(IDirect3DDevice9 *device)
8069 HRESULT hr;
8070 DWORD color;
8071 const DWORD shader_code[] = {
8072 0xffff0300, /* ps_3_0 */
8073 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8074 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8075 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8076 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8077 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8078 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8079 0x0000ffff /* END */
8081 IDirect3DPixelShader9 *shader;
8082 IDirect3DTexture9 *texture;
8083 IDirect3DSurface9 *surface, *backbuffer;
8084 const float quad[] = {
8085 -1.0, -1.0, 0.1,
8086 1.0, -1.0, 0.1,
8087 -1.0, 0.0, 0.1,
8089 1.0, -1.0, 0.1,
8090 1.0, 0.0, 0.1,
8091 -1.0, 0.0, 0.1,
8093 -1.0, 0.0, 0.1,
8094 -1.0, 1.0, 0.1,
8095 1.0, 0.0, 0.1,
8097 1.0, 0.0, 0.1,
8098 -1.0, 1.0, 0.1,
8099 1.0, 1.0, 0.1,
8101 const float blit[] = {
8102 0.0, -1.0, 0.1, 0.0, 0.0,
8103 1.0, -1.0, 0.1, 1.0, 0.0,
8104 0.0, 1.0, 0.1, 0.0, 1.0,
8105 1.0, 1.0, 0.1, 1.0, 1.0,
8108 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8109 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8110 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8112 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8113 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8114 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8115 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8116 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8117 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8118 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8119 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8122 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8124 hr = IDirect3DDevice9_BeginScene(device);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8126 if(SUCCEEDED(hr)) {
8127 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8128 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8133 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8134 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8137 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8139 /* Blit the texture onto the back buffer to make it visible */
8140 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8141 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8142 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8143 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8145 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8146 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8147 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8149 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8152 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8154 hr = IDirect3DDevice9_EndScene(device);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8158 color = getPixelColor(device, 160, 360);
8159 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8160 color = getPixelColor(device, 160, 120);
8161 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8162 color = getPixelColor(device, 480, 360);
8163 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8164 color = getPixelColor(device, 480, 120);
8165 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8166 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8168 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8169 IDirect3DDevice9_SetTexture(device, 0, NULL);
8170 IDirect3DPixelShader9_Release(shader);
8171 IDirect3DSurface9_Release(surface);
8172 IDirect3DSurface9_Release(backbuffer);
8173 IDirect3DTexture9_Release(texture);
8176 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8178 HRESULT hr;
8179 DWORD color;
8180 int i;
8181 D3DCAPS9 caps;
8182 BOOL L6V5U5_supported = FALSE;
8183 IDirect3DTexture9 *tex1, *tex2;
8184 D3DLOCKED_RECT locked_rect;
8186 static const float quad[][7] = {
8187 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8188 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8189 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8190 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8193 static const D3DVERTEXELEMENT9 decl_elements[] = {
8194 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8195 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8196 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8197 D3DDECL_END()
8200 /* use asymmetric matrix to test loading */
8201 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8202 float scale, offset;
8204 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8205 IDirect3DTexture9 *texture = NULL;
8207 memset(&caps, 0, sizeof(caps));
8208 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8209 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8210 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8211 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8212 return;
8213 } else {
8214 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8215 * They report that it is not supported, but after that bump mapping works properly. So just test
8216 * if the format is generally supported, and check the BUMPENVMAP flag
8218 IDirect3D9 *d3d9;
8220 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8221 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8222 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8223 L6V5U5_supported = SUCCEEDED(hr);
8224 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8225 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8226 IDirect3D9_Release(d3d9);
8227 if(FAILED(hr)) {
8228 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8229 return;
8233 /* Generate the textures */
8234 generate_bumpmap_textures(device);
8236 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8237 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8238 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8239 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8240 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8241 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8242 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8243 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8245 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8246 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8247 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8248 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8249 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8250 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8252 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8253 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8254 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8255 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8256 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8257 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8259 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8260 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8262 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8263 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8266 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8269 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8270 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8271 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8272 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8274 hr = IDirect3DDevice9_BeginScene(device);
8275 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8278 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8280 hr = IDirect3DDevice9_EndScene(device);
8281 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8283 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8284 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8285 * But since testing the color match is not the purpose of the test don't be too picky
8287 color = getPixelColor(device, 320-32, 240);
8288 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8289 color = getPixelColor(device, 320+32, 240);
8290 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8291 color = getPixelColor(device, 320, 240-32);
8292 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8293 color = getPixelColor(device, 320, 240+32);
8294 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8295 color = getPixelColor(device, 320, 240);
8296 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8297 color = getPixelColor(device, 320+32, 240+32);
8298 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8299 color = getPixelColor(device, 320-32, 240+32);
8300 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8301 color = getPixelColor(device, 320+32, 240-32);
8302 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8303 color = getPixelColor(device, 320-32, 240-32);
8304 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8305 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8306 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8308 for(i = 0; i < 2; i++) {
8309 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8310 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8311 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8312 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8313 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8314 IDirect3DTexture9_Release(texture); /* To destroy it */
8317 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8318 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8319 goto cleanup;
8321 if(L6V5U5_supported == FALSE) {
8322 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8323 goto cleanup;
8326 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8327 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8328 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8329 * would only make this test more complicated
8331 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8333 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8334 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8336 memset(&locked_rect, 0, sizeof(locked_rect));
8337 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8338 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8339 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8340 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8341 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8343 memset(&locked_rect, 0, sizeof(locked_rect));
8344 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8345 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8346 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8347 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8348 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8350 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8351 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8352 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8353 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8356 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8357 scale = 2.0;
8358 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8359 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8360 offset = 0.1;
8361 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8362 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8364 hr = IDirect3DDevice9_BeginScene(device);
8365 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8366 if(SUCCEEDED(hr)) {
8367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8368 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8369 hr = IDirect3DDevice9_EndScene(device);
8370 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8373 color = getPixelColor(device, 320, 240);
8374 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8375 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8376 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8378 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8379 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8382 /* Check a result scale factor > 1.0 */
8383 scale = 10;
8384 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8385 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8386 offset = 10;
8387 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8388 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8390 hr = IDirect3DDevice9_BeginScene(device);
8391 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8392 if(SUCCEEDED(hr)) {
8393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8394 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8395 hr = IDirect3DDevice9_EndScene(device);
8396 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8398 color = getPixelColor(device, 320, 240);
8399 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8400 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8401 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8403 /* Check clamping in the scale factor calculation */
8404 scale = 1000;
8405 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8406 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8407 offset = -1;
8408 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8409 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8411 hr = IDirect3DDevice9_BeginScene(device);
8412 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8413 if(SUCCEEDED(hr)) {
8414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8415 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8416 hr = IDirect3DDevice9_EndScene(device);
8417 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8419 color = getPixelColor(device, 320, 240);
8420 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8421 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8422 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8424 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8425 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8426 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8429 IDirect3DTexture9_Release(tex1);
8430 IDirect3DTexture9_Release(tex2);
8432 cleanup:
8433 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8434 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8435 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8436 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8438 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8439 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8440 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8443 static void stencil_cull_test(IDirect3DDevice9 *device) {
8444 HRESULT hr;
8445 IDirect3DSurface9 *depthstencil = NULL;
8446 D3DSURFACE_DESC desc;
8447 float quad1[] = {
8448 -1.0, -1.0, 0.1,
8449 0.0, -1.0, 0.1,
8450 -1.0, 0.0, 0.1,
8451 0.0, 0.0, 0.1,
8453 float quad2[] = {
8454 0.0, -1.0, 0.1,
8455 1.0, -1.0, 0.1,
8456 0.0, 0.0, 0.1,
8457 1.0, 0.0, 0.1,
8459 float quad3[] = {
8460 0.0, 0.0, 0.1,
8461 1.0, 0.0, 0.1,
8462 0.0, 1.0, 0.1,
8463 1.0, 1.0, 0.1,
8465 float quad4[] = {
8466 -1.0, 0.0, 0.1,
8467 0.0, 0.0, 0.1,
8468 -1.0, 1.0, 0.1,
8469 0.0, 1.0, 0.1,
8471 struct vertex painter[] = {
8472 {-1.0, -1.0, 0.0, 0x00000000},
8473 { 1.0, -1.0, 0.0, 0x00000000},
8474 {-1.0, 1.0, 0.0, 0x00000000},
8475 { 1.0, 1.0, 0.0, 0x00000000},
8477 WORD indices_cw[] = {0, 1, 3};
8478 WORD indices_ccw[] = {0, 2, 3};
8479 unsigned int i;
8480 DWORD color;
8482 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8483 if(depthstencil == NULL) {
8484 skip("No depth stencil buffer\n");
8485 return;
8487 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8488 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8489 IDirect3DSurface9_Release(depthstencil);
8490 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8491 skip("No 4 or 8 bit stencil surface\n");
8492 return;
8495 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8497 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8500 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8506 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8509 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8511 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8516 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8517 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8518 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8520 /* First pass: Fill the stencil buffer with some values... */
8521 hr = IDirect3DDevice9_BeginScene(device);
8522 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8523 if(SUCCEEDED(hr))
8525 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8526 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8527 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8528 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8529 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8530 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8531 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8532 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8535 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8537 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8538 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8539 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8540 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8541 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8542 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8543 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8547 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8548 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8549 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8550 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8551 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8552 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8555 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8556 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8557 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8558 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8559 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8560 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8561 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8563 hr = IDirect3DDevice9_EndScene(device);
8564 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8567 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8569 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8577 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8579 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8581 /* 2nd pass: Make the stencil values visible */
8582 hr = IDirect3DDevice9_BeginScene(device);
8583 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8584 if(SUCCEEDED(hr))
8586 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8587 for(i = 0; i < 16; i++) {
8588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8589 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8591 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8592 painter[1].diffuse = (i * 16);
8593 painter[2].diffuse = (i * 16);
8594 painter[3].diffuse = (i * 16);
8595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8596 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8598 hr = IDirect3DDevice9_EndScene(device);
8599 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8603 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8605 color = getPixelColor(device, 160, 420);
8606 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8607 color = getPixelColor(device, 160, 300);
8608 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8610 color = getPixelColor(device, 480, 420);
8611 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8612 color = getPixelColor(device, 480, 300);
8613 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8615 color = getPixelColor(device, 160, 180);
8616 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8617 color = getPixelColor(device, 160, 60);
8618 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8620 color = getPixelColor(device, 480, 180);
8621 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8622 color = getPixelColor(device, 480, 60);
8623 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8626 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8629 static void vpos_register_test(IDirect3DDevice9 *device)
8631 HRESULT hr;
8632 DWORD color;
8633 const DWORD shader_code[] = {
8634 0xffff0300, /* ps_3_0 */
8635 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8636 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8637 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8638 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8639 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8640 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8641 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8642 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8643 0x0000ffff /* end */
8645 const DWORD shader_frac_code[] = {
8646 0xffff0300, /* ps_3_0 */
8647 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8648 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8649 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8650 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8651 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8652 0x0000ffff /* end */
8654 IDirect3DPixelShader9 *shader, *shader_frac;
8655 IDirect3DSurface9 *surface = NULL, *backbuffer;
8656 const float quad[] = {
8657 -1.0, -1.0, 0.1, 0.0, 0.0,
8658 1.0, -1.0, 0.1, 1.0, 0.0,
8659 -1.0, 1.0, 0.1, 0.0, 1.0,
8660 1.0, 1.0, 0.1, 1.0, 1.0,
8662 D3DLOCKED_RECT lr;
8663 float constant[4] = {1.0, 0.0, 320, 240};
8664 DWORD *pos;
8666 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8667 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8668 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8669 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8670 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8671 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8672 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8674 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8675 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8676 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8677 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8679 hr = IDirect3DDevice9_BeginScene(device);
8680 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8681 if(SUCCEEDED(hr)) {
8682 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8683 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8685 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8686 hr = IDirect3DDevice9_EndScene(device);
8687 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8690 /* This has to be pixel exact */
8691 color = getPixelColor(device, 319, 239);
8692 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8693 color = getPixelColor(device, 320, 239);
8694 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8695 color = getPixelColor(device, 319, 240);
8696 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8697 color = getPixelColor(device, 320, 240);
8698 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8699 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8701 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8702 &surface, NULL);
8703 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8704 hr = IDirect3DDevice9_BeginScene(device);
8705 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8706 if(SUCCEEDED(hr)) {
8707 constant[2] = 16; constant[3] = 16;
8708 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8709 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8710 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8711 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8712 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8714 hr = IDirect3DDevice9_EndScene(device);
8715 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8717 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8718 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8720 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8721 color = *pos & 0x00ffffff;
8722 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8723 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8724 color = *pos & 0x00ffffff;
8725 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8726 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8727 color = *pos & 0x00ffffff;
8728 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8729 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8730 color = *pos & 0x00ffffff;
8731 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8733 hr = IDirect3DSurface9_UnlockRect(surface);
8734 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8736 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8737 * have full control over the multisampling setting inside this test
8739 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8740 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8741 hr = IDirect3DDevice9_BeginScene(device);
8742 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8743 if(SUCCEEDED(hr)) {
8744 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8745 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8747 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8748 hr = IDirect3DDevice9_EndScene(device);
8749 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8751 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8752 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8754 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8755 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8757 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8758 color = *pos & 0x00ffffff;
8759 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8761 hr = IDirect3DSurface9_UnlockRect(surface);
8762 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8764 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8765 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8766 IDirect3DPixelShader9_Release(shader);
8767 IDirect3DPixelShader9_Release(shader_frac);
8768 if(surface) IDirect3DSurface9_Release(surface);
8769 IDirect3DSurface9_Release(backbuffer);
8772 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8774 D3DCOLOR color;
8776 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8777 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8778 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8779 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8780 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8782 ++r;
8783 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8784 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8785 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8786 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8787 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8789 return TRUE;
8792 static void pointsize_test(IDirect3DDevice9 *device)
8794 HRESULT hr;
8795 D3DCAPS9 caps;
8796 D3DMATRIX matrix;
8797 D3DMATRIX identity;
8798 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8799 DWORD color;
8800 IDirect3DSurface9 *rt, *backbuffer;
8801 IDirect3DTexture9 *tex1, *tex2;
8802 RECT rect = {0, 0, 128, 128};
8803 D3DLOCKED_RECT lr;
8804 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8805 0x00000000, 0x00000000};
8806 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8807 0x00000000, 0x0000ff00};
8809 const float vertices[] = {
8810 64, 64, 0.1,
8811 128, 64, 0.1,
8812 192, 64, 0.1,
8813 256, 64, 0.1,
8814 320, 64, 0.1,
8815 384, 64, 0.1,
8816 448, 64, 0.1,
8817 512, 64, 0.1,
8820 /* 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 */
8821 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;
8822 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;
8823 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;
8824 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;
8826 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;
8827 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;
8828 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;
8829 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;
8831 memset(&caps, 0, sizeof(caps));
8832 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8833 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8834 if(caps.MaxPointSize < 32.0) {
8835 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8836 return;
8839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8840 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8841 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8842 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8843 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8844 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8845 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8846 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8848 hr = IDirect3DDevice9_BeginScene(device);
8849 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8850 if (SUCCEEDED(hr))
8852 ptsize = 15.0;
8853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8855 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8856 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8858 ptsize = 31.0;
8859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8860 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8862 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8864 ptsize = 30.75;
8865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8866 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8868 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8870 if (caps.MaxPointSize >= 63.0)
8872 ptsize = 63.0;
8873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8874 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8876 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8878 ptsize = 62.75;
8879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8880 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8882 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8885 ptsize = 1.0;
8886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8889 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8891 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8892 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8893 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8894 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8896 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8897 ptsize = 15.0;
8898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8899 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8900 ptsize = 1.0;
8901 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8902 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8903 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8904 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8907 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8909 /* pointsize < pointsize_min < pointsize_max?
8910 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8911 ptsize = 1.0;
8912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8913 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8914 ptsize = 15.0;
8915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8921 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8923 hr = IDirect3DDevice9_EndScene(device);
8924 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8927 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8928 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8929 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8931 if (caps.MaxPointSize >= 63.0)
8933 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8934 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8937 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8938 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8939 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8940 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8941 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8943 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8945 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8946 * generates texture coordinates for the point(result: Yes, it does)
8948 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8949 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8950 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8953 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8955 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8956 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8957 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8958 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8959 memset(&lr, 0, sizeof(lr));
8960 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8961 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8962 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8963 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8964 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8965 memset(&lr, 0, sizeof(lr));
8966 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8967 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8968 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8969 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8970 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8971 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8972 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8973 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8974 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8975 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8976 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8977 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8978 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8979 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8980 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8981 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8982 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8983 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8984 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8988 ptsize = 32.0;
8989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8990 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8992 hr = IDirect3DDevice9_BeginScene(device);
8993 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8994 if(SUCCEEDED(hr))
8996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8997 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8998 hr = IDirect3DDevice9_EndScene(device);
8999 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9002 color = getPixelColor(device, 64-4, 64-4);
9003 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9004 color = getPixelColor(device, 64-4, 64+4);
9005 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9006 color = getPixelColor(device, 64+4, 64+4);
9007 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9008 color = getPixelColor(device, 64+4, 64-4);
9009 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9010 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9012 U(matrix).m[0][0] = 1.0f / 64.0f;
9013 U(matrix).m[1][1] = -1.0f / 64.0f;
9014 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9015 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9017 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9018 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9020 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9021 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9022 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9024 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9025 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9026 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9027 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9029 hr = IDirect3DDevice9_BeginScene(device);
9030 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9032 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9033 hr = IDirect3DDevice9_EndScene(device);
9034 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9036 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9037 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9038 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9039 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9040 IDirect3DSurface9_Release(backbuffer);
9041 IDirect3DSurface9_Release(rt);
9043 color = getPixelColor(device, 64-4, 64-4);
9044 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9045 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9046 color = getPixelColor(device, 64+4, 64-4);
9047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9048 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9049 color = getPixelColor(device, 64-4, 64+4);
9050 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9051 "Expected color 0x00000000, got 0x%08x.\n", color);
9052 color = getPixelColor(device, 64+4, 64+4);
9053 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9054 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9056 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9057 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9059 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9060 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9061 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9062 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9063 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9064 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9065 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9066 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9067 IDirect3DTexture9_Release(tex1);
9068 IDirect3DTexture9_Release(tex2);
9070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9071 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9074 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9078 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9080 HRESULT hr;
9081 IDirect3DPixelShader9 *ps;
9082 IDirect3DTexture9 *tex1, *tex2;
9083 IDirect3DSurface9 *surf1, *surf2, *backbuf;
9084 D3DCAPS9 caps;
9085 DWORD color;
9086 DWORD shader_code[] = {
9087 0xffff0300, /* ps_3_0 */
9088 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9089 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9090 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9091 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9092 0x0000ffff /* END */
9094 float quad[] = {
9095 -1.0, -1.0, 0.1,
9096 1.0, -1.0, 0.1,
9097 -1.0, 1.0, 0.1,
9098 1.0, 1.0, 0.1,
9100 float texquad[] = {
9101 -1.0, -1.0, 0.1, 0.0, 0.0,
9102 0.0, -1.0, 0.1, 1.0, 0.0,
9103 -1.0, 1.0, 0.1, 0.0, 1.0,
9104 0.0, 1.0, 0.1, 1.0, 1.0,
9106 0.0, -1.0, 0.1, 0.0, 0.0,
9107 1.0, -1.0, 0.1, 1.0, 0.0,
9108 0.0, 1.0, 0.1, 0.0, 1.0,
9109 1.0, 1.0, 0.1, 1.0, 1.0,
9112 memset(&caps, 0, sizeof(caps));
9113 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9114 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9115 if(caps.NumSimultaneousRTs < 2) {
9116 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9117 return;
9120 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9121 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9123 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9124 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9125 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9126 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9127 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9128 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9130 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9131 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9132 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9133 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9134 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9135 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9137 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9138 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9139 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9140 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9141 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9142 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9143 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9144 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9146 hr = IDirect3DDevice9_BeginScene(device);
9147 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9148 if(SUCCEEDED(hr)) {
9149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9150 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9152 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9153 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9154 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9155 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9156 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9157 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9158 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9159 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9161 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9162 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9164 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9166 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9167 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9169 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9171 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9172 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9174 hr = IDirect3DDevice9_EndScene(device);
9175 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9178 color = getPixelColor(device, 160, 240);
9179 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9180 color = getPixelColor(device, 480, 240);
9181 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9182 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9184 IDirect3DPixelShader9_Release(ps);
9185 IDirect3DTexture9_Release(tex1);
9186 IDirect3DTexture9_Release(tex2);
9187 IDirect3DSurface9_Release(surf1);
9188 IDirect3DSurface9_Release(surf2);
9189 IDirect3DSurface9_Release(backbuf);
9192 struct formats {
9193 const char *fmtName;
9194 D3DFORMAT textureFormat;
9195 DWORD resultColorBlending;
9196 DWORD resultColorNoBlending;
9199 const struct formats test_formats[] = {
9200 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9201 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9202 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9203 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9204 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9205 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9206 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9207 { NULL, 0 }
9210 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9212 HRESULT hr;
9213 IDirect3DTexture9 *offscreenTexture = NULL;
9214 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9215 IDirect3D9 *d3d = NULL;
9216 DWORD color;
9217 DWORD r0, g0, b0, r1, g1, b1;
9218 int fmt_index;
9220 static const float quad[][5] = {
9221 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9222 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9223 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9224 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9227 /* Quad with R=0x10, G=0x20 */
9228 static const struct vertex quad1[] = {
9229 {-1.0f, -1.0f, 0.1f, 0x80102000},
9230 {-1.0f, 1.0f, 0.1f, 0x80102000},
9231 { 1.0f, -1.0f, 0.1f, 0x80102000},
9232 { 1.0f, 1.0f, 0.1f, 0x80102000},
9235 /* Quad with R=0x20, G=0x10 */
9236 static const struct vertex quad2[] = {
9237 {-1.0f, -1.0f, 0.1f, 0x80201000},
9238 {-1.0f, 1.0f, 0.1f, 0x80201000},
9239 { 1.0f, -1.0f, 0.1f, 0x80201000},
9240 { 1.0f, 1.0f, 0.1f, 0x80201000},
9243 IDirect3DDevice9_GetDirect3D(device, &d3d);
9245 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9246 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9247 if(!backbuffer) {
9248 goto out;
9251 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9253 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9254 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9255 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9256 continue;
9259 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9260 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9262 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9263 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9264 if(!offscreenTexture) {
9265 continue;
9268 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9269 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9270 if(!offscreen) {
9271 continue;
9274 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9275 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9277 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9278 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9279 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9280 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9281 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9282 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9283 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9284 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9286 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9288 /* Below we will draw two quads with different colors and try to blend them together.
9289 * The result color is compared with the expected outcome.
9291 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9292 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9293 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9294 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9295 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9300 /* Draw a quad using color 0x0010200 */
9301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9306 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9308 /* Draw a quad using color 0x0020100 */
9309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9310 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9312 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9314 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9316 /* We don't want to blend the result on the backbuffer */
9317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9318 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9320 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9321 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9322 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9323 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9324 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9326 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9327 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9329 /* This time with the texture */
9330 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9331 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9333 IDirect3DDevice9_EndScene(device);
9336 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9337 /* Compare the color of the center quad with our expectation */
9338 color = getPixelColor(device, 320, 240);
9339 r0 = (color & 0x00ff0000) >> 16;
9340 g0 = (color & 0x0000ff00) >> 8;
9341 b0 = (color & 0x000000ff) >> 0;
9343 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9344 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9345 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9347 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9348 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9349 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9350 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9351 } else {
9352 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9353 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9354 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9355 color = getPixelColor(device, 320, 240);
9356 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);
9358 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9360 IDirect3DDevice9_SetTexture(device, 0, NULL);
9361 if(offscreenTexture) {
9362 IDirect3DTexture9_Release(offscreenTexture);
9364 if(offscreen) {
9365 IDirect3DSurface9_Release(offscreen);
9369 out:
9370 /* restore things */
9371 if(backbuffer) {
9372 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9373 IDirect3DSurface9_Release(backbuffer);
9377 static void tssargtemp_test(IDirect3DDevice9 *device)
9379 HRESULT hr;
9380 DWORD color;
9381 static const struct vertex quad[] = {
9382 {-1.0, -1.0, 0.1, 0x00ff0000},
9383 { 1.0, -1.0, 0.1, 0x00ff0000},
9384 {-1.0, 1.0, 0.1, 0x00ff0000},
9385 { 1.0, 1.0, 0.1, 0x00ff0000}
9387 D3DCAPS9 caps;
9389 memset(&caps, 0, sizeof(caps));
9390 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9391 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9392 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9393 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9394 return;
9397 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9398 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9400 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9401 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9402 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9403 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9405 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9406 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9407 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9408 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9409 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9410 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9412 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9413 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9414 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9415 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9416 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9417 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9419 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9420 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9423 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9424 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9425 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9427 hr = IDirect3DDevice9_BeginScene(device);
9428 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9429 if(SUCCEEDED(hr)) {
9430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9431 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9432 hr = IDirect3DDevice9_EndScene(device);
9433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9435 color = getPixelColor(device, 320, 240);
9436 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9437 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9439 /* Set stage 1 back to default */
9440 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9441 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9442 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9443 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9444 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9445 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9446 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9447 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9448 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9449 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9452 struct testdata
9454 DWORD idxVertex; /* number of instances in the first stream */
9455 DWORD idxColor; /* number of instances in the second stream */
9456 DWORD idxInstance; /* should be 1 ?? */
9457 DWORD color1; /* color 1 instance */
9458 DWORD color2; /* color 2 instance */
9459 DWORD color3; /* color 3 instance */
9460 DWORD color4; /* color 4 instance */
9461 WORD strVertex; /* specify which stream to use 0-2*/
9462 WORD strColor;
9463 WORD strInstance;
9466 static const struct testdata testcases[]=
9468 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9469 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9470 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9471 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9472 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9473 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9474 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9475 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9476 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9477 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9478 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9479 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9480 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9481 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9482 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9484 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9485 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9489 /* Drawing Indexed Geometry with instances*/
9490 static void stream_test(IDirect3DDevice9 *device)
9492 IDirect3DVertexBuffer9 *vb = NULL;
9493 IDirect3DVertexBuffer9 *vb2 = NULL;
9494 IDirect3DVertexBuffer9 *vb3 = NULL;
9495 IDirect3DIndexBuffer9 *ib = NULL;
9496 IDirect3DVertexDeclaration9 *pDecl = NULL;
9497 IDirect3DVertexShader9 *shader = NULL;
9498 HRESULT hr;
9499 BYTE *data;
9500 DWORD color;
9501 DWORD ind;
9502 unsigned i;
9504 const DWORD shader_code[] =
9506 0xfffe0101, /* vs_1_1 */
9507 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9508 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9509 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9510 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9511 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9512 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9513 0x0000ffff
9516 const float quad[][3] =
9518 {-0.5f, -0.5f, 1.1f}, /*0 */
9519 {-0.5f, 0.5f, 1.1f}, /*1 */
9520 { 0.5f, -0.5f, 1.1f}, /*2 */
9521 { 0.5f, 0.5f, 1.1f}, /*3 */
9524 const float vertcolor[][4] =
9526 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9527 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9528 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9529 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9532 /* 4 position for 4 instances */
9533 const float instancepos[][3] =
9535 {-0.6f,-0.6f, 0.0f},
9536 { 0.6f,-0.6f, 0.0f},
9537 { 0.6f, 0.6f, 0.0f},
9538 {-0.6f, 0.6f, 0.0f},
9541 short indices[] = {0, 1, 2, 1, 2, 3};
9543 D3DVERTEXELEMENT9 decl[] =
9545 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9546 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9547 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9548 D3DDECL_END()
9551 /* set the default value because it isn't done in wine? */
9552 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9553 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9555 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9556 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9557 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9559 /* check wrong cases */
9560 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9561 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9562 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9563 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9564 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9565 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9566 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9567 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9568 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9569 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9570 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9571 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9572 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9573 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9574 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9575 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9576 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9577 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9578 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9579 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9581 /* set the default value back */
9582 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9583 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9585 /* create all VertexBuffers*/
9586 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9587 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9588 if(!vb) {
9589 skip("Failed to create a vertex buffer\n");
9590 return;
9592 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9593 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9594 if(!vb2) {
9595 skip("Failed to create a vertex buffer\n");
9596 goto out;
9598 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9599 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9600 if(!vb3) {
9601 skip("Failed to create a vertex buffer\n");
9602 goto out;
9605 /* create IndexBuffer*/
9606 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9607 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9608 if(!ib) {
9609 skip("Failed to create a index buffer\n");
9610 goto out;
9613 /* copy all Buffers (Vertex + Index)*/
9614 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9615 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9616 memcpy(data, quad, sizeof(quad));
9617 hr = IDirect3DVertexBuffer9_Unlock(vb);
9618 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9619 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9620 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9621 memcpy(data, vertcolor, sizeof(vertcolor));
9622 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9623 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9624 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9625 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9626 memcpy(data, instancepos, sizeof(instancepos));
9627 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9628 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9629 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9630 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9631 memcpy(data, indices, sizeof(indices));
9632 hr = IDirect3DIndexBuffer9_Unlock(ib);
9633 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9635 /* create VertexShader */
9636 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9637 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9638 if(!shader) {
9639 skip("Failed to create a vetex shader\n");
9640 goto out;
9643 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9644 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9646 hr = IDirect3DDevice9_SetIndices(device, ib);
9647 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9649 /* run all tests */
9650 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9652 struct testdata act = testcases[i];
9653 decl[0].Stream = act.strVertex;
9654 decl[1].Stream = act.strColor;
9655 decl[2].Stream = act.strInstance;
9656 /* create VertexDeclarations */
9657 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9658 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9660 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9661 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9663 hr = IDirect3DDevice9_BeginScene(device);
9664 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9665 if(SUCCEEDED(hr))
9667 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9668 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9670 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9671 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9672 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9673 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9675 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9676 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9677 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9678 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9680 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9681 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9682 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9683 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9685 /* don't know if this is right (1*3 and 4*1)*/
9686 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9687 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9688 hr = IDirect3DDevice9_EndScene(device);
9689 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9691 /* set all StreamSource && StreamSourceFreq back to default */
9692 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9693 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9694 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9695 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9696 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9697 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9698 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9700 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9701 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9702 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9703 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9706 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9707 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9709 color = getPixelColor(device, 160, 360);
9710 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9711 color = getPixelColor(device, 480, 360);
9712 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9713 color = getPixelColor(device, 480, 120);
9714 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9715 color = getPixelColor(device, 160, 120);
9716 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9718 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9719 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9722 hr = IDirect3DDevice9_SetIndices(device, NULL);
9723 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9725 out:
9726 if(vb) IDirect3DVertexBuffer9_Release(vb);
9727 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9728 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9729 if(ib)IDirect3DIndexBuffer9_Release(ib);
9730 if(shader)IDirect3DVertexShader9_Release(shader);
9733 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9734 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9735 IDirect3DTexture9 *dsttex = NULL;
9736 HRESULT hr;
9737 DWORD color;
9738 D3DRECT r1 = {0, 0, 50, 50 };
9739 D3DRECT r2 = {50, 0, 100, 50 };
9740 D3DRECT r3 = {50, 50, 100, 100};
9741 D3DRECT r4 = {0, 50, 50, 100};
9742 const float quad[] = {
9743 -1.0, -1.0, 0.1, 0.0, 0.0,
9744 1.0, -1.0, 0.1, 1.0, 0.0,
9745 -1.0, 1.0, 0.1, 0.0, 1.0,
9746 1.0, 1.0, 0.1, 1.0, 1.0,
9749 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9750 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9752 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9753 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9754 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9755 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9757 if(!src || !dsttex) {
9758 skip("One or more test resources could not be created\n");
9759 goto cleanup;
9762 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9763 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9765 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9766 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9768 /* Clear the StretchRect destination for debugging */
9769 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9770 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9771 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9772 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9774 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9775 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9777 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9778 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9779 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9780 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9781 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9782 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9783 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9784 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9786 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9787 * the target -> texture GL blit path
9789 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9790 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9791 IDirect3DSurface9_Release(dst);
9793 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9794 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9796 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9797 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9798 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9799 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9800 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9801 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9802 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9803 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9805 hr = IDirect3DDevice9_BeginScene(device);
9806 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9807 if(SUCCEEDED(hr)) {
9808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9809 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9810 hr = IDirect3DDevice9_EndScene(device);
9811 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9814 color = getPixelColor(device, 160, 360);
9815 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9816 color = getPixelColor(device, 480, 360);
9817 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9818 color = getPixelColor(device, 480, 120);
9819 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9820 color = getPixelColor(device, 160, 120);
9821 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9822 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9823 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9825 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9826 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9827 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9828 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9830 cleanup:
9831 if(src) IDirect3DSurface9_Release(src);
9832 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9833 if(dsttex) IDirect3DTexture9_Release(dsttex);
9836 static void texop_test(IDirect3DDevice9 *device)
9838 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9839 IDirect3DTexture9 *texture = NULL;
9840 D3DLOCKED_RECT locked_rect;
9841 D3DCOLOR color;
9842 D3DCAPS9 caps;
9843 HRESULT hr;
9844 unsigned i;
9846 static const struct {
9847 float x, y, z;
9848 float s, t;
9849 D3DCOLOR diffuse;
9850 } quad[] = {
9851 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9852 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9853 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9854 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9857 static const D3DVERTEXELEMENT9 decl_elements[] = {
9858 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9859 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9860 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9861 D3DDECL_END()
9864 static const struct {
9865 D3DTEXTUREOP op;
9866 const char *name;
9867 DWORD caps_flag;
9868 D3DCOLOR result;
9869 } test_data[] = {
9870 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9871 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9872 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9873 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9874 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9875 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9876 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9877 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9878 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9879 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9880 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9881 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9882 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9883 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9884 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9885 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9886 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9887 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9888 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9889 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9890 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9891 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9892 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9895 memset(&caps, 0, sizeof(caps));
9896 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9897 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9899 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9900 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9901 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9902 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9904 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9905 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9906 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9907 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9908 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9909 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9910 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9911 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9912 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9914 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9915 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9916 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9917 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9919 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9921 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9922 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9925 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9927 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9929 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9932 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9934 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9936 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9938 skip("tex operation %s not supported\n", test_data[i].name);
9939 continue;
9942 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9943 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9945 hr = IDirect3DDevice9_BeginScene(device);
9946 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9949 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9951 hr = IDirect3DDevice9_EndScene(device);
9952 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9954 color = getPixelColor(device, 320, 240);
9955 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9956 test_data[i].name, color, test_data[i].result);
9958 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9959 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9962 if (texture) IDirect3DTexture9_Release(texture);
9963 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9966 static void yuv_color_test(IDirect3DDevice9 *device) {
9967 HRESULT hr;
9968 IDirect3DSurface9 *surface = NULL, *target = NULL;
9969 unsigned int fmt, i;
9970 D3DFORMAT format;
9971 const char *fmt_string;
9972 D3DLOCKED_RECT lr;
9973 IDirect3D9 *d3d;
9974 HRESULT color;
9975 DWORD ref_color_left, ref_color_right;
9977 struct {
9978 DWORD in; /* The input color */
9979 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9980 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9981 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9982 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9983 } test_data[] = {
9984 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9985 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9986 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9987 * that
9989 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9990 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9991 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9992 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9993 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9994 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9995 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9996 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9997 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9998 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9999 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10000 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10001 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10002 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10004 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10005 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10006 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10007 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10010 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10011 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10012 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10013 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10015 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10016 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10018 for(fmt = 0; fmt < 2; fmt++) {
10019 if(fmt == 0) {
10020 format = D3DFMT_UYVY;
10021 fmt_string = "D3DFMT_UYVY";
10022 } else {
10023 format = D3DFMT_YUY2;
10024 fmt_string = "D3DFMT_YUY2";
10027 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10028 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10030 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10031 D3DRTYPE_SURFACE, format) != D3D_OK) {
10032 skip("%s is not supported\n", fmt_string);
10033 continue;
10036 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10037 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10040 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10041 if(fmt == 0) {
10042 ref_color_left = test_data[i].uyvy_left;
10043 ref_color_right = test_data[i].uyvy_right;
10044 } else {
10045 ref_color_left = test_data[i].yuy2_left;
10046 ref_color_right = test_data[i].yuy2_right;
10049 memset(&lr, 0, sizeof(lr));
10050 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10051 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10052 *((DWORD *) lr.pBits) = test_data[i].in;
10053 hr = IDirect3DSurface9_UnlockRect(surface);
10054 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10057 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10058 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10059 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10061 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10062 * prevent running into precision problems, read a far left and far right pixel. In the future we may
10063 * want to add tests for the filtered pixels as well.
10065 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10066 * differently, so we need a max diff of 16
10068 color = getPixelColor(device, 40, 240);
10069 ok(color_match(color, ref_color_left, 18),
10070 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10071 test_data[i].in, color, ref_color_left, fmt_string);
10072 color = getPixelColor(device, 600, 240);
10073 ok(color_match(color, ref_color_right, 18),
10074 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10075 test_data[i].in, color, ref_color_right, fmt_string);
10076 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10077 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10079 IDirect3DSurface9_Release(surface);
10081 IDirect3DSurface9_Release(target);
10082 IDirect3D9_Release(d3d);
10085 static void texop_range_test(IDirect3DDevice9 *device)
10087 static const struct {
10088 float x, y, z;
10089 D3DCOLOR diffuse;
10090 } quad[] = {
10091 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10092 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10093 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10094 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10096 HRESULT hr;
10097 IDirect3DTexture9 *texture;
10098 D3DLOCKED_RECT locked_rect;
10099 D3DCAPS9 caps;
10100 DWORD color;
10102 /* We need ADD and SUBTRACT operations */
10103 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10104 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10105 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10106 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10107 return;
10109 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10110 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10111 return;
10114 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10115 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10116 /* Stage 1: result = diffuse(=1.0) + diffuse
10117 * stage 2: result = result - tfactor(= 0.5)
10119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10120 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10121 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10122 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10123 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10124 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10125 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10126 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10127 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10128 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10129 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10130 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10131 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10132 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10134 hr = IDirect3DDevice9_BeginScene(device);
10135 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10137 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10138 hr = IDirect3DDevice9_EndScene(device);
10139 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10141 color = getPixelColor(device, 320, 240);
10142 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10143 color);
10144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10145 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10147 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10148 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10149 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10150 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10151 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10152 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10153 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10154 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10155 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10157 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10158 * stage 2: result = result + diffuse(1.0)
10160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10161 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10163 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10164 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10165 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10166 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10167 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10168 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10169 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10170 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10171 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10172 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10173 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10175 hr = IDirect3DDevice9_BeginScene(device);
10176 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10177 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10178 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10179 hr = IDirect3DDevice9_EndScene(device);
10180 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10182 color = getPixelColor(device, 320, 240);
10183 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10184 color);
10185 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10186 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10188 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10189 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10190 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10191 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10192 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10193 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10194 IDirect3DTexture9_Release(texture);
10197 static void alphareplicate_test(IDirect3DDevice9 *device) {
10198 struct vertex quad[] = {
10199 { -1.0, -1.0, 0.1, 0x80ff00ff },
10200 { 1.0, -1.0, 0.1, 0x80ff00ff },
10201 { -1.0, 1.0, 0.1, 0x80ff00ff },
10202 { 1.0, 1.0, 0.1, 0x80ff00ff },
10204 HRESULT hr;
10205 DWORD color;
10207 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10208 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10210 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10211 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10213 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10214 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10215 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10216 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10218 hr = IDirect3DDevice9_BeginScene(device);
10219 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10220 if(SUCCEEDED(hr)) {
10221 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10222 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10223 hr = IDirect3DDevice9_EndScene(device);
10224 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10227 color = getPixelColor(device, 320, 240);
10228 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10229 color);
10230 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10231 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10233 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10234 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10238 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10239 HRESULT hr;
10240 D3DCAPS9 caps;
10241 DWORD color;
10242 struct vertex quad[] = {
10243 { -1.0, -1.0, 0.1, 0x408080c0 },
10244 { 1.0, -1.0, 0.1, 0x408080c0 },
10245 { -1.0, 1.0, 0.1, 0x408080c0 },
10246 { 1.0, 1.0, 0.1, 0x408080c0 },
10249 memset(&caps, 0, sizeof(caps));
10250 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10251 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10252 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10253 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10254 return;
10257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10258 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10260 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10261 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10263 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10264 * mov r0.a, diffuse.a
10265 * mov r0, r0.a
10267 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10268 * 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
10269 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10271 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10272 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10273 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10274 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10275 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10276 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10277 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10278 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10279 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10280 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10281 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10282 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10283 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10285 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10286 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10288 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10290 hr = IDirect3DDevice9_BeginScene(device);
10291 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10292 if(SUCCEEDED(hr)) {
10293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10294 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10295 hr = IDirect3DDevice9_EndScene(device);
10296 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10299 color = getPixelColor(device, 320, 240);
10300 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10301 color);
10302 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10303 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10305 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10306 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10307 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10308 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10309 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10313 static void zwriteenable_test(IDirect3DDevice9 *device) {
10314 HRESULT hr;
10315 DWORD color;
10316 struct vertex quad1[] = {
10317 { -1.0, -1.0, 0.1, 0x00ff0000},
10318 { -1.0, 1.0, 0.1, 0x00ff0000},
10319 { 1.0, -1.0, 0.1, 0x00ff0000},
10320 { 1.0, 1.0, 0.1, 0x00ff0000},
10322 struct vertex quad2[] = {
10323 { -1.0, -1.0, 0.9, 0x0000ff00},
10324 { -1.0, 1.0, 0.9, 0x0000ff00},
10325 { 1.0, -1.0, 0.9, 0x0000ff00},
10326 { 1.0, 1.0, 0.9, 0x0000ff00},
10329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10330 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10332 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10333 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10337 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10341 hr = IDirect3DDevice9_BeginScene(device);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10343 if(SUCCEEDED(hr)) {
10344 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10345 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10346 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10347 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10348 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10349 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10352 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10354 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10358 hr = IDirect3DDevice9_EndScene(device);
10359 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10362 color = getPixelColor(device, 320, 240);
10363 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10364 color);
10365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10366 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10369 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10372 static void alphatest_test(IDirect3DDevice9 *device) {
10373 #define ALPHATEST_PASSED 0x0000ff00
10374 #define ALPHATEST_FAILED 0x00ff0000
10375 struct {
10376 D3DCMPFUNC func;
10377 DWORD color_less;
10378 DWORD color_equal;
10379 DWORD color_greater;
10380 } testdata[] = {
10381 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10382 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10383 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10384 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10385 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10386 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10387 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10388 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10390 unsigned int i, j;
10391 HRESULT hr;
10392 DWORD color;
10393 struct vertex quad[] = {
10394 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10395 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10396 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10397 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10399 D3DCAPS9 caps;
10401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10404 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10406 for(j = 0; j < 2; j++) {
10407 if(j == 1) {
10408 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10409 * the alpha test either for performance reasons(floating point RTs) or to work
10410 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10411 * codepath for ffp and shader in this case, and the test should cover both
10413 IDirect3DPixelShader9 *ps;
10414 DWORD shader_code[] = {
10415 0xffff0101, /* ps_1_1 */
10416 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10417 0x0000ffff /* end */
10419 memset(&caps, 0, sizeof(caps));
10420 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10421 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10422 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10423 break;
10426 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10427 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10428 IDirect3DDevice9_SetPixelShader(device, ps);
10429 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10430 IDirect3DPixelShader9_Release(ps);
10433 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10435 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10438 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10441 hr = IDirect3DDevice9_BeginScene(device);
10442 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10443 if(SUCCEEDED(hr)) {
10444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10445 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10446 hr = IDirect3DDevice9_EndScene(device);
10447 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10449 color = getPixelColor(device, 320, 240);
10450 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10451 color, testdata[i].color_less, testdata[i].func);
10452 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10453 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10455 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10456 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10459 hr = IDirect3DDevice9_BeginScene(device);
10460 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10461 if(SUCCEEDED(hr)) {
10462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10463 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10464 hr = IDirect3DDevice9_EndScene(device);
10465 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10467 color = getPixelColor(device, 320, 240);
10468 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10469 color, testdata[i].color_equal, testdata[i].func);
10470 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10471 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10473 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10474 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10476 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10477 hr = IDirect3DDevice9_BeginScene(device);
10478 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10479 if(SUCCEEDED(hr)) {
10480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10481 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10482 hr = IDirect3DDevice9_EndScene(device);
10483 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10485 color = getPixelColor(device, 320, 240);
10486 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10487 color, testdata[i].color_greater, testdata[i].func);
10488 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10489 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10493 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10494 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10495 IDirect3DDevice9_SetPixelShader(device, NULL);
10496 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10499 static void sincos_test(IDirect3DDevice9 *device) {
10500 const DWORD sin_shader_code[] = {
10501 0xfffe0200, /* vs_2_0 */
10502 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10503 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10504 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10505 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10506 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10507 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10508 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10509 0x0000ffff /* end */
10511 const DWORD cos_shader_code[] = {
10512 0xfffe0200, /* vs_2_0 */
10513 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10514 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10515 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10516 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10517 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10518 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10519 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10520 0x0000ffff /* end */
10522 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10523 HRESULT hr;
10524 struct {
10525 float x, y, z;
10526 } data[1280];
10527 unsigned int i;
10528 float sincosc1[4] = {D3DSINCOSCONST1};
10529 float sincosc2[4] = {D3DSINCOSCONST2};
10531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10532 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10534 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10535 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10536 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10537 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10538 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10539 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10540 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10541 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10542 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10543 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10545 /* Generate a point from -1 to 1 every 0.5 pixels */
10546 for(i = 0; i < 1280; i++) {
10547 data[i].x = (-640.0 + i) / 640.0;
10548 data[i].y = 0.0;
10549 data[i].z = 0.1;
10552 hr = IDirect3DDevice9_BeginScene(device);
10553 if(SUCCEEDED(hr)) {
10554 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10555 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10556 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10557 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10559 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10560 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10562 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10564 hr = IDirect3DDevice9_EndScene(device);
10565 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10568 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10569 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10571 IDirect3DDevice9_SetVertexShader(device, NULL);
10572 IDirect3DVertexShader9_Release(sin_shader);
10573 IDirect3DVertexShader9_Release(cos_shader);
10576 static void loop_index_test(IDirect3DDevice9 *device) {
10577 const DWORD shader_code[] = {
10578 0xfffe0200, /* vs_2_0 */
10579 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10580 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10581 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10582 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10583 0x0000001d, /* endloop */
10584 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10585 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10586 0x0000ffff /* END */
10588 IDirect3DVertexShader9 *shader;
10589 HRESULT hr;
10590 DWORD color;
10591 const float quad[] = {
10592 -1.0, -1.0, 0.1,
10593 1.0, -1.0, 0.1,
10594 -1.0, 1.0, 0.1,
10595 1.0, 1.0, 0.1
10597 const float zero[4] = {0, 0, 0, 0};
10598 const float one[4] = {1, 1, 1, 1};
10599 int i0[4] = {2, 10, -3, 0};
10600 float values[4];
10602 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10603 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10604 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10605 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10606 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10607 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10608 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10609 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10611 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10612 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10613 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10614 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10615 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10616 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10617 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10618 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10619 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10620 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10621 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10622 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10623 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10624 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10625 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10626 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10627 values[0] = 1.0;
10628 values[1] = 1.0;
10629 values[2] = 0.0;
10630 values[3] = 0.0;
10631 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10632 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10633 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10634 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10635 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10636 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10637 values[0] = -1.0;
10638 values[1] = 0.0;
10639 values[2] = 0.0;
10640 values[3] = 0.0;
10641 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10642 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10643 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10644 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10645 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10646 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10647 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10648 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10649 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10650 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10652 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10653 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10655 hr = IDirect3DDevice9_BeginScene(device);
10656 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10657 if(SUCCEEDED(hr))
10659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10660 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10661 hr = IDirect3DDevice9_EndScene(device);
10662 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10664 color = getPixelColor(device, 320, 240);
10665 ok(color_match(color, 0x0000ff00, 1),
10666 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10667 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10668 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10670 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10671 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10672 IDirect3DVertexShader9_Release(shader);
10675 static void sgn_test(IDirect3DDevice9 *device) {
10676 const DWORD shader_code[] = {
10677 0xfffe0200, /* vs_2_0 */
10678 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10679 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10680 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10681 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10682 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10683 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10684 0x0000ffff /* end */
10686 IDirect3DVertexShader9 *shader;
10687 HRESULT hr;
10688 DWORD color;
10689 const float quad[] = {
10690 -1.0, -1.0, 0.1,
10691 1.0, -1.0, 0.1,
10692 -1.0, 1.0, 0.1,
10693 1.0, 1.0, 0.1
10696 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10697 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10698 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10699 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10700 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10701 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10702 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10703 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10705 hr = IDirect3DDevice9_BeginScene(device);
10706 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10707 if(SUCCEEDED(hr))
10709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10710 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10711 hr = IDirect3DDevice9_EndScene(device);
10712 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10714 color = getPixelColor(device, 320, 240);
10715 ok(color_match(color, 0x008000ff, 1),
10716 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10717 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10718 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10720 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10721 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10722 IDirect3DVertexShader9_Release(shader);
10725 static void viewport_test(IDirect3DDevice9 *device) {
10726 HRESULT hr;
10727 DWORD color;
10728 D3DVIEWPORT9 vp, old_vp;
10729 const float quad[] =
10731 -0.5, -0.5, 0.1,
10732 0.5, -0.5, 0.1,
10733 -0.5, 0.5, 0.1,
10734 0.5, 0.5, 0.1
10737 memset(&old_vp, 0, sizeof(old_vp));
10738 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10739 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10744 /* Test a viewport with Width and Height bigger than the surface dimensions
10746 * TODO: Test Width < surface.width, but X + Width > surface.width
10747 * TODO: Test Width < surface.width, what happens with the height?
10749 memset(&vp, 0, sizeof(vp));
10750 vp.X = 0;
10751 vp.Y = 0;
10752 vp.Width = 10000;
10753 vp.Height = 10000;
10754 vp.MinZ = 0.0;
10755 vp.MaxZ = 0.0;
10756 hr = IDirect3DDevice9_SetViewport(device, &vp);
10757 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10759 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10760 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10761 hr = IDirect3DDevice9_BeginScene(device);
10762 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10763 if(SUCCEEDED(hr))
10765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10766 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10767 hr = IDirect3DDevice9_EndScene(device);
10768 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10771 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10772 color = getPixelColor(device, 158, 118);
10773 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10774 color = getPixelColor(device, 162, 118);
10775 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10776 color = getPixelColor(device, 158, 122);
10777 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10778 color = getPixelColor(device, 162, 122);
10779 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10781 color = getPixelColor(device, 478, 358);
10782 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10783 color = getPixelColor(device, 482, 358);
10784 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10785 color = getPixelColor(device, 478, 362);
10786 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10787 color = getPixelColor(device, 482, 362);
10788 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10790 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10791 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10793 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10794 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10797 /* This test tests depth clamping / clipping behaviour:
10798 * - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10799 * minimum/maximum z value.
10800 * - The viewport's MinZ/MaxZ is irrelevant for this.
10801 * - When D3DRS_CLIPPING is enabled depth values are clipped.
10802 * - Pretransformed vertices behave the same as regular vertices.
10804 static void depth_clamp_test(IDirect3DDevice9 *device)
10806 const struct tvertex quad1[] =
10808 { 0, 0, 5.0f, 1.0, 0xff002b7f},
10809 { 640, 0, 5.0f, 1.0, 0xff002b7f},
10810 { 0, 480, 5.0f, 1.0, 0xff002b7f},
10811 { 640, 480, 5.0f, 1.0, 0xff002b7f},
10813 const struct tvertex quad2[] =
10815 { 0, 300, 10.0f, 1.0, 0xfff9e814},
10816 { 640, 300, 10.0f, 1.0, 0xfff9e814},
10817 { 0, 360, 10.0f, 1.0, 0xfff9e814},
10818 { 640, 360, 10.0f, 1.0, 0xfff9e814},
10820 const struct vertex quad3[] =
10822 {-0.65, 0.55, 5.0f, 0xffffffff},
10823 {-0.35, 0.55, 5.0f, 0xffffffff},
10824 {-0.65, 0.15, 5.0f, 0xffffffff},
10825 {-0.35, 0.15, 5.0f, 0xffffffff},
10827 const struct vertex quad4[] =
10829 {-0.87, 0.83, 10.0f, 0xffffffff},
10830 {-0.65, 0.83, 10.0f, 0xffffffff},
10831 {-0.87, 0.55, 10.0f, 0xffffffff},
10832 {-0.65, 0.55, 10.0f, 0xffffffff},
10834 const struct vertex quad5[] =
10836 { -0.5, 0.5, 10.0f, 0xff14f914},
10837 { 0.5, 0.5, 10.0f, 0xff14f914},
10838 { -0.5, -0.5, 10.0f, 0xff14f914},
10839 { 0.5, -0.5, 10.0f, 0xff14f914},
10841 const struct tvertex quad6[] =
10843 { 0, 120, 10.0f, 1.0, 0xfff91414},
10844 { 640, 120, 10.0f, 1.0, 0xfff91414},
10845 { 0, 180, 10.0f, 1.0, 0xfff91414},
10846 { 640, 180, 10.0f, 1.0, 0xfff91414},
10849 D3DVIEWPORT9 vp;
10850 D3DCOLOR color;
10851 HRESULT hr;
10853 vp.X = 0;
10854 vp.Y = 0;
10855 vp.Width = 640;
10856 vp.Height = 480;
10857 vp.MinZ = 0.0;
10858 vp.MaxZ = 7.5;
10860 hr = IDirect3DDevice9_SetViewport(device, &vp);
10861 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10863 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10864 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10867 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10869 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10871 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10873 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10875 hr = IDirect3DDevice9_BeginScene(device);
10876 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10878 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10879 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10882 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10884 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10886 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10887 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10890 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10892 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10895 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10898 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10900 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10901 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10903 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10904 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10906 hr = IDirect3DDevice9_EndScene(device);
10907 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10909 color = getPixelColor(device, 75, 75);
10910 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10911 color = getPixelColor(device, 150, 150);
10912 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10913 color = getPixelColor(device, 320, 240);
10914 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10915 color = getPixelColor(device, 320, 330);
10916 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10917 color = getPixelColor(device, 320, 330);
10918 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10920 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10921 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10923 vp.MinZ = 0.0;
10924 vp.MaxZ = 1.0;
10925 hr = IDirect3DDevice9_SetViewport(device, &vp);
10926 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10929 static void depth_buffer_test(IDirect3DDevice9 *device)
10931 static const struct vertex quad1[] =
10933 { -1.0, 1.0, 0.33f, 0xff00ff00},
10934 { 1.0, 1.0, 0.33f, 0xff00ff00},
10935 { -1.0, -1.0, 0.33f, 0xff00ff00},
10936 { 1.0, -1.0, 0.33f, 0xff00ff00},
10938 static const struct vertex quad2[] =
10940 { -1.0, 1.0, 0.50f, 0xffff00ff},
10941 { 1.0, 1.0, 0.50f, 0xffff00ff},
10942 { -1.0, -1.0, 0.50f, 0xffff00ff},
10943 { 1.0, -1.0, 0.50f, 0xffff00ff},
10945 static const struct vertex quad3[] =
10947 { -1.0, 1.0, 0.66f, 0xffff0000},
10948 { 1.0, 1.0, 0.66f, 0xffff0000},
10949 { -1.0, -1.0, 0.66f, 0xffff0000},
10950 { 1.0, -1.0, 0.66f, 0xffff0000},
10952 static const DWORD expected_colors[4][4] =
10954 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10955 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10956 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10957 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10960 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10961 unsigned int i, j;
10962 D3DVIEWPORT9 vp;
10963 D3DCOLOR color;
10964 HRESULT hr;
10966 vp.X = 0;
10967 vp.Y = 0;
10968 vp.Width = 640;
10969 vp.Height = 480;
10970 vp.MinZ = 0.0;
10971 vp.MaxZ = 1.0;
10973 hr = IDirect3DDevice9_SetViewport(device, &vp);
10974 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10977 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10979 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10981 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10983 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10984 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10985 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10987 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10988 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10989 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10990 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10991 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10992 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10993 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10994 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10995 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10996 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10997 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10999 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11000 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11001 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11002 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11004 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11005 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11006 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11007 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11009 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11010 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11011 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11012 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11014 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11015 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11016 hr = IDirect3DDevice9_BeginScene(device);
11017 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11018 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11019 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11020 hr = IDirect3DDevice9_EndScene(device);
11021 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11023 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11024 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11025 IDirect3DSurface9_Release(backbuffer);
11026 IDirect3DSurface9_Release(rt3);
11027 IDirect3DSurface9_Release(rt2);
11028 IDirect3DSurface9_Release(rt1);
11030 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11031 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11033 hr = IDirect3DDevice9_BeginScene(device);
11034 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11036 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11039 hr = IDirect3DDevice9_EndScene(device);
11040 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11042 for (i = 0; i < 4; ++i)
11044 for (j = 0; j < 4; ++j)
11046 unsigned int x = 80 * ((2 * j) + 1);
11047 unsigned int y = 60 * ((2 * i) + 1);
11048 color = getPixelColor(device, x, y);
11049 ok(color_match(color, expected_colors[i][j], 0),
11050 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11054 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11055 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11058 static void shadow_test(IDirect3DDevice9 *device)
11060 static const DWORD ps_code[] =
11062 0xffff0200, /* ps_2_0 */
11063 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11064 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11065 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11066 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11067 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11068 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11069 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11070 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11071 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11072 0x0000ffff, /* end */
11074 struct
11076 D3DFORMAT format;
11077 const char *name;
11079 formats[] =
11081 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11082 {D3DFMT_D32, "D3DFMT_D32"},
11083 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11084 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11085 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11086 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11087 {D3DFMT_D16, "D3DFMT_D16"},
11088 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11089 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11091 struct
11093 float x, y, z;
11094 float s, t, p, q;
11096 quad[] =
11098 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11099 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11100 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11101 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11103 struct
11105 UINT x, y;
11106 D3DCOLOR color;
11108 expected_colors[] =
11110 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11111 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11112 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11113 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11114 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11115 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11116 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11117 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11120 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11121 IDirect3DPixelShader9 *ps;
11122 IDirect3D9 *d3d9;
11123 D3DCAPS9 caps;
11124 HRESULT hr;
11125 UINT i;
11127 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11128 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11129 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11131 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11132 return;
11135 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11136 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11137 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11138 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11139 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11140 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11142 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11143 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11144 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11145 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11146 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11149 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11151 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11153 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11155 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11157 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11160 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11161 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11162 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11163 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11164 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11165 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11166 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11168 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11170 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11172 D3DFORMAT format = formats[i].format;
11173 IDirect3DTexture9 *texture;
11174 IDirect3DSurface9 *ds;
11175 unsigned int j;
11177 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11178 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11179 if (FAILED(hr)) continue;
11181 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11182 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11183 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11185 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11186 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11188 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11189 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11191 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11192 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11194 IDirect3DDevice9_SetPixelShader(device, NULL);
11195 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11197 /* Setup the depth/stencil surface. */
11198 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11199 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11201 hr = IDirect3DDevice9_BeginScene(device);
11202 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11204 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11205 hr = IDirect3DDevice9_EndScene(device);
11206 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11208 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11209 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11210 IDirect3DSurface9_Release(ds);
11212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11213 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11215 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11216 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11218 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11219 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11221 /* Do the actual shadow mapping. */
11222 hr = IDirect3DDevice9_BeginScene(device);
11223 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11225 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11226 hr = IDirect3DDevice9_EndScene(device);
11227 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11229 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11230 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11231 IDirect3DTexture9_Release(texture);
11233 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11235 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11236 ok(color_match(color, expected_colors[j].color, 0),
11237 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11238 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11239 formats[i].name, color);
11242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11243 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11246 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11247 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11248 IDirect3DPixelShader9_Release(ps);
11250 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11251 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11252 IDirect3DSurface9_Release(original_ds);
11254 IDirect3DSurface9_Release(original_rt);
11255 IDirect3DSurface9_Release(rt);
11257 IDirect3D9_Release(d3d9);
11260 START_TEST(visual)
11262 IDirect3DDevice9 *device_ptr;
11263 D3DCAPS9 caps;
11264 HRESULT hr;
11265 DWORD color;
11267 d3d9_handle = LoadLibraryA("d3d9.dll");
11268 if (!d3d9_handle)
11270 skip("Could not load d3d9.dll\n");
11271 return;
11274 device_ptr = init_d3d9();
11275 if (!device_ptr)
11277 skip("Creating the device failed\n");
11278 return;
11281 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11283 /* Check for the reliability of the returned data */
11284 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11285 if(FAILED(hr))
11287 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11288 goto cleanup;
11291 color = getPixelColor(device_ptr, 1, 1);
11292 if(color !=0x00ff0000)
11294 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11295 goto cleanup;
11297 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11299 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11300 if(FAILED(hr))
11302 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11303 goto cleanup;
11306 color = getPixelColor(device_ptr, 639, 479);
11307 if(color != 0x0000ddee)
11309 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11310 goto cleanup;
11312 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11314 /* Now execute the real tests */
11315 depth_clamp_test(device_ptr);
11316 stretchrect_test(device_ptr);
11317 lighting_test(device_ptr);
11318 clear_test(device_ptr);
11319 color_fill_test(device_ptr);
11320 fog_test(device_ptr);
11321 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11323 test_cube_wrap(device_ptr);
11324 } else {
11325 skip("No cube texture support\n");
11327 z_range_test(device_ptr);
11328 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11330 maxmip_test(device_ptr);
11332 else
11334 skip("No mipmap support\n");
11336 offscreen_test(device_ptr);
11337 alpha_test(device_ptr);
11338 shademode_test(device_ptr);
11339 srgbtexture_test(device_ptr);
11340 release_buffer_test(device_ptr);
11341 float_texture_test(device_ptr);
11342 g16r16_texture_test(device_ptr);
11343 pixelshader_blending_test(device_ptr);
11344 texture_transform_flags_test(device_ptr);
11345 autogen_mipmap_test(device_ptr);
11346 fixed_function_decl_test(device_ptr);
11347 conditional_np2_repeat_test(device_ptr);
11348 fixed_function_bumpmap_test(device_ptr);
11349 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11350 stencil_cull_test(device_ptr);
11351 } else {
11352 skip("No two sided stencil support\n");
11354 pointsize_test(device_ptr);
11355 tssargtemp_test(device_ptr);
11356 np2_stretch_rect_test(device_ptr);
11357 yuv_color_test(device_ptr);
11358 zwriteenable_test(device_ptr);
11359 alphatest_test(device_ptr);
11360 viewport_test(device_ptr);
11362 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11364 test_constant_clamp_vs(device_ptr);
11365 test_compare_instructions(device_ptr);
11367 else skip("No vs_1_1 support\n");
11369 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11371 test_mova(device_ptr);
11372 loop_index_test(device_ptr);
11373 sincos_test(device_ptr);
11374 sgn_test(device_ptr);
11375 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11376 test_vshader_input(device_ptr);
11377 test_vshader_float16(device_ptr);
11378 stream_test(device_ptr);
11379 } else {
11380 skip("No vs_3_0 support\n");
11383 else skip("No vs_2_0 support\n");
11385 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11387 fog_with_shader_test(device_ptr);
11388 fog_srgbwrite_test(device_ptr);
11390 else skip("No vs_1_1 and ps_1_1 support\n");
11392 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11394 texbem_test(device_ptr);
11395 texdepth_test(device_ptr);
11396 texkill_test(device_ptr);
11397 x8l8v8u8_test(device_ptr);
11398 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11399 constant_clamp_ps_test(device_ptr);
11400 cnd_test(device_ptr);
11401 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11402 dp2add_ps_test(device_ptr);
11403 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
11404 nested_loop_test(device_ptr);
11405 fixed_function_varying_test(device_ptr);
11406 vFace_register_test(device_ptr);
11407 vpos_register_test(device_ptr);
11408 multiple_rendertargets_test(device_ptr);
11409 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11410 vshader_version_varying_test(device_ptr);
11411 pshader_version_varying_test(device_ptr);
11412 } else {
11413 skip("No vs_3_0 support\n");
11415 } else {
11416 skip("No ps_3_0 support\n");
11418 } else {
11419 skip("No ps_2_0 support\n");
11423 else skip("No ps_1_1 support\n");
11425 texop_test(device_ptr);
11426 texop_range_test(device_ptr);
11427 alphareplicate_test(device_ptr);
11428 dp3_alpha_test(device_ptr);
11429 depth_buffer_test(device_ptr);
11430 shadow_test(device_ptr);
11432 cleanup:
11433 if(device_ptr) {
11434 D3DPRESENT_PARAMETERS present_parameters;
11435 IDirect3DSwapChain9 *swapchain;
11436 ULONG ref;
11438 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11439 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11440 IDirect3DSwapChain9_Release(swapchain);
11441 ref = IDirect3DDevice9_Release(device_ptr);
11442 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11443 DestroyWindow(present_parameters.hDeviceWindow);