push 149f0a5527ac85057a8ef03858d34d91c36f97e8
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob15ddd44bfcb4d0c053d525ee3db2b4e16b0109b5
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 trace("viewport: X %u, Y %u, W %u, H %u, MinZ %.8e, MaxZ %.8e.\n",
499 old_vp.X, old_vp.Y, old_vp.Width, old_vp.Height, old_vp.MinZ, old_vp.MaxZ);
501 vp.X = 160;
502 vp.Y = 120;
503 vp.Width = 160;
504 vp.Height = 120;
505 vp.MinZ = 0.0;
506 vp.MaxZ = 1.0;
507 hr = IDirect3DDevice9_SetViewport(device, &vp);
508 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
509 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
510 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
512 vp.X = 320;
513 vp.Y = 240;
514 vp.Width = 320;
515 vp.Height = 240;
516 vp.MinZ = 0.0;
517 vp.MaxZ = 1.0;
518 hr = IDirect3DDevice9_SetViewport(device, &vp);
519 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
520 rect[0].x1 = 160;
521 rect[0].y1 = 120;
522 rect[0].x2 = 480;
523 rect[0].y2 = 360;
524 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
525 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
527 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
528 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
530 color = getPixelColor(device, 158, 118);
531 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
532 color = getPixelColor(device, 162, 118);
533 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
534 color = getPixelColor(device, 158, 122);
535 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
536 color = getPixelColor(device, 162, 122);
537 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
539 color = getPixelColor(device, 318, 238);
540 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
541 color = getPixelColor(device, 322, 238);
542 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
543 color = getPixelColor(device, 318, 242);
544 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
545 color = getPixelColor(device, 322, 242);
546 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
548 color = getPixelColor(device, 478, 358);
549 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
550 color = getPixelColor(device, 482, 358);
551 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
552 color = getPixelColor(device, 478, 362);
553 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
554 color = getPixelColor(device, 482, 362);
555 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
557 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
562 scissor.left = 160;
563 scissor.right = 480;
564 scissor.top = 120;
565 scissor.bottom = 360;
566 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
567 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
569 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
571 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
572 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
574 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
577 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
579 color = getPixelColor(device, 158, 118);
580 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
581 color = getPixelColor(device, 162, 118);
582 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
583 color = getPixelColor(device, 158, 122);
584 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
585 color = getPixelColor(device, 162, 122);
586 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
588 color = getPixelColor(device, 158, 358);
589 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
590 color = getPixelColor(device, 162, 358);
591 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
592 color = getPixelColor(device, 158, 358);
593 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
594 color = getPixelColor(device, 162, 362);
595 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
597 color = getPixelColor(device, 478, 118);
598 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
599 color = getPixelColor(device, 478, 122);
600 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
601 color = getPixelColor(device, 482, 122);
602 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
603 color = getPixelColor(device, 482, 358);
604 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
606 color = getPixelColor(device, 478, 358);
607 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
608 color = getPixelColor(device, 478, 362);
609 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
610 color = getPixelColor(device, 482, 358);
611 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612 color = getPixelColor(device, 482, 362);
613 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
615 color = getPixelColor(device, 318, 238);
616 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
617 color = getPixelColor(device, 318, 242);
618 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
619 color = getPixelColor(device, 322, 238);
620 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
621 color = getPixelColor(device, 322, 242);
622 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
624 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
626 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
627 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
629 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
631 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
632 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
635 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
637 /* Colorwriteenable does not affect the clear */
638 color = getPixelColor(device, 320, 240);
639 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
641 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
644 typedef struct {
645 float in[4];
646 DWORD out;
647 } test_data_t;
650 * c7 mova ARGB mov ARGB
651 * -2.4 -2 0x00ffff00 -3 0x00ff0000
652 * -1.6 -2 0x00ffff00 -2 0x00ffff00
653 * -0.4 0 0x0000ffff -1 0x0000ff00
654 * 0.4 0 0x0000ffff 0 0x0000ffff
655 * 1.6 2 0x00ff00ff 1 0x000000ff
656 * 2.4 2 0x00ff00ff 2 0x00ff00ff
658 static void test_mova(IDirect3DDevice9 *device)
660 static const DWORD mova_test[] = {
661 0xfffe0200, /* vs_2_0 */
662 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
663 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
664 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
665 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
666 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
667 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
668 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
669 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
670 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
671 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
672 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
673 0x0000ffff /* END */
675 static const DWORD mov_test[] = {
676 0xfffe0101, /* vs_1_1 */
677 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
678 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
679 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
680 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
681 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
682 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
683 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
684 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
685 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
686 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
687 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
688 0x0000ffff /* END */
691 static const test_data_t test_data[2][6] = {
693 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
694 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
695 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
696 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
697 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
698 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
701 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
702 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
703 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
704 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
705 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
706 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
710 static const float quad[][3] = {
711 {-1.0f, -1.0f, 0.0f},
712 {-1.0f, 1.0f, 0.0f},
713 { 1.0f, -1.0f, 0.0f},
714 { 1.0f, 1.0f, 0.0f},
717 static const D3DVERTEXELEMENT9 decl_elements[] = {
718 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
719 D3DDECL_END()
722 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
723 IDirect3DVertexShader9 *mova_shader = NULL;
724 IDirect3DVertexShader9 *mov_shader = NULL;
725 HRESULT hr;
726 UINT i, j;
728 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
729 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
730 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
731 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
732 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
733 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
734 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
735 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
737 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
738 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
739 for(j = 0; j < 2; ++j)
741 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
743 DWORD color;
745 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
746 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
748 hr = IDirect3DDevice9_BeginScene(device);
749 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
752 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
754 hr = IDirect3DDevice9_EndScene(device);
755 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
757 color = getPixelColor(device, 320, 240);
758 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
759 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
761 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
762 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
764 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
765 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
767 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
768 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
771 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
772 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
774 IDirect3DVertexDeclaration9_Release(vertex_declaration);
775 IDirect3DVertexShader9_Release(mova_shader);
776 IDirect3DVertexShader9_Release(mov_shader);
779 struct sVertex {
780 float x, y, z;
781 DWORD diffuse;
782 DWORD specular;
785 struct sVertexT {
786 float x, y, z, rhw;
787 DWORD diffuse;
788 DWORD specular;
791 static void fog_test(IDirect3DDevice9 *device)
793 HRESULT hr;
794 D3DCOLOR color;
795 float start = 0.0f, end = 1.0f;
796 D3DCAPS9 caps;
797 int i;
799 /* Gets full z based fog with linear fog, no fog with specular color */
800 struct sVertex unstransformed_1[] = {
801 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
802 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
803 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
804 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
806 /* Ok, I am too lazy to deal with transform matrices */
807 struct sVertex unstransformed_2[] = {
808 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
809 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
810 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
811 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
813 /* Untransformed ones. Give them a different diffuse color to make the test look
814 * nicer. It also makes making sure that they are drawn correctly easier.
816 struct sVertexT transformed_1[] = {
817 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
818 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
819 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
820 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
822 struct sVertexT transformed_2[] = {
823 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
824 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
825 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
826 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
828 struct vertex rev_fog_quads[] = {
829 {-1.0, -1.0, 0.1, 0x000000ff},
830 {-1.0, 0.0, 0.1, 0x000000ff},
831 { 0.0, 0.0, 0.1, 0x000000ff},
832 { 0.0, -1.0, 0.1, 0x000000ff},
834 { 0.0, -1.0, 0.9, 0x000000ff},
835 { 0.0, 0.0, 0.9, 0x000000ff},
836 { 1.0, 0.0, 0.9, 0x000000ff},
837 { 1.0, -1.0, 0.9, 0x000000ff},
839 { 0.0, 0.0, 0.4, 0x000000ff},
840 { 0.0, 1.0, 0.4, 0x000000ff},
841 { 1.0, 1.0, 0.4, 0x000000ff},
842 { 1.0, 0.0, 0.4, 0x000000ff},
844 {-1.0, 0.0, 0.7, 0x000000ff},
845 {-1.0, 1.0, 0.7, 0x000000ff},
846 { 0.0, 1.0, 0.7, 0x000000ff},
847 { 0.0, 0.0, 0.7, 0x000000ff},
849 WORD Indices[] = {0, 1, 2, 2, 3, 0};
851 memset(&caps, 0, sizeof(caps));
852 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
853 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
854 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
855 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
857 /* Setup initial states: No lighting, fog on, fog color */
858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
859 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
861 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
863 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
865 /* First test: Both table fog and vertex fog off */
866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
867 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
869 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
871 /* Start = 0, end = 1. Should be default, but set them */
872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
873 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
875 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
877 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
879 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
880 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
881 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
882 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
883 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
884 sizeof(unstransformed_1[0]));
885 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
887 /* That makes it use the Z value */
888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
889 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
890 /* Untransformed, vertex fog != none (or table fog != none):
891 * Use the Z value as input into the equation
893 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
894 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
895 sizeof(unstransformed_1[0]));
896 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
898 /* transformed verts */
899 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
900 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
901 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
902 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
903 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
904 sizeof(transformed_1[0]));
905 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
908 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
909 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
910 * equation
912 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
913 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
914 sizeof(transformed_2[0]));
915 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
917 hr = IDirect3DDevice9_EndScene(device);
918 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
920 else
922 ok(FALSE, "BeginScene failed\n");
925 color = getPixelColor(device, 160, 360);
926 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
927 color = getPixelColor(device, 160, 120);
928 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
929 color = getPixelColor(device, 480, 120);
930 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
931 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
933 color = getPixelColor(device, 480, 360);
934 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
936 else
938 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
939 * The settings above result in no fogging with vertex fog
941 color = getPixelColor(device, 480, 120);
942 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
943 trace("Info: Table fog not supported by this device\n");
945 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
947 /* Now test the special case fogstart == fogend */
948 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
949 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
951 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
953 start = 512;
954 end = 512;
955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
956 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
958 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
960 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
961 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
963 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
965 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
967 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
968 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
969 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
970 * The third transformed quad remains unfogged because the fogcoords are read from the specular
971 * color and has fixed fogstart and fogend.
973 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
975 sizeof(unstransformed_1[0]));
976 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
977 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
978 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
979 sizeof(unstransformed_1[0]));
980 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
982 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
983 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
984 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
985 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
986 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
987 sizeof(transformed_1[0]));
988 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
990 hr = IDirect3DDevice9_EndScene(device);
991 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
993 else
995 ok(FALSE, "BeginScene failed\n");
997 color = getPixelColor(device, 160, 360);
998 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
999 color = getPixelColor(device, 160, 120);
1000 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1001 color = getPixelColor(device, 480, 120);
1002 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1003 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1005 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1006 * but without shaders it seems to work everywhere
1008 end = 0.2;
1009 start = 0.8;
1010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1011 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1013 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1014 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1015 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1017 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1018 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1019 * so skip this for now
1021 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1022 const char *mode = (i ? "table" : "vertex");
1023 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1024 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1026 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1028 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1029 hr = IDirect3DDevice9_BeginScene(device);
1030 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1031 if(SUCCEEDED(hr)) {
1032 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1033 4, 5, 6, 6, 7, 4,
1034 8, 9, 10, 10, 11, 8,
1035 12, 13, 14, 14, 15, 12};
1037 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1038 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1039 sizeof(rev_fog_quads[0]));
1040 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1042 hr = IDirect3DDevice9_EndScene(device);
1043 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1045 color = getPixelColor(device, 160, 360);
1046 ok(color_match(color, 0x0000ff00, 1),
1047 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1049 color = getPixelColor(device, 160, 120);
1050 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1051 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1053 color = getPixelColor(device, 480, 120);
1054 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1055 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1057 color = getPixelColor(device, 480, 360);
1058 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1060 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1062 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1063 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1064 break;
1067 /* Turn off the fog master switch to avoid confusing other tests */
1068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1069 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1070 start = 0.0;
1071 end = 1.0;
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_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1077 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1079 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1082 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1083 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1084 * regardless of the actual addressing mode set. */
1085 static void test_cube_wrap(IDirect3DDevice9 *device)
1087 static const float quad[][6] = {
1088 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1089 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1090 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1091 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1094 static const D3DVERTEXELEMENT9 decl_elements[] = {
1095 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1096 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1097 D3DDECL_END()
1100 static const struct {
1101 D3DTEXTUREADDRESS mode;
1102 const char *name;
1103 } address_modes[] = {
1104 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1105 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1106 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1107 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1108 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1111 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1112 IDirect3DCubeTexture9 *texture = NULL;
1113 IDirect3DSurface9 *surface = NULL;
1114 D3DLOCKED_RECT locked_rect;
1115 HRESULT hr;
1116 UINT x;
1117 INT y, face;
1119 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1120 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1121 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1122 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1124 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1125 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1126 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1128 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1129 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1131 for (y = 0; y < 128; ++y)
1133 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1134 for (x = 0; x < 64; ++x)
1136 *ptr++ = 0xffff0000;
1138 for (x = 64; x < 128; ++x)
1140 *ptr++ = 0xff0000ff;
1144 hr = IDirect3DSurface9_UnlockRect(surface);
1145 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1147 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1148 D3DPOOL_DEFAULT, &texture, NULL);
1149 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1151 /* Create cube faces */
1152 for (face = 0; face < 6; ++face)
1154 IDirect3DSurface9 *face_surface = NULL;
1156 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1157 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1159 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1160 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1162 IDirect3DSurface9_Release(face_surface);
1165 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1166 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1168 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1169 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1171 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1172 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1173 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1176 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1178 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1180 DWORD color;
1182 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1183 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1184 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1185 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1187 hr = IDirect3DDevice9_BeginScene(device);
1188 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1191 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1193 hr = IDirect3DDevice9_EndScene(device);
1194 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1196 /* Due to the nature of this test, we sample essentially at the edge
1197 * between two faces. Because of this it's undefined from which face
1198 * the driver will sample. Fortunately that's not important for this
1199 * test, since all we care about is that it doesn't sample from the
1200 * other side of the surface or from the border. */
1201 color = getPixelColor(device, 320, 240);
1202 ok(color == 0x00ff0000 || color == 0x000000ff,
1203 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1204 color, address_modes[x].name);
1206 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1207 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1210 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1213 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1214 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1216 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1217 IDirect3DCubeTexture9_Release(texture);
1218 IDirect3DSurface9_Release(surface);
1221 static void offscreen_test(IDirect3DDevice9 *device)
1223 HRESULT hr;
1224 IDirect3DTexture9 *offscreenTexture = NULL;
1225 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1226 DWORD color;
1228 static const float quad[][5] = {
1229 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1230 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1231 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1232 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1235 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1236 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1238 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1239 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1240 if(!offscreenTexture) {
1241 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1242 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1243 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1244 if(!offscreenTexture) {
1245 skip("Cannot create an offscreen render target\n");
1246 goto out;
1250 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1251 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1252 if(!backbuffer) {
1253 goto out;
1256 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1257 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1258 if(!offscreen) {
1259 goto out;
1262 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1263 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1265 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1266 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1267 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1268 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1269 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1270 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1271 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1272 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1274 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1276 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1277 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1278 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1280 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1282 /* Draw without textures - Should result in a white quad */
1283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1284 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1286 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1287 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1288 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1289 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1291 /* This time with the texture */
1292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1293 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1295 IDirect3DDevice9_EndScene(device);
1298 /* Center quad - should be white */
1299 color = getPixelColor(device, 320, 240);
1300 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1301 /* Some quad in the cleared part of the texture */
1302 color = getPixelColor(device, 170, 240);
1303 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1304 /* Part of the originally cleared back buffer */
1305 color = getPixelColor(device, 10, 10);
1306 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1307 if(0) {
1308 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1309 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1310 * the offscreen rendering mode this test would succeed or fail
1312 color = getPixelColor(device, 10, 470);
1313 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1316 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1318 out:
1319 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1320 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1322 /* restore things */
1323 if(backbuffer) {
1324 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1325 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1326 IDirect3DSurface9_Release(backbuffer);
1328 if(offscreenTexture) {
1329 IDirect3DTexture9_Release(offscreenTexture);
1331 if(offscreen) {
1332 IDirect3DSurface9_Release(offscreen);
1336 /* This test tests fog in combination with shaders.
1337 * What's tested: linear fog (vertex and table) with pixel shader
1338 * linear table fog with non foggy vertex shader
1339 * vertex fog with foggy vertex shader, non-linear
1340 * fog with shader, non-linear fog with foggy shader,
1341 * linear table fog with foggy shader
1343 static void fog_with_shader_test(IDirect3DDevice9 *device)
1345 HRESULT hr;
1346 DWORD color;
1347 union {
1348 float f;
1349 DWORD i;
1350 } start, end;
1351 unsigned int i, j;
1353 /* basic vertex shader without fog computation ("non foggy") */
1354 static const DWORD vertex_shader_code1[] = {
1355 0xfffe0101, /* vs_1_1 */
1356 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1357 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1358 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1359 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1360 0x0000ffff
1362 /* basic vertex shader with reversed fog computation ("foggy") */
1363 static const DWORD vertex_shader_code2[] = {
1364 0xfffe0101, /* vs_1_1 */
1365 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1366 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1367 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1368 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1369 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1370 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1371 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1372 0x0000ffff
1374 /* basic pixel shader */
1375 static const DWORD pixel_shader_code[] = {
1376 0xffff0101, /* ps_1_1 */
1377 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1378 0x0000ffff
1381 static struct vertex quad[] = {
1382 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1383 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1384 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1385 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1388 static const D3DVERTEXELEMENT9 decl_elements[] = {
1389 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1390 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1391 D3DDECL_END()
1394 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1395 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1396 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1398 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1399 static const struct test_data_t {
1400 int vshader;
1401 int pshader;
1402 D3DFOGMODE vfog;
1403 D3DFOGMODE tfog;
1404 unsigned int color[11];
1405 } test_data[] = {
1406 /* only pixel shader: */
1407 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1408 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1411 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1413 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1414 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1415 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1416 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1417 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1418 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1419 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1420 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1421 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1423 /* vertex shader */
1424 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1425 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1426 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1427 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1428 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1429 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1430 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1431 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1432 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1434 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1435 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1436 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1437 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1438 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1439 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1441 /* vertex shader and pixel shader */
1442 /* The next 4 tests would read the fog coord output, but it isn't available.
1443 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1444 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1445 * These tests should be disabled if some other hardware behaves differently
1447 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1448 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1449 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1450 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1451 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1452 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1453 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1454 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1455 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1456 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1457 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1458 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1460 /* These use the Z coordinate with linear table fog */
1461 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1462 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1463 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1464 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1465 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1467 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1468 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1469 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1470 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1471 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1472 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1474 /* Non-linear table fog without fog coord */
1475 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1476 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1477 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1478 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1479 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1480 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1482 #if 0 /* FIXME: these fail on GeForce 8500 */
1483 /* foggy vertex shader */
1484 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1485 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1488 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1491 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1494 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1495 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1496 #endif
1498 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1499 * all using the fixed fog-coord linear fog
1501 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1502 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1503 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1504 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1505 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1506 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1507 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1508 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1509 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1510 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1511 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1512 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1514 /* These use table fog. Here the shader-provided fog coordinate is
1515 * ignored and the z coordinate used instead
1517 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1518 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1519 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1520 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1521 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1522 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1523 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1524 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1525 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1528 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1529 start.f=0.1f;
1530 end.f=0.9f;
1532 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1533 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1534 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1535 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1536 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1537 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1538 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1539 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1541 /* Setup initial states: No lighting, fog on, fog color */
1542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1543 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1545 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1547 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1549 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1552 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1554 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1556 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1557 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1558 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1560 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1562 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1564 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1565 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1566 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1567 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1569 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1571 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1573 for(j=0; j < 11; j++)
1575 /* Don't use the whole zrange to prevent rounding errors */
1576 quad[0].z = 0.001f + (float)j / 10.02f;
1577 quad[1].z = 0.001f + (float)j / 10.02f;
1578 quad[2].z = 0.001f + (float)j / 10.02f;
1579 quad[3].z = 0.001f + (float)j / 10.02f;
1581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1582 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1584 hr = IDirect3DDevice9_BeginScene(device);
1585 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1588 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1590 hr = IDirect3DDevice9_EndScene(device);
1591 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1593 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1594 color = getPixelColor(device, 128, 240);
1595 ok(color_match(color, test_data[i].color[j], 13),
1596 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1597 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1599 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1603 /* reset states */
1604 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1605 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1606 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1607 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1608 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1609 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1611 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1613 IDirect3DVertexShader9_Release(vertex_shader[1]);
1614 IDirect3DVertexShader9_Release(vertex_shader[2]);
1615 IDirect3DPixelShader9_Release(pixel_shader[1]);
1616 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1619 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1620 unsigned int i, x, y;
1621 HRESULT hr;
1622 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1623 D3DLOCKED_RECT locked_rect;
1625 /* Generate the textures */
1626 for(i=0; i<2; i++)
1628 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1629 D3DPOOL_MANAGED, &texture[i], NULL);
1630 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1632 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1633 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1634 for (y = 0; y < 128; ++y)
1636 if(i)
1637 { /* Set up black texture with 2x2 texel white spot in the middle */
1638 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1639 for (x = 0; x < 128; ++x)
1641 if(y>62 && y<66 && x>62 && x<66)
1642 *ptr++ = 0xffffffff;
1643 else
1644 *ptr++ = 0xff000000;
1647 else
1648 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1649 * (if multiplied with bumpenvmat)
1651 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1652 for (x = 0; x < 128; ++x)
1654 if(abs(x-64)>abs(y-64))
1656 if(x < 64)
1657 *ptr++ = 0xc000;
1658 else
1659 *ptr++ = 0x4000;
1661 else
1663 if(y < 64)
1664 *ptr++ = 0x0040;
1665 else
1666 *ptr++ = 0x00c0;
1671 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1672 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1674 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1675 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1677 /* Disable texture filtering */
1678 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1679 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1680 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1681 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1683 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1684 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1685 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1686 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1690 /* test the behavior of the texbem instruction
1691 * with normal 2D and projective 2D textures
1693 static void texbem_test(IDirect3DDevice9 *device)
1695 HRESULT hr;
1696 DWORD color;
1697 int i;
1699 static const DWORD pixel_shader_code[] = {
1700 0xffff0101, /* ps_1_1*/
1701 0x00000042, 0xb00f0000, /* tex t0*/
1702 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1703 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1704 0x0000ffff
1706 static const DWORD double_texbem_code[] = {
1707 0xffff0103, /* ps_1_3 */
1708 0x00000042, 0xb00f0000, /* tex t0 */
1709 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1710 0x00000042, 0xb00f0002, /* tex t2 */
1711 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1712 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1713 0x0000ffff /* end */
1717 static const float quad[][7] = {
1718 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1719 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1720 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1721 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1723 static const float quad_proj[][9] = {
1724 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1725 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1726 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1727 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1730 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1731 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1732 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1733 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1734 D3DDECL_END()
1736 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1737 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1738 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1739 D3DDECL_END()
1740 } };
1742 /* use asymmetric matrix to test loading */
1743 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1745 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1746 IDirect3DPixelShader9 *pixel_shader = NULL;
1747 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1748 D3DLOCKED_RECT locked_rect;
1750 generate_bumpmap_textures(device);
1752 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1753 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1754 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1755 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1756 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1758 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1759 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1762 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1764 for(i=0; i<2; i++)
1766 if(i)
1768 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1769 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1772 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1773 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1774 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1775 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1777 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1778 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1779 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1780 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1782 hr = IDirect3DDevice9_BeginScene(device);
1783 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1785 if(!i)
1786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1787 else
1788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1789 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1791 hr = IDirect3DDevice9_EndScene(device);
1792 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1794 color = getPixelColor(device, 320-32, 240);
1795 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1796 color = getPixelColor(device, 320+32, 240);
1797 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1798 color = getPixelColor(device, 320, 240-32);
1799 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1800 color = getPixelColor(device, 320, 240+32);
1801 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1803 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1804 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1806 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1807 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1808 IDirect3DPixelShader9_Release(pixel_shader);
1810 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1811 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1812 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1815 /* clean up */
1816 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1817 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1819 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1820 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1822 for(i=0; i<2; i++)
1824 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1825 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1826 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1827 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1828 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1829 IDirect3DTexture9_Release(texture);
1832 /* Test double texbem */
1833 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1834 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1835 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1836 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1837 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1838 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1839 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1840 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1842 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1843 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1844 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1845 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1847 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1848 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1850 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1851 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1852 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1853 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1854 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1855 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1858 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1859 #define tex 0x00ff0000
1860 #define tex1 0x0000ff00
1861 #define origin 0x000000ff
1862 static const DWORD pixel_data[] = {
1863 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1864 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1865 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1866 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1867 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1868 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1869 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1870 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1872 #undef tex1
1873 #undef tex2
1874 #undef origin
1876 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1877 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1878 for(i = 0; i < 8; i++) {
1879 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1881 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1882 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1885 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1886 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1887 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1888 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1889 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1890 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1891 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1892 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1893 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1894 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1895 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1896 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1898 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1899 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1900 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1901 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1902 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1903 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1904 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1905 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1906 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1907 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1909 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1910 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1911 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1912 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1913 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1914 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1915 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1916 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1917 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1918 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1920 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1921 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1922 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1923 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1924 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1925 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1926 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1927 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1928 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1929 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1930 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1931 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1932 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1933 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1934 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1935 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1937 hr = IDirect3DDevice9_BeginScene(device);
1938 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1939 if(SUCCEEDED(hr)) {
1940 static const float double_quad[] = {
1941 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1942 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1943 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1944 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1948 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1949 hr = IDirect3DDevice9_EndScene(device);
1950 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1952 color = getPixelColor(device, 320, 240);
1953 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1955 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1956 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1957 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1958 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1959 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1960 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1961 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1962 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1963 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1964 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1966 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1967 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1969 IDirect3DPixelShader9_Release(pixel_shader);
1970 IDirect3DTexture9_Release(texture);
1971 IDirect3DTexture9_Release(texture1);
1972 IDirect3DTexture9_Release(texture2);
1975 static void z_range_test(IDirect3DDevice9 *device)
1977 const struct vertex quad[] =
1979 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1980 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1981 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1982 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1984 const struct vertex quad2[] =
1986 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1987 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1988 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1989 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1992 const struct tvertex quad3[] =
1994 { 0, 240, 1.1f, 1.0, 0xffffff00},
1995 { 0, 480, 1.1f, 1.0, 0xffffff00},
1996 { 640, 240, -1.1f, 1.0, 0xffffff00},
1997 { 640, 480, -1.1f, 1.0, 0xffffff00},
1999 const struct tvertex quad4[] =
2001 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2002 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2003 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2004 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2006 HRESULT hr;
2007 DWORD color;
2008 IDirect3DVertexShader9 *shader;
2009 IDirect3DVertexDeclaration9 *decl;
2010 D3DCAPS9 caps;
2011 const DWORD shader_code[] = {
2012 0xfffe0101, /* vs_1_1 */
2013 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2014 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2015 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2016 0x0000ffff /* end */
2018 static const D3DVERTEXELEMENT9 decl_elements[] = {
2019 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2020 D3DDECL_END()
2022 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2023 * then call Present. Then clear the color buffer to make sure it has some defined content
2024 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2025 * by the depth value.
2027 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2028 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2029 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2030 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2032 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2034 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2035 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2036 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2037 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2039 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2041 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2042 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2043 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2045 hr = IDirect3DDevice9_BeginScene(device);
2046 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2047 if(hr == D3D_OK)
2049 /* Test the untransformed vertex path */
2050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2051 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2053 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2055 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2057 /* Test the transformed vertex path */
2058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2059 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2062 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2064 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2066 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2068 hr = IDirect3DDevice9_EndScene(device);
2069 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2072 /* Do not test the exact corner pixels, but go pretty close to them */
2074 /* Clipped because z > 1.0 */
2075 color = getPixelColor(device, 28, 238);
2076 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2077 color = getPixelColor(device, 28, 241);
2078 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2080 /* Not clipped, > z buffer clear value(0.75) */
2081 color = getPixelColor(device, 31, 238);
2082 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2083 color = getPixelColor(device, 31, 241);
2084 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2085 color = getPixelColor(device, 100, 238);
2086 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2087 color = getPixelColor(device, 100, 241);
2088 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2090 /* Not clipped, < z buffer clear value */
2091 color = getPixelColor(device, 104, 238);
2092 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2093 color = getPixelColor(device, 104, 241);
2094 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2095 color = getPixelColor(device, 318, 238);
2096 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2097 color = getPixelColor(device, 318, 241);
2098 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2100 /* Clipped because z < 0.0 */
2101 color = getPixelColor(device, 321, 238);
2102 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2103 color = getPixelColor(device, 321, 241);
2104 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2106 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2107 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2109 /* Test the shader path */
2110 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2111 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2112 skip("Vertex shaders not supported\n");
2113 goto out;
2115 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2117 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2118 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2120 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2123 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2124 IDirect3DDevice9_SetVertexShader(device, shader);
2125 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2127 hr = IDirect3DDevice9_BeginScene(device);
2128 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2129 if(hr == D3D_OK)
2131 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2132 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2133 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2135 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2137 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2138 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2140 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142 hr = IDirect3DDevice9_EndScene(device);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2146 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2147 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2148 IDirect3DDevice9_SetVertexShader(device, NULL);
2149 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2151 IDirect3DVertexDeclaration9_Release(decl);
2152 IDirect3DVertexShader9_Release(shader);
2154 /* Z < 1.0 */
2155 color = getPixelColor(device, 28, 238);
2156 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2158 /* 1.0 < z < 0.75 */
2159 color = getPixelColor(device, 31, 238);
2160 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2161 color = getPixelColor(device, 100, 238);
2162 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2164 /* 0.75 < z < 0.0 */
2165 color = getPixelColor(device, 104, 238);
2166 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2167 color = getPixelColor(device, 318, 238);
2168 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2170 /* 0.0 < z */
2171 color = getPixelColor(device, 321, 238);
2172 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2175 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2177 out:
2178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2179 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2180 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2181 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2183 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2186 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2188 D3DSURFACE_DESC desc;
2189 D3DLOCKED_RECT l;
2190 HRESULT hr;
2191 unsigned int x, y;
2192 DWORD *mem;
2194 memset(&desc, 0, sizeof(desc));
2195 memset(&l, 0, sizeof(l));
2196 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2197 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2198 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2199 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2200 if(FAILED(hr)) return;
2202 for(y = 0; y < desc.Height; y++)
2204 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2205 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2207 mem[x] = color;
2210 hr = IDirect3DSurface9_UnlockRect(surface);
2211 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2214 /* This tests a variety of possible StretchRect() situations */
2215 static void stretchrect_test(IDirect3DDevice9 *device)
2217 HRESULT hr;
2218 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2219 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2220 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2221 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2222 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2223 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2224 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2225 IDirect3DSurface9 *orig_rt = NULL;
2226 DWORD color;
2228 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2229 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2230 if(!orig_rt) {
2231 goto out;
2234 /* Create our temporary surfaces in system memory */
2235 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2236 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2237 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2238 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2240 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2241 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2242 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2243 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2244 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2245 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2246 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2248 /* Create render target surfaces */
2249 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2250 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2251 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2252 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2253 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2254 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2256 /* Create render target textures */
2257 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2258 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2259 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2260 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2261 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2262 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2263 if (tex_rt32) {
2264 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2265 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2267 if (tex_rt64) {
2268 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2269 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2271 if (tex_rt_dest64) {
2272 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2273 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2276 /* Create regular textures in D3DPOOL_DEFAULT */
2277 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2278 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2279 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2280 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2281 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2282 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2283 if (tex32) {
2284 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2285 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2287 if (tex64) {
2288 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2289 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2291 if (tex_dest64) {
2292 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2293 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2296 /*********************************************************************
2297 * Tests for when the source parameter is an offscreen plain surface *
2298 *********************************************************************/
2300 /* Fill the offscreen 64x64 surface with green */
2301 if (surf_offscreen64)
2302 fill_surface(surf_offscreen64, 0xff00ff00);
2304 /* offscreenplain ==> offscreenplain, same size */
2305 if(surf_offscreen64 && surf_offscreen_dest64) {
2306 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2307 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2309 if (hr == D3D_OK) {
2310 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2311 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2315 /* offscreenplain ==> rendertarget texture, same size */
2316 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2317 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2318 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2320 /* We can't lock rendertarget textures, so copy to our temp surface first */
2321 if (hr == D3D_OK) {
2322 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2323 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2326 if (hr == D3D_OK) {
2327 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2328 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2332 /* offscreenplain ==> rendertarget surface, same size */
2333 if(surf_offscreen64 && surf_rt_dest64) {
2334 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2335 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2337 if (hr == D3D_OK) {
2338 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2339 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2343 /* offscreenplain ==> texture, same size (should fail) */
2344 if(surf_offscreen64 && surf_tex_dest64) {
2345 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2346 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2349 /* Fill the smaller offscreen surface with red */
2350 fill_surface(surf_offscreen32, 0xffff0000);
2352 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2353 if(surf_offscreen32 && surf_offscreen64) {
2354 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2355 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2358 /* offscreenplain ==> rendertarget texture, scaling */
2359 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2360 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2361 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2363 /* We can't lock rendertarget textures, so copy to our temp surface first */
2364 if (hr == D3D_OK) {
2365 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2366 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2369 if (hr == D3D_OK) {
2370 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2371 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2375 /* offscreenplain ==> rendertarget surface, scaling */
2376 if(surf_offscreen32 && surf_rt_dest64) {
2377 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2378 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2380 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2381 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2384 /* offscreenplain ==> texture, scaling (should fail) */
2385 if(surf_offscreen32 && surf_tex_dest64) {
2386 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2387 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2390 /************************************************************
2391 * Tests for when the source parameter is a regular texture *
2392 ************************************************************/
2394 /* Fill the surface of the regular texture with blue */
2395 if (surf_tex64 && surf_temp64) {
2396 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2397 fill_surface(surf_temp64, 0xff0000ff);
2398 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2399 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2402 /* texture ==> offscreenplain, same size */
2403 if(surf_tex64 && surf_offscreen64) {
2404 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2405 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2408 /* texture ==> rendertarget texture, same size */
2409 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2410 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2411 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2413 /* We can't lock rendertarget textures, so copy to our temp surface first */
2414 if (hr == D3D_OK) {
2415 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2416 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2419 if (hr == D3D_OK) {
2420 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2421 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2425 /* texture ==> rendertarget surface, same size */
2426 if(surf_tex64 && surf_rt_dest64) {
2427 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2428 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2430 if (hr == D3D_OK) {
2431 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2432 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2436 /* texture ==> texture, same size (should fail) */
2437 if(surf_tex64 && surf_tex_dest64) {
2438 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2439 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2442 /* Fill the surface of the smaller regular texture with red */
2443 if (surf_tex32 && surf_temp32) {
2444 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2445 fill_surface(surf_temp32, 0xffff0000);
2446 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2447 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2450 /* texture ==> offscreenplain, scaling (should fail) */
2451 if(surf_tex32 && surf_offscreen64) {
2452 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2453 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2456 /* texture ==> rendertarget texture, scaling */
2457 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2458 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2459 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2461 /* We can't lock rendertarget textures, so copy to our temp surface first */
2462 if (hr == D3D_OK) {
2463 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2464 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2467 if (hr == D3D_OK) {
2468 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2469 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2473 /* texture ==> rendertarget surface, scaling */
2474 if(surf_tex32 && surf_rt_dest64) {
2475 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2476 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2478 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2479 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2482 /* texture ==> texture, scaling (should fail) */
2483 if(surf_tex32 && surf_tex_dest64) {
2484 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2485 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2488 /*****************************************************************
2489 * Tests for when the source parameter is a rendertarget texture *
2490 *****************************************************************/
2492 /* Fill the surface of the rendertarget texture with white */
2493 if (surf_tex_rt64 && surf_temp64) {
2494 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2495 fill_surface(surf_temp64, 0xffffffff);
2496 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2497 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2500 /* rendertarget texture ==> offscreenplain, same size */
2501 if(surf_tex_rt64 && surf_offscreen64) {
2502 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2503 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2506 /* rendertarget texture ==> rendertarget texture, same size */
2507 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2508 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2509 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2511 /* We can't lock rendertarget textures, so copy to our temp surface first */
2512 if (hr == D3D_OK) {
2513 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2514 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2517 if (hr == D3D_OK) {
2518 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2519 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2523 /* rendertarget texture ==> rendertarget surface, same size */
2524 if(surf_tex_rt64 && surf_rt_dest64) {
2525 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2526 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2528 if (hr == D3D_OK) {
2529 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2530 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2534 /* rendertarget texture ==> texture, same size (should fail) */
2535 if(surf_tex_rt64 && surf_tex_dest64) {
2536 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2537 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2540 /* Fill the surface of the smaller rendertarget texture with red */
2541 if (surf_tex_rt32 && surf_temp32) {
2542 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2543 fill_surface(surf_temp32, 0xffff0000);
2544 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2545 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2548 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2549 if(surf_tex_rt32 && surf_offscreen64) {
2550 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2551 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2554 /* rendertarget texture ==> rendertarget texture, scaling */
2555 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2556 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2557 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2559 /* We can't lock rendertarget textures, so copy to our temp surface first */
2560 if (hr == D3D_OK) {
2561 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2562 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2565 if (hr == D3D_OK) {
2566 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2567 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2571 /* rendertarget texture ==> rendertarget surface, scaling */
2572 if(surf_tex_rt32 && surf_rt_dest64) {
2573 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2574 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2576 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2577 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2580 /* rendertarget texture ==> texture, scaling (should fail) */
2581 if(surf_tex_rt32 && surf_tex_dest64) {
2582 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2583 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2586 /*****************************************************************
2587 * Tests for when the source parameter is a rendertarget surface *
2588 *****************************************************************/
2590 /* Fill the surface of the rendertarget surface with black */
2591 if (surf_rt64)
2592 fill_surface(surf_rt64, 0xff000000);
2594 /* rendertarget texture ==> offscreenplain, same size */
2595 if(surf_rt64 && surf_offscreen64) {
2596 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2597 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2600 /* rendertarget surface ==> rendertarget texture, same size */
2601 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2602 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2603 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2605 /* We can't lock rendertarget textures, so copy to our temp surface first */
2606 if (hr == D3D_OK) {
2607 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2608 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2611 if (hr == D3D_OK) {
2612 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2613 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2617 /* rendertarget surface ==> rendertarget surface, same size */
2618 if(surf_rt64 && surf_rt_dest64) {
2619 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2620 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2622 if (hr == D3D_OK) {
2623 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2624 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2628 /* rendertarget surface ==> texture, same size (should fail) */
2629 if(surf_rt64 && surf_tex_dest64) {
2630 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2631 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2634 /* Fill the surface of the smaller rendertarget texture with red */
2635 if (surf_rt32)
2636 fill_surface(surf_rt32, 0xffff0000);
2638 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2639 if(surf_rt32 && surf_offscreen64) {
2640 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2641 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2644 /* rendertarget surface ==> rendertarget texture, scaling */
2645 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2646 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2647 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2649 /* We can't lock rendertarget textures, so copy to our temp surface first */
2650 if (hr == D3D_OK) {
2651 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2652 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2655 if (hr == D3D_OK) {
2656 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2657 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2661 /* rendertarget surface ==> rendertarget surface, scaling */
2662 if(surf_rt32 && surf_rt_dest64) {
2663 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2664 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2666 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2667 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2670 /* rendertarget surface ==> texture, scaling (should fail) */
2671 if(surf_rt32 && surf_tex_dest64) {
2672 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2673 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2676 /* TODO: Test when source and destination RECT parameters are given... */
2677 /* TODO: Test format conversions */
2680 out:
2681 /* Clean up */
2682 if (surf_rt32)
2683 IDirect3DSurface9_Release(surf_rt32);
2684 if (surf_rt64)
2685 IDirect3DSurface9_Release(surf_rt64);
2686 if (surf_rt_dest64)
2687 IDirect3DSurface9_Release(surf_rt_dest64);
2688 if (surf_temp32)
2689 IDirect3DSurface9_Release(surf_temp32);
2690 if (surf_temp64)
2691 IDirect3DSurface9_Release(surf_temp64);
2692 if (surf_offscreen32)
2693 IDirect3DSurface9_Release(surf_offscreen32);
2694 if (surf_offscreen64)
2695 IDirect3DSurface9_Release(surf_offscreen64);
2696 if (surf_offscreen_dest64)
2697 IDirect3DSurface9_Release(surf_offscreen_dest64);
2699 if (tex_rt32) {
2700 if (surf_tex_rt32)
2701 IDirect3DSurface9_Release(surf_tex_rt32);
2702 IDirect3DTexture9_Release(tex_rt32);
2704 if (tex_rt64) {
2705 if (surf_tex_rt64)
2706 IDirect3DSurface9_Release(surf_tex_rt64);
2707 IDirect3DTexture9_Release(tex_rt64);
2709 if (tex_rt_dest64) {
2710 if (surf_tex_rt_dest64)
2711 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2712 IDirect3DTexture9_Release(tex_rt_dest64);
2714 if (tex32) {
2715 if (surf_tex32)
2716 IDirect3DSurface9_Release(surf_tex32);
2717 IDirect3DTexture9_Release(tex32);
2719 if (tex64) {
2720 if (surf_tex64)
2721 IDirect3DSurface9_Release(surf_tex64);
2722 IDirect3DTexture9_Release(tex64);
2724 if (tex_dest64) {
2725 if (surf_tex_dest64)
2726 IDirect3DSurface9_Release(surf_tex_dest64);
2727 IDirect3DTexture9_Release(tex_dest64);
2730 if (orig_rt) {
2731 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2732 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2733 IDirect3DSurface9_Release(orig_rt);
2737 static void maxmip_test(IDirect3DDevice9 *device)
2739 IDirect3DTexture9 *texture = NULL;
2740 IDirect3DSurface9 *surface = NULL;
2741 HRESULT hr;
2742 DWORD color;
2743 const float quads[] = {
2744 -1.0, -1.0, 0.0, 0.0, 0.0,
2745 -1.0, 0.0, 0.0, 0.0, 1.0,
2746 0.0, -1.0, 0.0, 1.0, 0.0,
2747 0.0, 0.0, 0.0, 1.0, 1.0,
2749 0.0, -1.0, 0.0, 0.0, 0.0,
2750 0.0, 0.0, 0.0, 0.0, 1.0,
2751 1.0, -1.0, 0.0, 1.0, 0.0,
2752 1.0, 0.0, 0.0, 1.0, 1.0,
2754 0.0, 0.0, 0.0, 0.0, 0.0,
2755 0.0, 1.0, 0.0, 0.0, 1.0,
2756 1.0, 0.0, 0.0, 1.0, 0.0,
2757 1.0, 1.0, 0.0, 1.0, 1.0,
2759 -1.0, 0.0, 0.0, 0.0, 0.0,
2760 -1.0, 1.0, 0.0, 0.0, 1.0,
2761 0.0, 0.0, 0.0, 1.0, 0.0,
2762 0.0, 1.0, 0.0, 1.0, 1.0,
2765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2766 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2768 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2769 &texture, NULL);
2770 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2771 if(!texture)
2773 skip("Failed to create test texture\n");
2774 return;
2777 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2778 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2779 fill_surface(surface, 0xffff0000);
2780 IDirect3DSurface9_Release(surface);
2781 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2782 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2783 fill_surface(surface, 0xff00ff00);
2784 IDirect3DSurface9_Release(surface);
2785 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2786 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2787 fill_surface(surface, 0xff0000ff);
2788 IDirect3DSurface9_Release(surface);
2790 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2791 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2792 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2793 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2795 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2796 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2798 hr = IDirect3DDevice9_BeginScene(device);
2799 if(SUCCEEDED(hr))
2801 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2802 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2804 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2806 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2807 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2809 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2811 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2812 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2816 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2817 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2819 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2820 hr = IDirect3DDevice9_EndScene(device);
2821 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
2824 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2825 color = getPixelColor(device, 160, 360);
2826 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2827 color = getPixelColor(device, 160, 120);
2828 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2829 color = getPixelColor(device, 480, 120);
2830 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2831 color = getPixelColor(device, 480, 360);
2832 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2834 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2836 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2837 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2839 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2840 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2842 hr = IDirect3DDevice9_BeginScene(device);
2843 if(SUCCEEDED(hr))
2845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2846 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2848 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2850 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2851 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2853 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2855 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2856 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2857 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2858 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2860 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2861 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2863 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2864 hr = IDirect3DDevice9_EndScene(device);
2865 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
2868 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2869 * samples from the highest level in the texture(level 2)
2871 color = getPixelColor(device, 160, 360);
2872 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2873 color = getPixelColor(device, 160, 120);
2874 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2875 color = getPixelColor(device, 480, 120);
2876 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2877 color = getPixelColor(device, 480, 360);
2878 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2879 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2880 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2882 hr = IDirect3DDevice9_BeginScene(device);
2883 if(SUCCEEDED(hr))
2885 DWORD ret;
2887 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2888 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2889 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2890 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2891 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2892 ret = IDirect3DTexture9_SetLOD(texture, 1);
2893 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2895 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2897 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2898 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2899 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2900 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2901 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2902 ret = IDirect3DTexture9_SetLOD(texture, 2);
2903 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2905 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2907 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2908 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2909 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2910 ret = IDirect3DTexture9_SetLOD(texture, 1);
2911 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2913 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2915 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2916 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2917 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2918 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2919 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2920 ret = IDirect3DTexture9_SetLOD(texture, 1);
2921 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2923 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2924 hr = IDirect3DDevice9_EndScene(device);
2927 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2928 * samples from the highest level in the texture(level 2)
2930 color = getPixelColor(device, 160, 360);
2931 ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2932 color = getPixelColor(device, 160, 120);
2933 ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2934 color = getPixelColor(device, 480, 120);
2935 ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2936 color = getPixelColor(device, 480, 360);
2937 ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2938 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2939 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2941 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2942 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2943 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2944 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2945 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2946 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2947 IDirect3DTexture9_Release(texture);
2950 static void release_buffer_test(IDirect3DDevice9 *device)
2952 IDirect3DVertexBuffer9 *vb = NULL;
2953 IDirect3DIndexBuffer9 *ib = NULL;
2954 HRESULT hr;
2955 BYTE *data;
2956 LONG ref;
2958 static const struct vertex quad[] = {
2959 {-1.0, -1.0, 0.1, 0xffff0000},
2960 {-1.0, 1.0, 0.1, 0xffff0000},
2961 { 1.0, 1.0, 0.1, 0xffff0000},
2963 {-1.0, -1.0, 0.1, 0xff00ff00},
2964 {-1.0, 1.0, 0.1, 0xff00ff00},
2965 { 1.0, 1.0, 0.1, 0xff00ff00}
2967 short indices[] = {3, 4, 5};
2969 /* Index and vertex buffers should always be creatable */
2970 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2971 D3DPOOL_MANAGED, &vb, NULL);
2972 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2973 if(!vb) {
2974 skip("Failed to create a vertex buffer\n");
2975 return;
2977 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2978 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2979 if(!ib) {
2980 skip("Failed to create an index buffer\n");
2981 return;
2984 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2985 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2986 memcpy(data, quad, sizeof(quad));
2987 hr = IDirect3DVertexBuffer9_Unlock(vb);
2988 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2990 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2991 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2992 memcpy(data, indices, sizeof(indices));
2993 hr = IDirect3DIndexBuffer9_Unlock(ib);
2994 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2996 hr = IDirect3DDevice9_SetIndices(device, ib);
2997 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2998 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2999 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3000 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3001 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3003 /* Now destroy the bound index buffer and draw again */
3004 ref = IDirect3DIndexBuffer9_Release(ib);
3005 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3007 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3008 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3010 hr = IDirect3DDevice9_BeginScene(device);
3011 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3012 if(SUCCEEDED(hr))
3014 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3015 * making assumptions about the indices or vertices
3017 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3018 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3019 hr = IDirect3DDevice9_EndScene(device);
3020 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3023 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3024 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3026 hr = IDirect3DDevice9_SetIndices(device, NULL);
3027 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3028 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3029 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3031 /* Index buffer was already destroyed as part of the test */
3032 IDirect3DVertexBuffer9_Release(vb);
3035 static void float_texture_test(IDirect3DDevice9 *device)
3037 IDirect3D9 *d3d = NULL;
3038 HRESULT hr;
3039 IDirect3DTexture9 *texture = NULL;
3040 D3DLOCKED_RECT lr;
3041 float *data;
3042 DWORD color;
3043 float quad[] = {
3044 -1.0, -1.0, 0.1, 0.0, 0.0,
3045 -1.0, 1.0, 0.1, 0.0, 1.0,
3046 1.0, -1.0, 0.1, 1.0, 0.0,
3047 1.0, 1.0, 0.1, 1.0, 1.0,
3050 memset(&lr, 0, sizeof(lr));
3051 IDirect3DDevice9_GetDirect3D(device, &d3d);
3052 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3053 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3054 skip("D3DFMT_R32F textures not supported\n");
3055 goto out;
3058 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3059 D3DPOOL_MANAGED, &texture, NULL);
3060 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3061 if(!texture) {
3062 skip("Failed to create R32F texture\n");
3063 goto out;
3066 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3067 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3068 data = lr.pBits;
3069 *data = 0.0;
3070 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3071 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3073 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3074 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3076 hr = IDirect3DDevice9_BeginScene(device);
3077 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3078 if(SUCCEEDED(hr))
3080 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3081 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3084 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3086 hr = IDirect3DDevice9_EndScene(device);
3087 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3089 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3090 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3092 color = getPixelColor(device, 240, 320);
3093 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3095 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3096 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3098 out:
3099 if(texture) IDirect3DTexture9_Release(texture);
3100 IDirect3D9_Release(d3d);
3103 static void g16r16_texture_test(IDirect3DDevice9 *device)
3105 IDirect3D9 *d3d = NULL;
3106 HRESULT hr;
3107 IDirect3DTexture9 *texture = NULL;
3108 D3DLOCKED_RECT lr;
3109 DWORD *data;
3110 DWORD color;
3111 float quad[] = {
3112 -1.0, -1.0, 0.1, 0.0, 0.0,
3113 -1.0, 1.0, 0.1, 0.0, 1.0,
3114 1.0, -1.0, 0.1, 1.0, 0.0,
3115 1.0, 1.0, 0.1, 1.0, 1.0,
3118 memset(&lr, 0, sizeof(lr));
3119 IDirect3DDevice9_GetDirect3D(device, &d3d);
3120 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3121 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3122 skip("D3DFMT_G16R16 textures not supported\n");
3123 goto out;
3126 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3127 D3DPOOL_MANAGED, &texture, NULL);
3128 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3129 if(!texture) {
3130 skip("Failed to create D3DFMT_G16R16 texture\n");
3131 goto out;
3134 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3135 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3136 data = lr.pBits;
3137 *data = 0x0f00f000;
3138 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3139 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3141 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3144 hr = IDirect3DDevice9_BeginScene(device);
3145 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3146 if(SUCCEEDED(hr))
3148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3149 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3152 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3154 hr = IDirect3DDevice9_EndScene(device);
3155 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3157 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3158 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3160 color = getPixelColor(device, 240, 320);
3161 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3162 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3165 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3167 out:
3168 if(texture) IDirect3DTexture9_Release(texture);
3169 IDirect3D9_Release(d3d);
3172 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3174 HRESULT hr;
3175 IDirect3D9 *d3d;
3176 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3177 D3DCAPS9 caps;
3178 IDirect3DTexture9 *texture = NULL;
3179 IDirect3DVolumeTexture9 *volume = NULL;
3180 unsigned int x, y, z;
3181 D3DLOCKED_RECT lr;
3182 D3DLOCKED_BOX lb;
3183 DWORD color;
3184 UINT w, h;
3185 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3186 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3187 0.0, 1.0, 0.0, 0.0,
3188 0.0, 0.0, 1.0, 0.0,
3189 0.0, 0.0, 0.0, 1.0};
3190 static const D3DVERTEXELEMENT9 decl_elements[] = {
3191 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3192 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3193 D3DDECL_END()
3195 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3196 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3197 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3198 D3DDECL_END()
3200 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3201 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3202 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3203 D3DDECL_END()
3205 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3206 0x00, 0xff, 0x00, 0x00,
3207 0x00, 0x00, 0x00, 0x00,
3208 0x00, 0x00, 0x00, 0x00};
3210 memset(&lr, 0, sizeof(lr));
3211 memset(&lb, 0, sizeof(lb));
3212 IDirect3DDevice9_GetDirect3D(device, &d3d);
3213 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3214 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3215 fmt = D3DFMT_A16B16G16R16;
3217 IDirect3D9_Release(d3d);
3219 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3220 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3221 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3222 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3223 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3226 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3227 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3228 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3229 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3230 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3231 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3232 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3233 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3234 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3235 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3236 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3238 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3239 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3242 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3244 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3245 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3246 w = min(1024, caps.MaxTextureWidth);
3247 h = min(1024, caps.MaxTextureHeight);
3248 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3249 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3250 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3251 if(!texture) {
3252 skip("Failed to create the test texture\n");
3253 return;
3256 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3257 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3258 * 1.0 in red and green for the x and y coords
3260 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3261 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3262 for(y = 0; y < h; y++) {
3263 for(x = 0; x < w; x++) {
3264 double r_f = (double) y / (double) h;
3265 double g_f = (double) x / (double) w;
3266 if(fmt == D3DFMT_A16B16G16R16) {
3267 unsigned short r, g;
3268 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3269 r = (unsigned short) (r_f * 65536.0);
3270 g = (unsigned short) (g_f * 65536.0);
3271 dst[0] = r;
3272 dst[1] = g;
3273 dst[2] = 0;
3274 dst[3] = 65535;
3275 } else {
3276 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3277 unsigned char r = (unsigned char) (r_f * 255.0);
3278 unsigned char g = (unsigned char) (g_f * 255.0);
3279 dst[0] = 0;
3280 dst[1] = g;
3281 dst[2] = r;
3282 dst[3] = 255;
3286 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3287 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3288 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3289 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3291 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3292 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3293 hr = IDirect3DDevice9_BeginScene(device);
3294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3295 if(SUCCEEDED(hr))
3297 float quad1[] = {
3298 -1.0, -1.0, 0.1, 1.0, 1.0,
3299 -1.0, 0.0, 0.1, 1.0, 1.0,
3300 0.0, -1.0, 0.1, 1.0, 1.0,
3301 0.0, 0.0, 0.1, 1.0, 1.0,
3303 float quad2[] = {
3304 -1.0, 0.0, 0.1, 1.0, 1.0,
3305 -1.0, 1.0, 0.1, 1.0, 1.0,
3306 0.0, 0.0, 0.1, 1.0, 1.0,
3307 0.0, 1.0, 0.1, 1.0, 1.0,
3309 float quad3[] = {
3310 0.0, 0.0, 0.1, 0.5, 0.5,
3311 0.0, 1.0, 0.1, 0.5, 0.5,
3312 1.0, 0.0, 0.1, 0.5, 0.5,
3313 1.0, 1.0, 0.1, 0.5, 0.5,
3315 float quad4[] = {
3316 320, 480, 0.1, 1.0, 0.0, 1.0,
3317 320, 240, 0.1, 1.0, 0.0, 1.0,
3318 640, 480, 0.1, 1.0, 0.0, 1.0,
3319 640, 240, 0.1, 1.0, 0.0, 1.0,
3321 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3322 0.0, 0.0, 0.0, 0.0,
3323 0.0, 0.0, 0.0, 0.0,
3324 0.0, 0.0, 0.0, 0.0};
3326 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3327 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3328 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3329 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3330 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3332 /* What happens with transforms enabled? */
3333 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3334 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3336 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3338 /* What happens if 4 coords are used, but only 2 given ?*/
3339 mat[8] = 1.0;
3340 mat[13] = 1.0;
3341 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3342 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3343 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3344 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3346 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3348 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3349 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3350 * due to the coords in the vertices. (turns out red, indeed)
3352 memset(mat, 0, sizeof(mat));
3353 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3354 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3355 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3356 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3357 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3358 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3360 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3362 hr = IDirect3DDevice9_EndScene(device);
3363 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3365 color = getPixelColor(device, 160, 360);
3366 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3367 color = getPixelColor(device, 160, 120);
3368 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3369 color = getPixelColor(device, 480, 120);
3370 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3371 color = getPixelColor(device, 480, 360);
3372 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3374 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3376 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3377 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3379 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3380 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3381 hr = IDirect3DDevice9_BeginScene(device);
3382 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3383 if(SUCCEEDED(hr))
3385 float quad1[] = {
3386 -1.0, -1.0, 0.1, 0.8, 0.2,
3387 -1.0, 0.0, 0.1, 0.8, 0.2,
3388 0.0, -1.0, 0.1, 0.8, 0.2,
3389 0.0, 0.0, 0.1, 0.8, 0.2,
3391 float quad2[] = {
3392 -1.0, 0.0, 0.1, 0.5, 1.0,
3393 -1.0, 1.0, 0.1, 0.5, 1.0,
3394 0.0, 0.0, 0.1, 0.5, 1.0,
3395 0.0, 1.0, 0.1, 0.5, 1.0,
3397 float quad3[] = {
3398 0.0, 0.0, 0.1, 0.5, 1.0,
3399 0.0, 1.0, 0.1, 0.5, 1.0,
3400 1.0, 0.0, 0.1, 0.5, 1.0,
3401 1.0, 1.0, 0.1, 0.5, 1.0,
3403 float quad4[] = {
3404 0.0, -1.0, 0.1, 0.8, 0.2,
3405 0.0, 0.0, 0.1, 0.8, 0.2,
3406 1.0, -1.0, 0.1, 0.8, 0.2,
3407 1.0, 0.0, 0.1, 0.8, 0.2,
3409 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3410 0.0, 0.0, 0.0, 0.0,
3411 0.0, 1.0, 0.0, 0.0,
3412 0.0, 0.0, 0.0, 0.0};
3414 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3416 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3418 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3419 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3422 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3424 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3425 * it behaves like COUNT2 because normal textures require 2 coords
3427 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3430 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3432 /* Just to be sure, the same as quad2 above */
3433 memset(mat, 0, sizeof(mat));
3434 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3435 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3436 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3437 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3439 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3441 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3442 * used? And what happens to the first?
3444 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3445 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3447 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3449 hr = IDirect3DDevice9_EndScene(device);
3450 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3452 color = getPixelColor(device, 160, 360);
3453 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3454 color = getPixelColor(device, 160, 120);
3455 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3456 color = getPixelColor(device, 480, 120);
3457 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3458 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3459 color = getPixelColor(device, 480, 360);
3460 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3461 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3462 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3463 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3465 IDirect3DTexture9_Release(texture);
3467 /* Test projected textures, without any fancy matrices */
3468 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3470 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3471 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3472 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3473 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3474 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3475 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3477 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3478 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3479 for(x = 0; x < 4; x++) {
3480 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3482 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3483 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3484 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3485 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3487 hr = IDirect3DDevice9_BeginScene(device);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3489 if(SUCCEEDED(hr))
3491 const float proj_quads[] = {
3492 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3493 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3494 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3495 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3496 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3497 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3498 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3499 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3502 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3503 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3505 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3507 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3508 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3510 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3512 hr = IDirect3DDevice9_EndScene(device);
3513 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3516 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3517 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3518 IDirect3DTexture9_Release(texture);
3520 color = getPixelColor(device, 158, 118);
3521 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3522 color = getPixelColor(device, 162, 118);
3523 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3524 color = getPixelColor(device, 158, 122);
3525 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3526 color = getPixelColor(device, 162, 122);
3527 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3529 color = getPixelColor(device, 158, 178);
3530 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3531 color = getPixelColor(device, 162, 178);
3532 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3533 color = getPixelColor(device, 158, 182);
3534 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3535 color = getPixelColor(device, 162, 182);
3536 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3538 color = getPixelColor(device, 318, 118);
3539 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3540 color = getPixelColor(device, 322, 118);
3541 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3542 color = getPixelColor(device, 318, 122);
3543 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3544 color = getPixelColor(device, 322, 122);
3545 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3547 color = getPixelColor(device, 318, 178);
3548 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3549 color = getPixelColor(device, 322, 178);
3550 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3551 color = getPixelColor(device, 318, 182);
3552 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3553 color = getPixelColor(device, 322, 182);
3554 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3556 color = getPixelColor(device, 238, 298);
3557 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3558 color = getPixelColor(device, 242, 298);
3559 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3560 color = getPixelColor(device, 238, 302);
3561 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3562 color = getPixelColor(device, 242, 302);
3563 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3565 color = getPixelColor(device, 238, 388);
3566 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3567 color = getPixelColor(device, 242, 388);
3568 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3569 color = getPixelColor(device, 238, 392);
3570 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3571 color = getPixelColor(device, 242, 392);
3572 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3574 color = getPixelColor(device, 478, 298);
3575 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3576 color = getPixelColor(device, 482, 298);
3577 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3578 color = getPixelColor(device, 478, 302);
3579 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3580 color = getPixelColor(device, 482, 302);
3581 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3583 color = getPixelColor(device, 478, 388);
3584 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3585 color = getPixelColor(device, 482, 388);
3586 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3587 color = getPixelColor(device, 478, 392);
3588 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3589 color = getPixelColor(device, 482, 392);
3590 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3592 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3593 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3595 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3596 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3597 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3598 * Thus watch out if sampling from texels between 0 and 1.
3600 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3601 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3602 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3603 if(!volume) {
3604 skip("Failed to create a volume texture\n");
3605 goto out;
3608 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3609 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3610 for(z = 0; z < 32; z++) {
3611 for(y = 0; y < 32; y++) {
3612 for(x = 0; x < 32; x++) {
3613 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3614 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3615 float r_f = (float) x / 31.0;
3616 float g_f = (float) y / 31.0;
3617 float b_f = (float) z / 31.0;
3619 if(fmt == D3DFMT_A16B16G16R16) {
3620 unsigned short *mem_s = mem;
3621 mem_s[0] = r_f * 65535.0;
3622 mem_s[1] = g_f * 65535.0;
3623 mem_s[2] = b_f * 65535.0;
3624 mem_s[3] = 65535;
3625 } else {
3626 unsigned char *mem_c = mem;
3627 mem_c[0] = b_f * 255.0;
3628 mem_c[1] = g_f * 255.0;
3629 mem_c[2] = r_f * 255.0;
3630 mem_c[3] = 255;
3635 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3636 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3638 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3639 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3641 hr = IDirect3DDevice9_BeginScene(device);
3642 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3643 if(SUCCEEDED(hr))
3645 float quad1[] = {
3646 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3647 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3648 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3649 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3651 float quad2[] = {
3652 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3653 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3654 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3655 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3657 float quad3[] = {
3658 0.0, 0.0, 0.1, 0.0, 0.0,
3659 0.0, 1.0, 0.1, 0.0, 0.0,
3660 1.0, 0.0, 0.1, 0.0, 0.0,
3661 1.0, 1.0, 0.1, 0.0, 0.0
3663 float quad4[] = {
3664 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3665 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3666 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3667 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3669 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3670 0.0, 0.0, 1.0, 0.0,
3671 0.0, 1.0, 0.0, 0.0,
3672 0.0, 0.0, 0.0, 1.0};
3673 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3676 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3677 * values
3679 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3680 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3682 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3684 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3686 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3687 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3688 * otherwise the w will be missing(blue).
3689 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3690 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3692 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3693 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3695 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3697 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3698 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3699 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3700 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3701 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3702 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3703 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3705 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3707 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3708 * disable. ATI extends it up to the amount of values needed for the volume texture
3710 memset(mat, 0, sizeof(mat));
3711 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3712 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3713 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3714 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3715 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3718 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3720 hr = IDirect3DDevice9_EndScene(device);
3721 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3724 color = getPixelColor(device, 160, 360);
3725 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3726 color = getPixelColor(device, 160, 120);
3727 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3728 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3729 color = getPixelColor(device, 480, 120);
3730 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3731 color = getPixelColor(device, 480, 360);
3732 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3734 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3735 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3738 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3739 hr = IDirect3DDevice9_BeginScene(device);
3740 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3741 if(SUCCEEDED(hr))
3743 float quad1[] = {
3744 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3745 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3746 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3747 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3749 float quad2[] = {
3750 -1.0, 0.0, 0.1,
3751 -1.0, 1.0, 0.1,
3752 0.0, 0.0, 0.1,
3753 0.0, 1.0, 0.1,
3755 float quad3[] = {
3756 0.0, 0.0, 0.1, 1.0,
3757 0.0, 1.0, 0.1, 1.0,
3758 1.0, 0.0, 0.1, 1.0,
3759 1.0, 1.0, 0.1, 1.0
3761 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3762 0.0, 0.0, 0.0, 0.0,
3763 0.0, 0.0, 0.0, 0.0,
3764 0.0, 1.0, 0.0, 0.0};
3765 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3766 1.0, 0.0, 0.0, 0.0,
3767 0.0, 1.0, 0.0, 0.0,
3768 0.0, 0.0, 1.0, 0.0};
3769 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3772 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3774 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3775 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3776 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3779 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3781 /* None passed */
3782 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3783 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3785 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3787 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3789 /* 4 used, 1 passed */
3790 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3791 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3792 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3793 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3795 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3797 hr = IDirect3DDevice9_EndScene(device);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3800 color = getPixelColor(device, 160, 360);
3801 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3802 color = getPixelColor(device, 160, 120);
3803 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3804 color = getPixelColor(device, 480, 120);
3805 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3806 /* Quad4: unused */
3808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3809 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3811 IDirect3DVolumeTexture9_Release(volume);
3813 out:
3814 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3815 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3816 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3817 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3818 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3819 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3820 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3821 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3822 IDirect3DVertexDeclaration9_Release(decl);
3823 IDirect3DVertexDeclaration9_Release(decl2);
3824 IDirect3DVertexDeclaration9_Release(decl3);
3827 static void texdepth_test(IDirect3DDevice9 *device)
3829 IDirect3DPixelShader9 *shader;
3830 HRESULT hr;
3831 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3832 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3833 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3834 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3835 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3836 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3837 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3838 DWORD shader_code[] = {
3839 0xffff0104, /* ps_1_4 */
3840 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3841 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3842 0x0000fffd, /* phase */
3843 0x00000057, 0x800f0005, /* texdepth r5 */
3844 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3845 0x0000ffff /* end */
3847 DWORD color;
3848 float vertex[] = {
3849 -1.0, -1.0, 0.0,
3850 1.0, -1.0, 1.0,
3851 -1.0, 1.0, 0.0,
3852 1.0, 1.0, 1.0
3855 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3856 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3859 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3863 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3865 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3867 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
3869 /* Fill the depth buffer with a gradient */
3870 hr = IDirect3DDevice9_BeginScene(device);
3871 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3872 if(SUCCEEDED(hr))
3874 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3875 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3876 hr = IDirect3DDevice9_EndScene(device);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3880 /* Now perform the actual tests. Same geometry, but with the shader */
3881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3882 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3885 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3886 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3888 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3889 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3890 hr = IDirect3DDevice9_BeginScene(device);
3891 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3892 if(SUCCEEDED(hr))
3894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3895 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3897 hr = IDirect3DDevice9_EndScene(device);
3898 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3901 color = getPixelColor(device, 158, 240);
3902 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3903 color = getPixelColor(device, 162, 240);
3904 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3906 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3907 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3909 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3910 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3912 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3914 hr = IDirect3DDevice9_BeginScene(device);
3915 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3916 if(SUCCEEDED(hr))
3918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3919 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3921 hr = IDirect3DDevice9_EndScene(device);
3922 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3925 color = getPixelColor(device, 318, 240);
3926 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3927 color = getPixelColor(device, 322, 240);
3928 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3930 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3931 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3933 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3934 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3936 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3937 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3938 hr = IDirect3DDevice9_BeginScene(device);
3939 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3940 if(SUCCEEDED(hr))
3942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3943 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3945 hr = IDirect3DDevice9_EndScene(device);
3946 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3949 color = getPixelColor(device, 1, 240);
3950 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3952 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3953 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3955 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3956 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3958 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3959 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3960 hr = IDirect3DDevice9_BeginScene(device);
3961 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3962 if(SUCCEEDED(hr))
3964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3965 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3967 hr = IDirect3DDevice9_EndScene(device);
3968 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3970 color = getPixelColor(device, 318, 240);
3971 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3972 color = getPixelColor(device, 322, 240);
3973 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3975 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3976 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3979 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3981 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3982 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3983 hr = IDirect3DDevice9_BeginScene(device);
3984 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3985 if(SUCCEEDED(hr))
3987 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3988 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3990 hr = IDirect3DDevice9_EndScene(device);
3991 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3994 color = getPixelColor(device, 1, 240);
3995 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3997 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3998 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4000 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4001 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4003 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4004 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4005 hr = IDirect3DDevice9_BeginScene(device);
4006 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4007 if(SUCCEEDED(hr))
4009 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4010 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4012 hr = IDirect3DDevice9_EndScene(device);
4013 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4016 color = getPixelColor(device, 638, 240);
4017 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4019 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4020 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4022 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4023 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4025 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4026 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4027 hr = IDirect3DDevice9_BeginScene(device);
4028 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4029 if(SUCCEEDED(hr))
4031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4032 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4034 hr = IDirect3DDevice9_EndScene(device);
4035 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4038 color = getPixelColor(device, 638, 240);
4039 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4041 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4044 /* Cleanup */
4045 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4046 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4047 IDirect3DPixelShader9_Release(shader);
4049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4050 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4052 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4055 static void texkill_test(IDirect3DDevice9 *device)
4057 IDirect3DPixelShader9 *shader;
4058 HRESULT hr;
4059 DWORD color;
4061 const float vertex[] = {
4062 /* bottom top right left */
4063 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4064 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4065 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4066 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4069 DWORD shader_code_11[] = {
4070 0xffff0101, /* ps_1_1 */
4071 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4072 0x00000041, 0xb00f0000, /* texkill t0 */
4073 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4074 0x0000ffff /* end */
4076 DWORD shader_code_20[] = {
4077 0xffff0200, /* ps_2_0 */
4078 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4079 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4080 0x01000041, 0xb00f0000, /* texkill t0 */
4081 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4082 0x0000ffff /* end */
4085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4086 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4087 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4088 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4090 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4091 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4092 hr = IDirect3DDevice9_BeginScene(device);
4093 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4094 if(SUCCEEDED(hr))
4096 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4097 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4099 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4100 hr = IDirect3DDevice9_EndScene(device);
4101 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4103 color = getPixelColor(device, 63, 46);
4104 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4105 color = getPixelColor(device, 66, 46);
4106 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4107 color = getPixelColor(device, 63, 49);
4108 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4109 color = getPixelColor(device, 66, 49);
4110 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4112 color = getPixelColor(device, 578, 46);
4113 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4114 color = getPixelColor(device, 575, 46);
4115 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4116 color = getPixelColor(device, 578, 49);
4117 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4118 color = getPixelColor(device, 575, 49);
4119 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4121 color = getPixelColor(device, 63, 430);
4122 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4123 color = getPixelColor(device, 63, 433);
4124 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4125 color = getPixelColor(device, 66, 433);
4126 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4127 color = getPixelColor(device, 66, 430);
4128 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4130 color = getPixelColor(device, 578, 430);
4131 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4132 color = getPixelColor(device, 578, 433);
4133 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4134 color = getPixelColor(device, 575, 433);
4135 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4136 color = getPixelColor(device, 575, 430);
4137 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4140 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4142 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4143 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4144 IDirect3DPixelShader9_Release(shader);
4146 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4148 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4149 if(FAILED(hr)) {
4150 skip("Failed to create 2.0 test shader, most likely not supported\n");
4151 return;
4154 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4155 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4156 hr = IDirect3DDevice9_BeginScene(device);
4157 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4158 if(SUCCEEDED(hr))
4160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4161 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4162 hr = IDirect3DDevice9_EndScene(device);
4163 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4166 color = getPixelColor(device, 63, 46);
4167 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4168 color = getPixelColor(device, 66, 46);
4169 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4170 color = getPixelColor(device, 63, 49);
4171 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4172 color = getPixelColor(device, 66, 49);
4173 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4175 color = getPixelColor(device, 578, 46);
4176 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4177 color = getPixelColor(device, 575, 46);
4178 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4179 color = getPixelColor(device, 578, 49);
4180 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4181 color = getPixelColor(device, 575, 49);
4182 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4184 color = getPixelColor(device, 63, 430);
4185 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4186 color = getPixelColor(device, 63, 433);
4187 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4188 color = getPixelColor(device, 66, 433);
4189 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4190 color = getPixelColor(device, 66, 430);
4191 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4193 color = getPixelColor(device, 578, 430);
4194 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4195 color = getPixelColor(device, 578, 433);
4196 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4197 color = getPixelColor(device, 575, 433);
4198 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4199 color = getPixelColor(device, 575, 430);
4200 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4203 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4205 /* Cleanup */
4206 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4207 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4208 IDirect3DPixelShader9_Release(shader);
4211 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4213 IDirect3D9 *d3d9;
4214 HRESULT hr;
4215 IDirect3DTexture9 *texture;
4216 IDirect3DPixelShader9 *shader;
4217 IDirect3DPixelShader9 *shader2;
4218 D3DLOCKED_RECT lr;
4219 DWORD color;
4220 DWORD shader_code[] = {
4221 0xffff0101, /* ps_1_1 */
4222 0x00000042, 0xb00f0000, /* tex t0 */
4223 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4224 0x0000ffff /* end */
4226 DWORD shader_code2[] = {
4227 0xffff0101, /* ps_1_1 */
4228 0x00000042, 0xb00f0000, /* tex t0 */
4229 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4230 0x0000ffff /* end */
4233 float quad[] = {
4234 -1.0, -1.0, 0.1, 0.5, 0.5,
4235 1.0, -1.0, 0.1, 0.5, 0.5,
4236 -1.0, 1.0, 0.1, 0.5, 0.5,
4237 1.0, 1.0, 0.1, 0.5, 0.5,
4240 memset(&lr, 0, sizeof(lr));
4241 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4242 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4243 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4244 IDirect3D9_Release(d3d9);
4245 if(FAILED(hr)) {
4246 skip("No D3DFMT_X8L8V8U8 support\n");
4247 return;
4250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4251 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4253 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4254 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4255 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4256 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4257 *((DWORD *) lr.pBits) = 0x11ca3141;
4258 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4259 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4261 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4262 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4263 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4264 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4266 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4267 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4268 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4269 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4270 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4271 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4273 hr = IDirect3DDevice9_BeginScene(device);
4274 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4275 if(SUCCEEDED(hr))
4277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4278 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4280 hr = IDirect3DDevice9_EndScene(device);
4281 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4283 color = getPixelColor(device, 578, 430);
4284 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4285 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4286 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4287 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4289 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4290 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4291 hr = IDirect3DDevice9_BeginScene(device);
4292 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4293 if(SUCCEEDED(hr))
4295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4296 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4298 hr = IDirect3DDevice9_EndScene(device);
4299 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4301 color = getPixelColor(device, 578, 430);
4302 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4303 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4304 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4306 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4307 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4308 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4309 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4310 IDirect3DPixelShader9_Release(shader);
4311 IDirect3DPixelShader9_Release(shader2);
4312 IDirect3DTexture9_Release(texture);
4315 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4317 HRESULT hr;
4318 IDirect3D9 *d3d;
4319 IDirect3DTexture9 *texture = NULL;
4320 IDirect3DSurface9 *surface;
4321 DWORD color;
4322 const RECT r1 = {256, 256, 512, 512};
4323 const RECT r2 = {512, 256, 768, 512};
4324 const RECT r3 = {256, 512, 512, 768};
4325 const RECT r4 = {512, 512, 768, 768};
4326 unsigned int x, y;
4327 D3DLOCKED_RECT lr;
4328 memset(&lr, 0, sizeof(lr));
4330 IDirect3DDevice9_GetDirect3D(device, &d3d);
4331 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4332 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4333 skip("No autogenmipmap support\n");
4334 IDirect3D9_Release(d3d);
4335 return;
4337 IDirect3D9_Release(d3d);
4339 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4340 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4342 /* Make the mipmap big, so that a smaller mipmap is used
4344 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4345 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4346 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4348 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4349 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4350 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4351 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4352 for(y = 0; y < 1024; y++) {
4353 for(x = 0; x < 1024; x++) {
4354 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4355 POINT pt;
4357 pt.x = x;
4358 pt.y = y;
4359 if(PtInRect(&r1, pt)) {
4360 *dst = 0xffff0000;
4361 } else if(PtInRect(&r2, pt)) {
4362 *dst = 0xff00ff00;
4363 } else if(PtInRect(&r3, pt)) {
4364 *dst = 0xff0000ff;
4365 } else if(PtInRect(&r4, pt)) {
4366 *dst = 0xff000000;
4367 } else {
4368 *dst = 0xffffffff;
4372 hr = IDirect3DSurface9_UnlockRect(surface);
4373 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4374 IDirect3DSurface9_Release(surface);
4376 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4377 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4378 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4379 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4381 hr = IDirect3DDevice9_BeginScene(device);
4382 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4383 if(SUCCEEDED(hr)) {
4384 const float quad[] = {
4385 -0.5, -0.5, 0.1, 0.0, 0.0,
4386 -0.5, 0.5, 0.1, 0.0, 1.0,
4387 0.5, -0.5, 0.1, 1.0, 0.0,
4388 0.5, 0.5, 0.1, 1.0, 1.0
4391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4392 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4394 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4395 hr = IDirect3DDevice9_EndScene(device);
4396 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4398 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4400 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4401 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4402 IDirect3DTexture9_Release(texture);
4404 color = getPixelColor(device, 200, 200);
4405 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4406 color = getPixelColor(device, 280, 200);
4407 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4408 color = getPixelColor(device, 360, 200);
4409 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4410 color = getPixelColor(device, 440, 200);
4411 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4412 color = getPixelColor(device, 200, 270);
4413 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4414 color = getPixelColor(device, 280, 270);
4415 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4416 color = getPixelColor(device, 360, 270);
4417 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4418 color = getPixelColor(device, 440, 270);
4419 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4420 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4421 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4424 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4426 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4427 IDirect3DVertexDeclaration9 *decl;
4428 HRESULT hr;
4429 DWORD color;
4430 DWORD shader_code_11[] = {
4431 0xfffe0101, /* vs_1_1 */
4432 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4433 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4434 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4435 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4436 0x0000ffff /* end */
4438 DWORD shader_code_11_2[] = {
4439 0xfffe0101, /* vs_1_1 */
4440 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4441 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4442 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4443 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4444 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4445 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4446 0x0000ffff /* end */
4448 DWORD shader_code_20[] = {
4449 0xfffe0200, /* vs_2_0 */
4450 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4451 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4452 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4453 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4454 0x0000ffff /* end */
4456 DWORD shader_code_20_2[] = {
4457 0xfffe0200, /* vs_2_0 */
4458 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4459 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4460 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4461 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4462 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4463 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4464 0x0000ffff /* end */
4466 static const D3DVERTEXELEMENT9 decl_elements[] = {
4467 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4468 D3DDECL_END()
4470 float quad1[] = {
4471 -1.0, -1.0, 0.1,
4472 0.0, -1.0, 0.1,
4473 -1.0, 0.0, 0.1,
4474 0.0, 0.0, 0.1
4476 float quad2[] = {
4477 0.0, -1.0, 0.1,
4478 1.0, -1.0, 0.1,
4479 0.0, 0.0, 0.1,
4480 1.0, 0.0, 0.1
4482 float quad3[] = {
4483 0.0, 0.0, 0.1,
4484 1.0, 0.0, 0.1,
4485 0.0, 1.0, 0.1,
4486 1.0, 1.0, 0.1
4488 float quad4[] = {
4489 -1.0, 0.0, 0.1,
4490 0.0, 0.0, 0.1,
4491 -1.0, 1.0, 0.1,
4492 0.0, 1.0, 0.1
4494 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4495 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4497 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4498 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4500 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4501 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4502 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4503 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4504 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4505 if(FAILED(hr)) shader_20 = NULL;
4506 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4507 if(FAILED(hr)) shader_20_2 = NULL;
4508 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4509 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4511 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4512 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4513 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4514 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4515 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4516 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4518 hr = IDirect3DDevice9_BeginScene(device);
4519 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4520 if(SUCCEEDED(hr))
4522 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4523 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4525 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4527 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4528 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4530 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4532 if(shader_20) {
4533 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4534 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4536 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4539 if(shader_20_2) {
4540 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4541 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4543 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4546 hr = IDirect3DDevice9_EndScene(device);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4550 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4551 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4552 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4553 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4555 color = getPixelColor(device, 160, 360);
4556 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4557 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4558 color = getPixelColor(device, 480, 360);
4559 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4560 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4561 if(shader_20) {
4562 color = getPixelColor(device, 160, 120);
4563 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4564 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4566 if(shader_20_2) {
4567 color = getPixelColor(device, 480, 120);
4568 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4569 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4571 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4572 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4574 IDirect3DVertexDeclaration9_Release(decl);
4575 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4576 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4577 IDirect3DVertexShader9_Release(shader_11_2);
4578 IDirect3DVertexShader9_Release(shader_11);
4581 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4583 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4584 HRESULT hr;
4585 DWORD color;
4586 DWORD shader_code_11[] = {
4587 0xffff0101, /* ps_1_1 */
4588 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4589 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4590 0x0000ffff /* end */
4592 DWORD shader_code_12[] = {
4593 0xffff0102, /* ps_1_2 */
4594 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4595 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4596 0x0000ffff /* end */
4598 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4599 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4600 * During development of this test, 1.3 shaders were verified too
4602 DWORD shader_code_14[] = {
4603 0xffff0104, /* ps_1_4 */
4604 /* Try to make one constant local. It gets clamped too, although the binary contains
4605 * the bigger numbers
4607 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4608 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4609 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4610 0x0000ffff /* end */
4612 DWORD shader_code_20[] = {
4613 0xffff0200, /* ps_2_0 */
4614 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4615 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4616 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4617 0x0000ffff /* end */
4619 float quad1[] = {
4620 -1.0, -1.0, 0.1,
4621 0.0, -1.0, 0.1,
4622 -1.0, 0.0, 0.1,
4623 0.0, 0.0, 0.1
4625 float quad2[] = {
4626 0.0, -1.0, 0.1,
4627 1.0, -1.0, 0.1,
4628 0.0, 0.0, 0.1,
4629 1.0, 0.0, 0.1
4631 float quad3[] = {
4632 0.0, 0.0, 0.1,
4633 1.0, 0.0, 0.1,
4634 0.0, 1.0, 0.1,
4635 1.0, 1.0, 0.1
4637 float quad4[] = {
4638 -1.0, 0.0, 0.1,
4639 0.0, 0.0, 0.1,
4640 -1.0, 1.0, 0.1,
4641 0.0, 1.0, 0.1
4643 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4644 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4647 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4649 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4650 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4651 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4652 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4653 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4654 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4655 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4656 if(FAILED(hr)) shader_20 = NULL;
4658 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4659 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4660 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4661 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4662 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4663 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4665 hr = IDirect3DDevice9_BeginScene(device);
4666 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4667 if(SUCCEEDED(hr))
4669 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4670 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4672 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4674 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4675 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4677 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4679 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4680 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4682 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4684 if(shader_20) {
4685 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4686 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4688 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4691 hr = IDirect3DDevice9_EndScene(device);
4692 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4694 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4695 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4697 color = getPixelColor(device, 160, 360);
4698 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4699 "quad 1 has color %08x, expected 0x00808000\n", color);
4700 color = getPixelColor(device, 480, 360);
4701 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4702 "quad 2 has color %08x, expected 0x00808000\n", color);
4703 color = getPixelColor(device, 480, 120);
4704 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4705 "quad 3 has color %08x, expected 0x00808000\n", color);
4706 if(shader_20) {
4707 color = getPixelColor(device, 160, 120);
4708 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4709 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4712 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4714 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4715 IDirect3DPixelShader9_Release(shader_14);
4716 IDirect3DPixelShader9_Release(shader_12);
4717 IDirect3DPixelShader9_Release(shader_11);
4720 static void dp2add_ps_test(IDirect3DDevice9 *device)
4722 IDirect3DPixelShader9 *shader_dp2add = NULL;
4723 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4724 HRESULT hr;
4725 DWORD color;
4727 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4728 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4729 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4730 * r0 first.
4731 * The result here for the r,g,b components should be roughly 0.5:
4732 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4733 static const DWORD shader_code_dp2add[] = {
4734 0xffff0200, /* ps_2_0 */
4735 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4737 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4738 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4740 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4741 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4742 0x0000ffff /* end */
4745 /* Test the _sat modifier, too. Result here should be:
4746 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4747 * _SAT: ==> 1.0
4748 * ADD: (1.0 + -0.5) = 0.5
4750 static const DWORD shader_code_dp2add_sat[] = {
4751 0xffff0200, /* ps_2_0 */
4752 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4754 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4755 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4756 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4758 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4759 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4760 0x0000ffff /* end */
4763 const float quad[] = {
4764 -1.0, -1.0, 0.1,
4765 1.0, -1.0, 0.1,
4766 -1.0, 1.0, 0.1,
4767 1.0, 1.0, 0.1
4771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4772 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4774 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4775 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4777 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4780 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4781 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4783 if (shader_dp2add) {
4785 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4786 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4788 hr = IDirect3DDevice9_BeginScene(device);
4789 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4790 if(SUCCEEDED(hr))
4792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4793 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4795 hr = IDirect3DDevice9_EndScene(device);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4799 color = getPixelColor(device, 360, 240);
4800 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4801 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4803 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4804 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4806 IDirect3DPixelShader9_Release(shader_dp2add);
4807 } else {
4808 skip("dp2add shader creation failed\n");
4811 if (shader_dp2add_sat) {
4813 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4816 hr = IDirect3DDevice9_BeginScene(device);
4817 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4818 if(SUCCEEDED(hr))
4820 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4821 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4823 hr = IDirect3DDevice9_EndScene(device);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4827 color = getPixelColor(device, 360, 240);
4828 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4829 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4831 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4834 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4835 } else {
4836 skip("dp2add shader creation failed\n");
4839 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4843 static void cnd_test(IDirect3DDevice9 *device)
4845 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4846 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4847 HRESULT hr;
4848 DWORD color;
4849 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4850 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4851 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4853 DWORD shader_code_11[] = {
4854 0xffff0101, /* ps_1_1 */
4855 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4856 0x00000040, 0xb00f0000, /* texcoord t0 */
4857 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4858 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4859 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4860 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4861 0x0000ffff /* end */
4863 DWORD shader_code_12[] = {
4864 0xffff0102, /* ps_1_2 */
4865 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4866 0x00000040, 0xb00f0000, /* texcoord t0 */
4867 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4868 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4869 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4870 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4871 0x0000ffff /* end */
4873 DWORD shader_code_13[] = {
4874 0xffff0103, /* ps_1_3 */
4875 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4876 0x00000040, 0xb00f0000, /* texcoord t0 */
4877 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4878 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4879 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4880 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4881 0x0000ffff /* end */
4883 DWORD shader_code_14[] = {
4884 0xffff0104, /* ps_1_3 */
4885 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4886 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4887 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4888 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4889 0x0000ffff /* end */
4892 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4893 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4894 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4895 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4896 * native CreatePixelShader returns an error.
4898 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4899 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4900 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4901 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4903 DWORD shader_code_11_coissue[] = {
4904 0xffff0101, /* ps_1_1 */
4905 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4906 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4907 0x00000040, 0xb00f0000, /* texcoord t0 */
4908 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4909 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4910 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4911 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4912 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4913 /* 0x40000000 = D3DSI_COISSUE */
4914 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4915 0x0000ffff /* end */
4917 DWORD shader_code_12_coissue[] = {
4918 0xffff0102, /* ps_1_2 */
4919 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4920 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4921 0x00000040, 0xb00f0000, /* texcoord t0 */
4922 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4923 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4924 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4925 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4926 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4927 /* 0x40000000 = D3DSI_COISSUE */
4928 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4929 0x0000ffff /* end */
4931 DWORD shader_code_13_coissue[] = {
4932 0xffff0103, /* ps_1_3 */
4933 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4934 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4935 0x00000040, 0xb00f0000, /* texcoord t0 */
4936 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4937 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4938 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4939 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4940 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4941 /* 0x40000000 = D3DSI_COISSUE */
4942 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4943 0x0000ffff /* end */
4945 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4946 * compare against 0.5
4948 DWORD shader_code_14_coissue[] = {
4949 0xffff0104, /* ps_1_4 */
4950 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4951 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4952 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4953 /* 0x40000000 = D3DSI_COISSUE */
4954 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4955 0x0000ffff /* end */
4957 float quad1[] = {
4958 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4959 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4960 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4961 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4963 float quad2[] = {
4964 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4965 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4966 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4967 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4969 float quad3[] = {
4970 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4971 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4972 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4973 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4975 float quad4[] = {
4976 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4977 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4978 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4979 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4981 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4982 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4983 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4984 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4986 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4987 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4989 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4990 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4991 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4993 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4994 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4995 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4996 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4997 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4998 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4999 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5001 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5002 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5003 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5006 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5007 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5008 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5009 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5010 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5011 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5013 hr = IDirect3DDevice9_BeginScene(device);
5014 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5015 if(SUCCEEDED(hr))
5017 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5018 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5019 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5020 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5022 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5023 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5025 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5027 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5028 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5030 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5032 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5033 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5035 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5037 hr = IDirect3DDevice9_EndScene(device);
5038 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5041 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5042 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5044 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5045 color = getPixelColor(device, 158, 118);
5046 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5047 color = getPixelColor(device, 162, 118);
5048 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5049 color = getPixelColor(device, 158, 122);
5050 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5051 color = getPixelColor(device, 162, 122);
5052 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5054 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5055 color = getPixelColor(device, 158, 358);
5056 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5057 color = getPixelColor(device, 162, 358);
5058 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5059 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5060 color = getPixelColor(device, 158, 362);
5061 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5062 color = getPixelColor(device, 162, 362);
5063 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5064 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5066 /* 1.2 shader */
5067 color = getPixelColor(device, 478, 358);
5068 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5069 color = getPixelColor(device, 482, 358);
5070 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5071 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5072 color = getPixelColor(device, 478, 362);
5073 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5074 color = getPixelColor(device, 482, 362);
5075 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5076 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5078 /* 1.3 shader */
5079 color = getPixelColor(device, 478, 118);
5080 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5081 color = getPixelColor(device, 482, 118);
5082 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5083 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5084 color = getPixelColor(device, 478, 122);
5085 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5086 color = getPixelColor(device, 482, 122);
5087 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5088 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5090 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5091 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5093 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5094 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5095 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5097 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5098 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5100 hr = IDirect3DDevice9_BeginScene(device);
5101 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5102 if(SUCCEEDED(hr))
5104 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5105 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5107 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5109 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5110 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5112 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5114 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5115 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5116 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5117 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5119 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5120 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5122 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5124 hr = IDirect3DDevice9_EndScene(device);
5125 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5128 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5129 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5131 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5132 * that we swapped the values in c1 and c2 to make the other tests return some color
5134 color = getPixelColor(device, 158, 118);
5135 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5136 color = getPixelColor(device, 162, 118);
5137 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5138 color = getPixelColor(device, 158, 122);
5139 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5140 color = getPixelColor(device, 162, 122);
5141 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5143 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5144 color = getPixelColor(device, 158, 358);
5145 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5146 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5147 color = getPixelColor(device, 162, 358);
5148 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5149 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5150 color = getPixelColor(device, 158, 362);
5151 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5152 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5153 color = getPixelColor(device, 162, 362);
5154 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5155 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5157 /* 1.2 shader */
5158 color = getPixelColor(device, 478, 358);
5159 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5160 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5161 color = getPixelColor(device, 482, 358);
5162 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5163 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5164 color = getPixelColor(device, 478, 362);
5165 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5166 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5167 color = getPixelColor(device, 482, 362);
5168 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5169 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5171 /* 1.3 shader */
5172 color = getPixelColor(device, 478, 118);
5173 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5174 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5175 color = getPixelColor(device, 482, 118);
5176 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5177 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5178 color = getPixelColor(device, 478, 122);
5179 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5180 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5181 color = getPixelColor(device, 482, 122);
5182 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5183 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5185 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5186 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5188 IDirect3DPixelShader9_Release(shader_14_coissue);
5189 IDirect3DPixelShader9_Release(shader_13_coissue);
5190 IDirect3DPixelShader9_Release(shader_12_coissue);
5191 IDirect3DPixelShader9_Release(shader_11_coissue);
5192 IDirect3DPixelShader9_Release(shader_14);
5193 IDirect3DPixelShader9_Release(shader_13);
5194 IDirect3DPixelShader9_Release(shader_12);
5195 IDirect3DPixelShader9_Release(shader_11);
5198 static void nested_loop_test(IDirect3DDevice9 *device) {
5199 const DWORD shader_code[] = {
5200 0xffff0300, /* ps_3_0 */
5201 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5202 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5203 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5204 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5205 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5206 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5207 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5208 0x0000001d, /* endloop */
5209 0x0000001d, /* endloop */
5210 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5211 0x0000ffff /* end */
5213 IDirect3DPixelShader9 *shader;
5214 HRESULT hr;
5215 DWORD color;
5216 const float quad[] = {
5217 -1.0, -1.0, 0.1,
5218 1.0, -1.0, 0.1,
5219 -1.0, 1.0, 0.1,
5220 1.0, 1.0, 0.1
5223 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5224 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5225 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5226 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5227 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5228 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5230 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5232 hr = IDirect3DDevice9_BeginScene(device);
5233 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5234 if(SUCCEEDED(hr))
5236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5237 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5238 hr = IDirect3DDevice9_EndScene(device);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5242 color = getPixelColor(device, 360, 240);
5243 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5244 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5246 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5249 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5250 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5251 IDirect3DPixelShader9_Release(shader);
5254 struct varying_test_struct
5256 const DWORD *shader_code;
5257 IDirect3DPixelShader9 *shader;
5258 DWORD color, color_rhw;
5259 const char *name;
5260 BOOL todo, todo_rhw;
5263 struct hugeVertex
5265 float pos_x, pos_y, pos_z, rhw;
5266 float weight_1, weight_2, weight_3, weight_4;
5267 float index_1, index_2, index_3, index_4;
5268 float normal_1, normal_2, normal_3, normal_4;
5269 float fog_1, fog_2, fog_3, fog_4;
5270 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5271 float tangent_1, tangent_2, tangent_3, tangent_4;
5272 float binormal_1, binormal_2, binormal_3, binormal_4;
5273 float depth_1, depth_2, depth_3, depth_4;
5274 DWORD diffuse, specular;
5277 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5278 /* dcl_position: fails to compile */
5279 const DWORD blendweight_code[] = {
5280 0xffff0300, /* ps_3_0 */
5281 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5282 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5283 0x0000ffff /* end */
5285 const DWORD blendindices_code[] = {
5286 0xffff0300, /* ps_3_0 */
5287 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5288 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5289 0x0000ffff /* end */
5291 const DWORD normal_code[] = {
5292 0xffff0300, /* ps_3_0 */
5293 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5294 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5295 0x0000ffff /* end */
5297 /* psize: fails? */
5298 const DWORD texcoord0_code[] = {
5299 0xffff0300, /* ps_3_0 */
5300 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5301 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5302 0x0000ffff /* end */
5304 const DWORD tangent_code[] = {
5305 0xffff0300, /* ps_3_0 */
5306 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5307 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5308 0x0000ffff /* end */
5310 const DWORD binormal_code[] = {
5311 0xffff0300, /* ps_3_0 */
5312 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5313 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5314 0x0000ffff /* end */
5316 /* tessfactor: fails */
5317 /* positiont: fails */
5318 const DWORD color_code[] = {
5319 0xffff0300, /* ps_3_0 */
5320 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5321 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5322 0x0000ffff /* end */
5324 const DWORD fog_code[] = {
5325 0xffff0300, /* ps_3_0 */
5326 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5327 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5328 0x0000ffff /* end */
5330 const DWORD depth_code[] = {
5331 0xffff0300, /* ps_3_0 */
5332 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5333 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5334 0x0000ffff /* end */
5336 const DWORD specular_code[] = {
5337 0xffff0300, /* ps_3_0 */
5338 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5339 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5340 0x0000ffff /* end */
5342 /* sample: fails */
5344 struct varying_test_struct tests[] = {
5345 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5346 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5347 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5348 /* Why does dx not forward the texcoord? */
5349 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5350 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5351 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5352 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5353 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5354 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5355 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5357 /* Declare a monster vertex type :-) */
5358 static const D3DVERTEXELEMENT9 decl_elements[] = {
5359 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5360 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5361 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5362 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5363 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5364 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5365 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5366 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5367 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5368 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5369 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5370 D3DDECL_END()
5372 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5373 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5374 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5375 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5376 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5377 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5378 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5379 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5380 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5381 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5382 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5383 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5384 D3DDECL_END()
5386 struct hugeVertex data[4] = {
5388 -1.0, -1.0, 0.1, 1.0,
5389 0.1, 0.1, 0.1, 0.1,
5390 0.2, 0.2, 0.2, 0.2,
5391 0.3, 0.3, 0.3, 0.3,
5392 0.4, 0.4, 0.4, 0.4,
5393 0.50, 0.55, 0.55, 0.55,
5394 0.6, 0.6, 0.6, 0.7,
5395 0.7, 0.7, 0.7, 0.6,
5396 0.8, 0.8, 0.8, 0.8,
5397 0xe6e6e6e6, /* 0.9 * 256 */
5398 0x224488ff /* Nothing special */
5401 1.0, -1.0, 0.1, 1.0,
5402 0.1, 0.1, 0.1, 0.1,
5403 0.2, 0.2, 0.2, 0.2,
5404 0.3, 0.3, 0.3, 0.3,
5405 0.4, 0.4, 0.4, 0.4,
5406 0.50, 0.55, 0.55, 0.55,
5407 0.6, 0.6, 0.6, 0.7,
5408 0.7, 0.7, 0.7, 0.6,
5409 0.8, 0.8, 0.8, 0.8,
5410 0xe6e6e6e6, /* 0.9 * 256 */
5411 0x224488ff /* Nothing special */
5414 -1.0, 1.0, 0.1, 1.0,
5415 0.1, 0.1, 0.1, 0.1,
5416 0.2, 0.2, 0.2, 0.2,
5417 0.3, 0.3, 0.3, 0.3,
5418 0.4, 0.4, 0.4, 0.4,
5419 0.50, 0.55, 0.55, 0.55,
5420 0.6, 0.6, 0.6, 0.7,
5421 0.7, 0.7, 0.7, 0.6,
5422 0.8, 0.8, 0.8, 0.8,
5423 0xe6e6e6e6, /* 0.9 * 256 */
5424 0x224488ff /* Nothing special */
5427 1.0, 1.0, 0.1, 1.0,
5428 0.1, 0.1, 0.1, 0.1,
5429 0.2, 0.2, 0.2, 0.2,
5430 0.3, 0.3, 0.3, 0.3,
5431 0.4, 0.4, 0.4, 0.4,
5432 0.50, 0.55, 0.55, 0.55,
5433 0.6, 0.6, 0.6, 0.7,
5434 0.7, 0.7, 0.7, 0.6,
5435 0.8, 0.8, 0.8, 0.8,
5436 0xe6e6e6e6, /* 0.9 * 256 */
5437 0x224488ff /* Nothing special */
5440 struct hugeVertex data2[4];
5441 IDirect3DVertexDeclaration9 *decl;
5442 IDirect3DVertexDeclaration9 *decl2;
5443 HRESULT hr;
5444 unsigned int i;
5445 DWORD color, r, g, b, r_e, g_e, b_e;
5446 BOOL drawok;
5448 memcpy(data2, data, sizeof(data2));
5449 data2[0].pos_x = 0; data2[0].pos_y = 0;
5450 data2[1].pos_x = 640; data2[1].pos_y = 0;
5451 data2[2].pos_x = 0; data2[2].pos_y = 480;
5452 data2[3].pos_x = 640; data2[3].pos_y = 480;
5454 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5456 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5457 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5458 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5459 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5461 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5463 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5464 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5465 tests[i].name, hr);
5468 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5471 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5473 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5474 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5476 hr = IDirect3DDevice9_BeginScene(device);
5477 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5478 drawok = FALSE;
5479 if(SUCCEEDED(hr))
5481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5482 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5483 drawok = SUCCEEDED(hr);
5484 hr = IDirect3DDevice9_EndScene(device);
5485 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5488 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5489 * the failure and do not check the color if it failed
5491 if(!drawok) {
5492 continue;
5495 color = getPixelColor(device, 360, 240);
5496 r = color & 0x00ff0000 >> 16;
5497 g = color & 0x0000ff00 >> 8;
5498 b = color & 0x000000ff;
5499 r_e = tests[i].color & 0x00ff0000 >> 16;
5500 g_e = tests[i].color & 0x0000ff00 >> 8;
5501 b_e = tests[i].color & 0x000000ff;
5503 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5504 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5506 if(tests[i].todo) {
5507 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5508 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5509 tests[i].name, color, tests[i].color);
5510 } else {
5511 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5512 "Test %s returned color 0x%08x, expected 0x%08x\n",
5513 tests[i].name, color, tests[i].color);
5517 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5519 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5521 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5524 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5527 hr = IDirect3DDevice9_BeginScene(device);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5529 if(SUCCEEDED(hr))
5531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5532 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5533 hr = IDirect3DDevice9_EndScene(device);
5534 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5537 color = getPixelColor(device, 360, 240);
5538 r = color & 0x00ff0000 >> 16;
5539 g = color & 0x0000ff00 >> 8;
5540 b = color & 0x000000ff;
5541 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5542 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5543 b_e = tests[i].color_rhw & 0x000000ff;
5545 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5548 if(tests[i].todo_rhw) {
5549 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5550 * pipeline
5552 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5553 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5554 tests[i].name, color, tests[i].color_rhw);
5555 } else {
5556 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5557 "Test %s returned color 0x%08x, expected 0x%08x\n",
5558 tests[i].name, color, tests[i].color_rhw);
5562 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5564 IDirect3DPixelShader9_Release(tests[i].shader);
5567 IDirect3DVertexDeclaration9_Release(decl2);
5568 IDirect3DVertexDeclaration9_Release(decl);
5571 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5572 static const DWORD ps_code[] = {
5573 0xffff0300, /* ps_3_0 */
5574 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5575 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5576 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5577 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5578 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5579 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5580 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5581 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5582 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5584 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5585 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5586 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5587 0x0000001d, /* endloop */
5588 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5589 0x0000ffff /* end */
5591 static const DWORD vs_1_code[] = {
5592 0xfffe0101, /* vs_1_1 */
5593 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5594 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5595 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5596 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5597 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5598 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5599 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5600 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5601 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5602 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5603 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5604 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5605 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5606 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5607 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5608 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5609 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5610 0x0000ffff
5612 DWORD vs_2_code[] = {
5613 0xfffe0200, /* vs_2_0 */
5614 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5615 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5616 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5617 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5618 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5619 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5620 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5621 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5622 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5623 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5624 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5625 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5626 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5627 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5628 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5629 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5630 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5631 0x0000ffff /* end */
5633 /* TODO: Define normal, tangent, blendweight and depth here */
5634 static const DWORD vs_3_code[] = {
5635 0xfffe0300, /* vs_3_0 */
5636 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5637 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5638 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5639 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5640 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5641 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5642 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5643 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5644 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5645 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5646 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5647 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5648 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5649 0x0000ffff /* end */
5651 float quad1[] = {
5652 -1.0, -1.0, 0.1,
5653 0.0, -1.0, 0.1,
5654 -1.0, 0.0, 0.1,
5655 0.0, 0.0, 0.1
5657 float quad2[] = {
5658 0.0, -1.0, 0.1,
5659 1.0, -1.0, 0.1,
5660 0.0, 0.0, 0.1,
5661 1.0, 0.0, 0.1
5663 float quad3[] = {
5664 -1.0, 0.0, 0.1,
5665 0.0, 0.0, 0.1,
5666 -1.0, 1.0, 0.1,
5667 0.0, 1.0, 0.1
5670 HRESULT hr;
5671 DWORD color;
5672 IDirect3DPixelShader9 *pixelshader = NULL;
5673 IDirect3DVertexShader9 *vs_1_shader = NULL;
5674 IDirect3DVertexShader9 *vs_2_shader = NULL;
5675 IDirect3DVertexShader9 *vs_3_shader = NULL;
5677 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5678 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5680 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5681 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5682 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5683 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5684 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5685 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5686 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5687 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5688 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5689 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5690 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5692 hr = IDirect3DDevice9_BeginScene(device);
5693 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5694 if(SUCCEEDED(hr))
5696 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5697 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5698 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5699 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5701 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5702 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5704 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5706 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5707 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5709 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5711 hr = IDirect3DDevice9_EndScene(device);
5712 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5715 color = getPixelColor(device, 160, 120);
5716 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5717 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5718 /* Accept two ways of oFog handling:
5720 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5721 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5723 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5724 * This happens with software vertex processing and on Intel cards
5726 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5727 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5729 color = getPixelColor(device, 160, 360);
5730 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5731 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5732 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5733 color = getPixelColor(device, 480, 360);
5734 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5735 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5736 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5738 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5739 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5741 /* cleanup */
5742 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5743 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5744 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5745 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5746 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5747 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5748 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5749 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5752 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5753 static const DWORD vs_code[] = {
5754 0xfffe0300, /* vs_3_0 */
5755 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5756 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5757 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5758 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5759 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5760 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5761 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5762 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5763 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5764 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5765 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5766 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5767 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5769 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5770 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5771 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5772 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5773 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5774 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5775 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5776 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5777 0x0000ffff /* end */
5779 static const DWORD ps_1_code[] = {
5780 0xffff0104, /* ps_1_4 */
5781 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5782 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5783 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5784 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5785 0x0000ffff /* end */
5787 static const DWORD ps_2_code[] = {
5788 0xffff0200, /* ps_2_0 */
5789 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5790 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5791 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5793 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5794 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5795 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5796 0x0000ffff /* end */
5798 static const DWORD ps_3_code[] = {
5799 0xffff0300, /* ps_3_0 */
5800 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5801 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5802 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5804 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5805 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5806 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5807 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5808 0x0000ffff /* end */
5811 float quad1[] = {
5812 -1.0, -1.0, 0.1,
5813 0.0, -1.0, 0.1,
5814 -1.0, 0.0, 0.1,
5815 0.0, 0.0, 0.1
5817 float quad2[] = {
5818 0.0, -1.0, 0.1,
5819 1.0, -1.0, 0.1,
5820 0.0, 0.0, 0.1,
5821 1.0, 0.0, 0.1
5823 float quad3[] = {
5824 -1.0, 0.0, 0.1,
5825 0.0, 0.0, 0.1,
5826 -1.0, 1.0, 0.1,
5827 0.0, 1.0, 0.1
5829 float quad4[] = {
5830 0.0, 0.0, 0.1,
5831 1.0, 0.0, 0.1,
5832 0.0, 1.0, 0.1,
5833 1.0, 1.0, 0.1
5836 HRESULT hr;
5837 DWORD color;
5838 IDirect3DVertexShader9 *vertexshader = NULL;
5839 IDirect3DPixelShader9 *ps_1_shader = NULL;
5840 IDirect3DPixelShader9 *ps_2_shader = NULL;
5841 IDirect3DPixelShader9 *ps_3_shader = NULL;
5842 IDirect3DTexture9 *texture = NULL;
5843 D3DLOCKED_RECT lr;
5844 unsigned int x, y;
5846 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5847 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5849 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5850 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5851 if(FAILED(hr)) {
5852 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5853 return;
5855 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5856 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5857 for(y = 0; y < 512; y++) {
5858 for(x = 0; x < 512; x++) {
5859 double r_f = (double) x / (double) 512;
5860 double g_f = (double) y / (double) 512;
5861 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5862 unsigned short r = (unsigned short) (r_f * 65535.0);
5863 unsigned short g = (unsigned short) (g_f * 65535.0);
5864 dst[0] = r;
5865 dst[1] = g;
5866 dst[2] = 0;
5867 dst[3] = 65535;
5870 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5871 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5873 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5874 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5875 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5876 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5877 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5878 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5879 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5880 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5881 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5882 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5883 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5885 hr = IDirect3DDevice9_BeginScene(device);
5886 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5887 if(SUCCEEDED(hr))
5889 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5890 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5892 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5894 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5895 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5897 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5899 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5900 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5902 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5904 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5905 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5906 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5907 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5908 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5909 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5910 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5912 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5914 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5915 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5917 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5919 hr = IDirect3DDevice9_EndScene(device);
5920 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5923 color = getPixelColor(device, 160, 120);
5924 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5925 (color & 0x0000ff00) == 0x0000ff00 &&
5926 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5927 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5928 color = getPixelColor(device, 160, 360);
5929 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5930 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5931 (color & 0x000000ff) == 0x00000000,
5932 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5933 color = getPixelColor(device, 480, 360);
5934 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5935 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5936 (color & 0x000000ff) == 0x00000000,
5937 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5938 color = getPixelColor(device, 480, 160);
5939 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5940 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5941 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5942 (color & 0x000000ff) == 0x00000000),
5943 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5945 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5946 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5948 /* cleanup */
5949 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5950 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5951 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5952 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5953 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5955 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5956 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5957 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5958 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5959 if(texture) IDirect3DTexture9_Release(texture);
5962 static void test_compare_instructions(IDirect3DDevice9 *device)
5964 DWORD shader_sge_vec_code[] = {
5965 0xfffe0101, /* vs_1_1 */
5966 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5967 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5968 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5969 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5970 0x0000ffff /* end */
5972 DWORD shader_slt_vec_code[] = {
5973 0xfffe0101, /* vs_1_1 */
5974 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5975 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5976 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5977 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5978 0x0000ffff /* end */
5980 DWORD shader_sge_scalar_code[] = {
5981 0xfffe0101, /* vs_1_1 */
5982 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5983 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5984 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5985 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5986 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5987 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5988 0x0000ffff /* end */
5990 DWORD shader_slt_scalar_code[] = {
5991 0xfffe0101, /* vs_1_1 */
5992 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5993 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5994 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5995 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5996 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5997 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5998 0x0000ffff /* end */
6000 IDirect3DVertexShader9 *shader_sge_vec;
6001 IDirect3DVertexShader9 *shader_slt_vec;
6002 IDirect3DVertexShader9 *shader_sge_scalar;
6003 IDirect3DVertexShader9 *shader_slt_scalar;
6004 HRESULT hr, color;
6005 float quad1[] = {
6006 -1.0, -1.0, 0.1,
6007 0.0, -1.0, 0.1,
6008 -1.0, 0.0, 0.1,
6009 0.0, 0.0, 0.1
6011 float quad2[] = {
6012 0.0, -1.0, 0.1,
6013 1.0, -1.0, 0.1,
6014 0.0, 0.0, 0.1,
6015 1.0, 0.0, 0.1
6017 float quad3[] = {
6018 -1.0, 0.0, 0.1,
6019 0.0, 0.0, 0.1,
6020 -1.0, 1.0, 0.1,
6021 0.0, 1.0, 0.1
6023 float quad4[] = {
6024 0.0, 0.0, 0.1,
6025 1.0, 0.0, 0.1,
6026 0.0, 1.0, 0.1,
6027 1.0, 1.0, 0.1
6029 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6030 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6033 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6035 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6036 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6037 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6039 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6040 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6041 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6042 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6043 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6044 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6045 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6046 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6047 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6050 hr = IDirect3DDevice9_BeginScene(device);
6051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6052 if(SUCCEEDED(hr))
6054 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6055 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6057 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6059 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6060 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6062 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6064 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6065 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6067 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6069 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6070 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6072 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6073 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6075 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6077 hr = IDirect3DDevice9_EndScene(device);
6078 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6081 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6084 color = getPixelColor(device, 160, 360);
6085 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6086 color = getPixelColor(device, 480, 360);
6087 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6088 color = getPixelColor(device, 160, 120);
6089 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6090 color = getPixelColor(device, 480, 160);
6091 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6094 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6096 IDirect3DVertexShader9_Release(shader_sge_vec);
6097 IDirect3DVertexShader9_Release(shader_slt_vec);
6098 IDirect3DVertexShader9_Release(shader_sge_scalar);
6099 IDirect3DVertexShader9_Release(shader_slt_scalar);
6102 static void test_vshader_input(IDirect3DDevice9 *device)
6104 DWORD swapped_shader_code_3[] = {
6105 0xfffe0300, /* vs_3_0 */
6106 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6107 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6108 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6109 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6110 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6111 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6112 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6113 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6114 0x0000ffff /* end */
6116 DWORD swapped_shader_code_1[] = {
6117 0xfffe0101, /* vs_1_1 */
6118 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6119 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6120 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6121 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6122 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6123 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6124 0x0000ffff /* end */
6126 DWORD swapped_shader_code_2[] = {
6127 0xfffe0200, /* vs_2_0 */
6128 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6129 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6130 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6131 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6132 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6133 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6134 0x0000ffff /* end */
6136 DWORD texcoord_color_shader_code_3[] = {
6137 0xfffe0300, /* vs_3_0 */
6138 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6139 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6140 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6141 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6142 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6143 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6144 0x0000ffff /* end */
6146 DWORD texcoord_color_shader_code_2[] = {
6147 0xfffe0200, /* vs_2_0 */
6148 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6149 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6150 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6151 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6152 0x0000ffff /* end */
6154 DWORD texcoord_color_shader_code_1[] = {
6155 0xfffe0101, /* vs_1_1 */
6156 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6157 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6158 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6159 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6160 0x0000ffff /* end */
6162 DWORD color_color_shader_code_3[] = {
6163 0xfffe0300, /* vs_3_0 */
6164 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6165 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6166 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6167 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6168 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6169 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6170 0x0000ffff /* end */
6172 DWORD color_color_shader_code_2[] = {
6173 0xfffe0200, /* vs_2_0 */
6174 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6175 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6176 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6177 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6178 0x0000ffff /* end */
6180 DWORD color_color_shader_code_1[] = {
6181 0xfffe0101, /* vs_1_1 */
6182 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6183 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6184 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6185 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6186 0x0000ffff /* end */
6188 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6189 HRESULT hr;
6190 DWORD color;
6191 float quad1[] = {
6192 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6193 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6194 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6195 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6197 float quad2[] = {
6198 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6199 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6200 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6201 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6203 float quad3[] = {
6204 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6205 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6206 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6207 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6209 float quad4[] = {
6210 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6211 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6212 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6213 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6215 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6216 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6217 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6218 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6219 D3DDECL_END()
6221 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6222 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6223 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6224 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6225 D3DDECL_END()
6227 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6228 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6229 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6230 D3DDECL_END()
6232 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6233 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6234 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6235 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6236 D3DDECL_END()
6238 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6239 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6240 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6241 D3DDECL_END()
6243 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6244 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6245 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6246 D3DDECL_END()
6248 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6249 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6250 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6251 D3DDECL_END()
6253 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6254 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6255 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6256 D3DDECL_END()
6258 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6259 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6260 unsigned int i;
6261 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6262 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6264 struct vertex quad1_color[] = {
6265 {-1.0, -1.0, 0.1, 0x00ff8040},
6266 { 0.0, -1.0, 0.1, 0x00ff8040},
6267 {-1.0, 0.0, 0.1, 0x00ff8040},
6268 { 0.0, 0.0, 0.1, 0x00ff8040}
6270 struct vertex quad2_color[] = {
6271 { 0.0, -1.0, 0.1, 0x00ff8040},
6272 { 1.0, -1.0, 0.1, 0x00ff8040},
6273 { 0.0, 0.0, 0.1, 0x00ff8040},
6274 { 1.0, 0.0, 0.1, 0x00ff8040}
6276 struct vertex quad3_color[] = {
6277 {-1.0, 0.0, 0.1, 0x00ff8040},
6278 { 0.0, 0.0, 0.1, 0x00ff8040},
6279 {-1.0, 1.0, 0.1, 0x00ff8040},
6280 { 0.0, 1.0, 0.1, 0x00ff8040}
6282 float quad4_color[] = {
6283 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6284 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6285 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6286 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6289 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6290 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6291 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6292 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6293 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6294 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6295 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6296 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6298 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6299 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6300 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6301 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6302 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6304 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6305 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6307 for(i = 1; i <= 3; i++) {
6308 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6309 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6310 if(i == 3) {
6311 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6312 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6313 } else if(i == 2){
6314 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6316 } else if(i == 1) {
6317 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6318 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6321 hr = IDirect3DDevice9_BeginScene(device);
6322 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6323 if(SUCCEEDED(hr))
6325 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6326 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6328 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6329 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6330 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6331 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6333 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6334 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6336 if(i == 3 || i == 2) {
6337 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6338 } else if(i == 1) {
6339 /* Succeeds or fails, depending on SW or HW vertex processing */
6340 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6343 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6346 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6348 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6349 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6351 if(i == 3 || i == 2) {
6352 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6353 } else if(i == 1) {
6354 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6357 hr = IDirect3DDevice9_EndScene(device);
6358 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6361 if(i == 3 || i == 2) {
6362 color = getPixelColor(device, 160, 360);
6363 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6364 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6366 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6367 color = getPixelColor(device, 480, 360);
6368 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6369 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6370 color = getPixelColor(device, 160, 120);
6371 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6372 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6373 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6375 color = getPixelColor(device, 480, 160);
6376 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6377 } else if(i == 1) {
6378 color = getPixelColor(device, 160, 360);
6379 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6380 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6381 color = getPixelColor(device, 480, 360);
6382 /* Accept the clear color as well in this case, since SW VP returns an error */
6383 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6384 color = getPixelColor(device, 160, 120);
6385 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6386 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6387 color = getPixelColor(device, 480, 160);
6388 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6391 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6392 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6395 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6397 /* Now find out if the whole streams are re-read, or just the last active value for the
6398 * vertices is used.
6400 hr = IDirect3DDevice9_BeginScene(device);
6401 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6402 if(SUCCEEDED(hr))
6404 float quad1_modified[] = {
6405 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6406 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6407 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6408 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6410 float quad2_modified[] = {
6411 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6412 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6413 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6414 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6417 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6420 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6421 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6423 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6425 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6426 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6428 if(i == 3 || i == 2) {
6429 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6430 } else if(i == 1) {
6431 /* Succeeds or fails, depending on SW or HW vertex processing */
6432 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6435 hr = IDirect3DDevice9_EndScene(device);
6436 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6439 color = getPixelColor(device, 480, 350);
6440 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6441 * as well.
6443 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6444 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6445 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6446 * refrast's result.
6448 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6450 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6451 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6453 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6454 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6456 IDirect3DDevice9_SetVertexShader(device, NULL);
6457 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6459 IDirect3DVertexShader9_Release(swapped_shader);
6462 for(i = 1; i <= 3; i++) {
6463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6464 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6465 if(i == 3) {
6466 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6467 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6468 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6469 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6470 } else if(i == 2){
6471 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6472 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6473 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6474 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6475 } else if(i == 1) {
6476 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6477 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6478 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6479 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6482 hr = IDirect3DDevice9_BeginScene(device);
6483 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6484 if(SUCCEEDED(hr))
6486 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6487 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6488 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6489 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6490 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6491 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6493 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6494 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6496 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6497 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6498 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6501 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6503 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6504 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6505 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6506 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6507 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6508 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6510 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6511 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6512 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6513 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6515 hr = IDirect3DDevice9_EndScene(device);
6516 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6518 IDirect3DDevice9_SetVertexShader(device, NULL);
6519 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6521 color = getPixelColor(device, 160, 360);
6522 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6523 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6524 color = getPixelColor(device, 480, 360);
6525 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6526 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6527 color = getPixelColor(device, 160, 120);
6528 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6529 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6530 color = getPixelColor(device, 480, 160);
6531 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6532 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6534 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6535 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6537 IDirect3DVertexShader9_Release(texcoord_color_shader);
6538 IDirect3DVertexShader9_Release(color_color_shader);
6541 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6542 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6543 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6544 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6546 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6547 IDirect3DVertexDeclaration9_Release(decl_color_color);
6548 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6549 IDirect3DVertexDeclaration9_Release(decl_color_float);
6552 static void srgbtexture_test(IDirect3DDevice9 *device)
6554 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6555 * texture stage state to render a quad using that texture. The resulting
6556 * color components should be 0x36 (~ 0.21), per this formula:
6557 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6558 * This is true where srgb_color > 0.04045.
6560 IDirect3D9 *d3d = NULL;
6561 HRESULT hr;
6562 LPDIRECT3DTEXTURE9 texture = NULL;
6563 LPDIRECT3DSURFACE9 surface = NULL;
6564 D3DLOCKED_RECT lr;
6565 DWORD color;
6566 float quad[] = {
6567 -1.0, 1.0, 0.0, 0.0, 0.0,
6568 1.0, 1.0, 0.0, 1.0, 0.0,
6569 -1.0, -1.0, 0.0, 0.0, 1.0,
6570 1.0, -1.0, 0.0, 1.0, 1.0,
6574 memset(&lr, 0, sizeof(lr));
6575 IDirect3DDevice9_GetDirect3D(device, &d3d);
6576 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6577 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6578 D3DFMT_A8R8G8B8) != D3D_OK) {
6579 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6580 goto out;
6583 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6584 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6585 &texture, NULL);
6586 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6587 if(!texture) {
6588 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6589 goto out;
6591 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6592 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6594 fill_surface(surface, 0xff7f7f7f);
6595 IDirect3DSurface9_Release(surface);
6597 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6598 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6599 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6602 hr = IDirect3DDevice9_BeginScene(device);
6603 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6604 if(SUCCEEDED(hr))
6606 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6609 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6610 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6614 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6616 hr = IDirect3DDevice9_EndScene(device);
6617 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6620 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6621 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6622 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6623 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6625 color = getPixelColor(device, 320, 240);
6626 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6628 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6629 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6631 out:
6632 if(texture) IDirect3DTexture9_Release(texture);
6633 IDirect3D9_Release(d3d);
6636 static void shademode_test(IDirect3DDevice9 *device)
6638 /* Render a quad and try all of the different fixed function shading models. */
6639 HRESULT hr;
6640 DWORD color0, color1;
6641 DWORD color0_gouraud = 0, color1_gouraud = 0;
6642 DWORD shademode = D3DSHADE_FLAT;
6643 DWORD primtype = D3DPT_TRIANGLESTRIP;
6644 LPVOID data = NULL;
6645 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6646 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6647 UINT i, j;
6648 struct vertex quad_strip[] =
6650 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6651 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6652 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6653 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6655 struct vertex quad_list[] =
6657 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6658 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6659 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6661 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6662 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6663 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6666 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6667 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6668 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6669 if (FAILED(hr)) goto bail;
6671 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6672 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6673 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6674 if (FAILED(hr)) goto bail;
6676 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6679 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6680 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6682 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6683 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6684 memcpy(data, quad_strip, sizeof(quad_strip));
6685 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6686 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6688 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6689 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6690 memcpy(data, quad_list, sizeof(quad_list));
6691 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6692 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6694 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6695 * the color fixups we have to do for FLAT shading will be dependent on that. */
6696 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6697 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6699 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6700 for (j=0; j<2; j++) {
6702 /* Inner loop just changes the D3DRS_SHADEMODE */
6703 for (i=0; i<3; i++) {
6704 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6705 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6708 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6710 hr = IDirect3DDevice9_BeginScene(device);
6711 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6712 if(SUCCEEDED(hr))
6714 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6715 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6717 hr = IDirect3DDevice9_EndScene(device);
6718 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6721 /* Sample two spots from the output */
6722 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6723 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6724 switch(shademode) {
6725 case D3DSHADE_FLAT:
6726 /* Should take the color of the first vertex of each triangle */
6727 if (0)
6729 /* This test depends on EXT_provoking_vertex being
6730 * available. This extension is currently (20090810)
6731 * not common enough to let the test fail if it isn't
6732 * present. */
6733 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6734 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6736 shademode = D3DSHADE_GOURAUD;
6737 break;
6738 case D3DSHADE_GOURAUD:
6739 /* Should be an interpolated blend */
6741 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6742 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6743 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6744 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6746 color0_gouraud = color0;
6747 color1_gouraud = color1;
6749 shademode = D3DSHADE_PHONG;
6750 break;
6751 case D3DSHADE_PHONG:
6752 /* Should be the same as GOURAUD, since no hardware implements this */
6753 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6754 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6755 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6756 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6758 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6759 color0_gouraud, color0);
6760 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6761 color1_gouraud, color1);
6762 break;
6766 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6767 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6769 /* Now, do it all over again with a TRIANGLELIST */
6770 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6771 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6772 primtype = D3DPT_TRIANGLELIST;
6773 shademode = D3DSHADE_FLAT;
6776 bail:
6777 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6778 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6782 if (vb_strip)
6783 IDirect3DVertexBuffer9_Release(vb_strip);
6784 if (vb_list)
6785 IDirect3DVertexBuffer9_Release(vb_list);
6789 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6791 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6792 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6793 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6794 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6795 * 0.73
6797 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6798 * so use shaders for this task
6800 IDirect3DPixelShader9 *pshader;
6801 IDirect3DVertexShader9 *vshader;
6802 IDirect3D9 *d3d;
6803 DWORD vshader_code[] = {
6804 0xfffe0101, /* vs_1_1 */
6805 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6806 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6807 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6808 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6809 0x0000ffff /* end */
6811 DWORD pshader_code[] = {
6812 0xffff0101, /* ps_1_1 */
6813 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6814 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6815 0x0000ffff /* end */
6817 const float quad[] = {
6818 -1.0, -1.0, 0.1,
6819 1.0, -1.0, 0.1,
6820 -1.0, 1.0, 0.1,
6821 1.0, 1.0, 0.1
6823 HRESULT hr;
6824 D3DCOLOR color;
6826 IDirect3DDevice9_GetDirect3D(device, &d3d);
6827 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6828 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6829 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6830 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6831 * works
6833 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6834 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6835 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6836 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6837 IDirect3D9_Release(d3d);
6838 return;
6840 IDirect3D9_Release(d3d);
6842 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6843 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6846 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6851 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6852 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6856 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6857 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6858 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6859 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6860 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6861 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6862 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6863 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6864 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6865 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6867 hr = IDirect3DDevice9_BeginScene(device);
6868 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6869 if(SUCCEEDED(hr)) {
6870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6871 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6873 hr = IDirect3DDevice9_EndScene(device);
6874 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6877 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6878 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6879 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6880 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6881 IDirect3DPixelShader9_Release(pshader);
6882 IDirect3DVertexShader9_Release(vshader);
6884 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6885 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6889 color = getPixelColor(device, 160, 360);
6890 ok(color_match(color, 0x00808080, 1),
6891 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6892 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6893 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6896 static void alpha_test(IDirect3DDevice9 *device)
6898 HRESULT hr;
6899 IDirect3DTexture9 *offscreenTexture;
6900 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6901 DWORD color;
6903 struct vertex quad1[] =
6905 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6906 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6907 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6908 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6910 struct vertex quad2[] =
6912 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6913 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6914 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6915 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6917 static const float composite_quad[][5] = {
6918 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6919 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6920 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6921 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6924 /* Clear the render target with alpha = 0.5 */
6925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6926 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6928 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6929 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6931 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6932 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6933 if(!backbuffer) {
6934 goto out;
6937 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6938 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6939 if(!offscreen) {
6940 goto out;
6943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6944 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6946 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6947 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6948 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6949 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6950 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6951 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6952 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6953 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6955 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6958 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6959 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6961 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6963 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6967 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6970 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6972 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6974 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6976 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6977 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6978 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6979 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6980 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6982 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6985 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6989 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6992 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6994 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6996 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6998 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6999 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7001 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7002 * Disable alpha blending for the final composition
7004 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7005 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7006 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7007 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7009 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7010 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7011 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7012 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7013 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7014 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7016 hr = IDirect3DDevice9_EndScene(device);
7017 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7020 color = getPixelColor(device, 160, 360);
7021 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7022 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7024 color = getPixelColor(device, 160, 120);
7025 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7026 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7028 color = getPixelColor(device, 480, 360);
7029 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7030 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7032 color = getPixelColor(device, 480, 120);
7033 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7034 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7036 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7038 out:
7039 /* restore things */
7040 if(backbuffer) {
7041 IDirect3DSurface9_Release(backbuffer);
7043 if(offscreenTexture) {
7044 IDirect3DTexture9_Release(offscreenTexture);
7046 if(offscreen) {
7047 IDirect3DSurface9_Release(offscreen);
7051 struct vertex_shortcolor {
7052 float x, y, z;
7053 unsigned short r, g, b, a;
7055 struct vertex_floatcolor {
7056 float x, y, z;
7057 float r, g, b, a;
7060 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7062 HRESULT hr;
7063 BOOL s_ok, ub_ok, f_ok;
7064 DWORD color, size, i;
7065 void *data;
7066 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7067 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7068 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7069 D3DDECL_END()
7071 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7072 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7073 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7074 D3DDECL_END()
7076 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7077 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7078 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7079 D3DDECL_END()
7081 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7082 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7083 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7084 D3DDECL_END()
7086 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7087 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7088 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7089 D3DDECL_END()
7091 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7092 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7093 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7094 D3DDECL_END()
7096 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7097 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7098 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7099 D3DDECL_END()
7101 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7102 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7103 IDirect3DVertexBuffer9 *vb, *vb2;
7104 struct vertex quad1[] = /* D3DCOLOR */
7106 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7107 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7108 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7109 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7111 struct vertex quad2[] = /* UBYTE4N */
7113 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7114 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7115 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7116 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7118 struct vertex_shortcolor quad3[] = /* short */
7120 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7121 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7122 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7123 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7125 struct vertex_floatcolor quad4[] =
7127 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7128 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7129 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7130 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7132 DWORD colors[] = {
7133 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7134 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7135 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7136 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7137 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7138 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7139 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7140 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7141 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7142 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7143 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7144 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7145 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7146 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7147 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7148 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7150 float quads[] = {
7151 -1.0, -1.0, 0.1,
7152 -1.0, 0.0, 0.1,
7153 0.0, -1.0, 0.1,
7154 0.0, 0.0, 0.1,
7156 0.0, -1.0, 0.1,
7157 0.0, 0.0, 0.1,
7158 1.0, -1.0, 0.1,
7159 1.0, 0.0, 0.1,
7161 0.0, 0.0, 0.1,
7162 0.0, 1.0, 0.1,
7163 1.0, 0.0, 0.1,
7164 1.0, 1.0, 0.1,
7166 -1.0, 0.0, 0.1,
7167 -1.0, 1.0, 0.1,
7168 0.0, 0.0, 0.1,
7169 0.0, 1.0, 0.1
7171 struct tvertex quad_transformed[] = {
7172 { 90, 110, 0.1, 2.0, 0x00ffff00},
7173 { 570, 110, 0.1, 2.0, 0x00ffff00},
7174 { 90, 300, 0.1, 2.0, 0x00ffff00},
7175 { 570, 300, 0.1, 2.0, 0x00ffff00}
7177 D3DCAPS9 caps;
7179 memset(&caps, 0, sizeof(caps));
7180 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7181 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7184 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7186 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7187 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7188 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7189 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7190 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7191 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7192 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7193 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7194 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7195 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7196 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7197 } else {
7198 trace("D3DDTCAPS_UBYTE4N not supported\n");
7199 dcl_ubyte_2 = NULL;
7200 dcl_ubyte = NULL;
7202 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7203 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7204 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7205 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7207 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7208 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7209 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7210 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7212 hr = IDirect3DDevice9_BeginScene(device);
7213 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7214 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7215 if(SUCCEEDED(hr)) {
7216 if(dcl_color) {
7217 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7218 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7220 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7223 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7224 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7225 * using software vertex processing. Doh!
7227 if(dcl_ubyte) {
7228 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7231 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7232 ub_ok = SUCCEEDED(hr);
7235 if(dcl_short) {
7236 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7238 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7239 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7240 s_ok = SUCCEEDED(hr);
7243 if(dcl_float) {
7244 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7245 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7247 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7248 f_ok = SUCCEEDED(hr);
7251 hr = IDirect3DDevice9_EndScene(device);
7252 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7255 if(dcl_short) {
7256 color = getPixelColor(device, 480, 360);
7257 ok(color == 0x000000ff || !s_ok,
7258 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7260 if(dcl_ubyte) {
7261 color = getPixelColor(device, 160, 120);
7262 ok(color == 0x0000ffff || !ub_ok,
7263 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7265 if(dcl_color) {
7266 color = getPixelColor(device, 160, 360);
7267 ok(color == 0x00ffff00,
7268 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7270 if(dcl_float) {
7271 color = getPixelColor(device, 480, 120);
7272 ok(color == 0x00ff0000 || !f_ok,
7273 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7275 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7277 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7278 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7279 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7280 * whether the immediate mode code works
7282 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7283 hr = IDirect3DDevice9_BeginScene(device);
7284 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7285 if(SUCCEEDED(hr)) {
7286 if(dcl_color) {
7287 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7288 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7289 memcpy(data, quad1, sizeof(quad1));
7290 hr = IDirect3DVertexBuffer9_Unlock(vb);
7291 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7292 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7293 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7294 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7295 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7296 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7297 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7300 if(dcl_ubyte) {
7301 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7302 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7303 memcpy(data, quad2, sizeof(quad2));
7304 hr = IDirect3DVertexBuffer9_Unlock(vb);
7305 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7306 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7307 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7308 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7309 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7310 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7311 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7312 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7313 ub_ok = SUCCEEDED(hr);
7316 if(dcl_short) {
7317 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7318 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7319 memcpy(data, quad3, sizeof(quad3));
7320 hr = IDirect3DVertexBuffer9_Unlock(vb);
7321 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7322 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7323 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7324 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7325 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7326 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7327 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7328 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7329 s_ok = SUCCEEDED(hr);
7332 if(dcl_float) {
7333 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7334 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7335 memcpy(data, quad4, sizeof(quad4));
7336 hr = IDirect3DVertexBuffer9_Unlock(vb);
7337 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7338 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7340 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7341 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7342 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7343 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7344 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7345 f_ok = SUCCEEDED(hr);
7348 hr = IDirect3DDevice9_EndScene(device);
7349 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7352 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7353 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7354 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7355 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7357 if(dcl_short) {
7358 color = getPixelColor(device, 480, 360);
7359 ok(color == 0x000000ff || !s_ok,
7360 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7362 if(dcl_ubyte) {
7363 color = getPixelColor(device, 160, 120);
7364 ok(color == 0x0000ffff || !ub_ok,
7365 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7367 if(dcl_color) {
7368 color = getPixelColor(device, 160, 360);
7369 ok(color == 0x00ffff00,
7370 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7372 if(dcl_float) {
7373 color = getPixelColor(device, 480, 120);
7374 ok(color == 0x00ff0000 || !f_ok,
7375 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7377 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7379 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7380 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7382 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7383 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7384 memcpy(data, quad_transformed, sizeof(quad_transformed));
7385 hr = IDirect3DVertexBuffer9_Unlock(vb);
7386 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7388 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7389 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7391 hr = IDirect3DDevice9_BeginScene(device);
7392 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7393 if(SUCCEEDED(hr)) {
7394 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7395 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7396 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7399 hr = IDirect3DDevice9_EndScene(device);
7400 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7403 color = getPixelColor(device, 88, 108);
7404 ok(color == 0x000000ff,
7405 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7406 color = getPixelColor(device, 92, 108);
7407 ok(color == 0x000000ff,
7408 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7409 color = getPixelColor(device, 88, 112);
7410 ok(color == 0x000000ff,
7411 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7412 color = getPixelColor(device, 92, 112);
7413 ok(color == 0x00ffff00,
7414 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7416 color = getPixelColor(device, 568, 108);
7417 ok(color == 0x000000ff,
7418 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7419 color = getPixelColor(device, 572, 108);
7420 ok(color == 0x000000ff,
7421 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7422 color = getPixelColor(device, 568, 112);
7423 ok(color == 0x00ffff00,
7424 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7425 color = getPixelColor(device, 572, 112);
7426 ok(color == 0x000000ff,
7427 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7429 color = getPixelColor(device, 88, 298);
7430 ok(color == 0x000000ff,
7431 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7432 color = getPixelColor(device, 92, 298);
7433 ok(color == 0x00ffff00,
7434 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7435 color = getPixelColor(device, 88, 302);
7436 ok(color == 0x000000ff,
7437 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7438 color = getPixelColor(device, 92, 302);
7439 ok(color == 0x000000ff,
7440 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7442 color = getPixelColor(device, 568, 298);
7443 ok(color == 0x00ffff00,
7444 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7445 color = getPixelColor(device, 572, 298);
7446 ok(color == 0x000000ff,
7447 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7448 color = getPixelColor(device, 568, 302);
7449 ok(color == 0x000000ff,
7450 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7451 color = getPixelColor(device, 572, 302);
7452 ok(color == 0x000000ff,
7453 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7455 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7457 /* This test is pointless without those two declarations: */
7458 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7459 skip("color-ubyte switching test declarations aren't supported\n");
7460 goto out;
7463 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7464 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7465 memcpy(data, quads, sizeof(quads));
7466 hr = IDirect3DVertexBuffer9_Unlock(vb);
7467 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7468 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7469 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7470 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7471 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7472 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7473 memcpy(data, colors, sizeof(colors));
7474 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7475 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7477 for(i = 0; i < 2; i++) {
7478 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7479 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7481 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7482 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7483 if(i == 0) {
7484 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7485 } else {
7486 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7490 hr = IDirect3DDevice9_BeginScene(device);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7492 ub_ok = FALSE;
7493 if(SUCCEEDED(hr)) {
7494 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7496 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7497 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7498 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7499 ub_ok = SUCCEEDED(hr);
7501 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7503 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7504 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7506 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7507 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7508 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7509 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7510 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7511 ub_ok = (SUCCEEDED(hr) && ub_ok);
7513 hr = IDirect3DDevice9_EndScene(device);
7514 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7517 if(i == 0) {
7518 color = getPixelColor(device, 480, 360);
7519 ok(color == 0x00ff0000,
7520 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7521 color = getPixelColor(device, 160, 120);
7522 ok(color == 0x00ffffff,
7523 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7524 color = getPixelColor(device, 160, 360);
7525 ok(color == 0x000000ff || !ub_ok,
7526 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7527 color = getPixelColor(device, 480, 120);
7528 ok(color == 0x000000ff || !ub_ok,
7529 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7530 } else {
7531 color = getPixelColor(device, 480, 360);
7532 ok(color == 0x000000ff,
7533 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7534 color = getPixelColor(device, 160, 120);
7535 ok(color == 0x00ffffff,
7536 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7537 color = getPixelColor(device, 160, 360);
7538 ok(color == 0x00ff0000 || !ub_ok,
7539 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7540 color = getPixelColor(device, 480, 120);
7541 ok(color == 0x00ff0000 || !ub_ok,
7542 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7544 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7547 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7548 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7549 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7550 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7551 IDirect3DVertexBuffer9_Release(vb2);
7553 out:
7554 IDirect3DVertexBuffer9_Release(vb);
7555 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7556 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7557 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7558 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7559 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7560 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7561 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7564 struct vertex_float16color {
7565 float x, y, z;
7566 DWORD c1, c2;
7569 static void test_vshader_float16(IDirect3DDevice9 *device)
7571 HRESULT hr;
7572 DWORD color;
7573 void *data;
7574 static const D3DVERTEXELEMENT9 decl_elements[] = {
7575 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7576 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7577 D3DDECL_END()
7579 IDirect3DVertexDeclaration9 *vdecl = NULL;
7580 IDirect3DVertexBuffer9 *buffer = NULL;
7581 IDirect3DVertexShader9 *shader;
7582 DWORD shader_code[] = {
7583 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7584 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7585 0x90e40001, 0x0000ffff
7587 struct vertex_float16color quad[] = {
7588 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7589 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7590 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7591 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7593 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7594 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7595 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7596 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7598 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7599 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7600 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7601 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7603 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7604 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7605 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7606 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7610 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7612 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7613 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7614 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7615 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7616 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7617 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7619 hr = IDirect3DDevice9_BeginScene(device);
7620 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7621 if(SUCCEEDED(hr)) {
7622 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7623 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7625 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7627 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7628 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7629 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7631 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7633 hr = IDirect3DDevice9_EndScene(device);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7636 color = getPixelColor(device, 480, 360);
7637 ok(color == 0x00ff0000,
7638 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7639 color = getPixelColor(device, 160, 120);
7640 ok(color == 0x00000000,
7641 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7642 color = getPixelColor(device, 160, 360);
7643 ok(color == 0x0000ff00,
7644 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7645 color = getPixelColor(device, 480, 120);
7646 ok(color == 0x000000ff,
7647 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7648 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7653 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7654 D3DPOOL_MANAGED, &buffer, NULL);
7655 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7656 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7657 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7658 memcpy(data, quad, sizeof(quad));
7659 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7660 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7661 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7662 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7664 hr = IDirect3DDevice9_BeginScene(device);
7665 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7666 if(SUCCEEDED(hr)) {
7667 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7669 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7670 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7671 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7672 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7673 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7676 hr = IDirect3DDevice9_EndScene(device);
7677 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7680 color = getPixelColor(device, 480, 360);
7681 ok(color == 0x00ff0000,
7682 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7683 color = getPixelColor(device, 160, 120);
7684 ok(color == 0x00000000,
7685 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7686 color = getPixelColor(device, 160, 360);
7687 ok(color == 0x0000ff00,
7688 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7689 color = getPixelColor(device, 480, 120);
7690 ok(color == 0x000000ff,
7691 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7692 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7694 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7695 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7696 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7697 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7698 IDirect3DDevice9_SetVertexShader(device, NULL);
7699 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7701 IDirect3DVertexDeclaration9_Release(vdecl);
7702 IDirect3DVertexShader9_Release(shader);
7703 IDirect3DVertexBuffer9_Release(buffer);
7706 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7708 D3DCAPS9 caps;
7709 IDirect3DTexture9 *texture;
7710 HRESULT hr;
7711 D3DLOCKED_RECT rect;
7712 unsigned int x, y;
7713 DWORD *dst, color;
7714 const float quad[] = {
7715 -1.0, -1.0, 0.1, -0.2, -0.2,
7716 1.0, -1.0, 0.1, 1.2, -0.2,
7717 -1.0, 1.0, 0.1, -0.2, 1.2,
7718 1.0, 1.0, 0.1, 1.2, 1.2
7720 memset(&caps, 0, sizeof(caps));
7722 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7723 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7724 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7725 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7726 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7727 "Card has conditional NP2 support without power of two restriction set\n");
7728 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7729 return;
7730 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7731 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7732 return;
7735 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7736 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7738 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7739 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7741 memset(&rect, 0, sizeof(rect));
7742 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7743 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7744 for(y = 0; y < 10; y++) {
7745 for(x = 0; x < 10; x++) {
7746 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7747 if(x == 0 || x == 9 || y == 0 || y == 9) {
7748 *dst = 0x00ff0000;
7749 } else {
7750 *dst = 0x000000ff;
7754 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7755 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7757 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7758 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7759 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7760 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7761 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7762 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7763 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7764 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7766 hr = IDirect3DDevice9_BeginScene(device);
7767 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7768 if(SUCCEEDED(hr)) {
7769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7770 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7772 hr = IDirect3DDevice9_EndScene(device);
7773 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7776 color = getPixelColor(device, 1, 1);
7777 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7778 color = getPixelColor(device, 639, 479);
7779 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7781 color = getPixelColor(device, 135, 101);
7782 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7783 color = getPixelColor(device, 140, 101);
7784 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7785 color = getPixelColor(device, 135, 105);
7786 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7787 color = getPixelColor(device, 140, 105);
7788 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7790 color = getPixelColor(device, 135, 376);
7791 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7792 color = getPixelColor(device, 140, 376);
7793 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7794 color = getPixelColor(device, 135, 379);
7795 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7796 color = getPixelColor(device, 140, 379);
7797 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7799 color = getPixelColor(device, 500, 101);
7800 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7801 color = getPixelColor(device, 504, 101);
7802 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7803 color = getPixelColor(device, 500, 105);
7804 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7805 color = getPixelColor(device, 504, 105);
7806 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7808 color = getPixelColor(device, 500, 376);
7809 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7810 color = getPixelColor(device, 504, 376);
7811 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7812 color = getPixelColor(device, 500, 380);
7813 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7814 color = getPixelColor(device, 504, 380);
7815 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7817 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7819 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7820 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7821 IDirect3DTexture9_Release(texture);
7824 static void vFace_register_test(IDirect3DDevice9 *device)
7826 HRESULT hr;
7827 DWORD color;
7828 const DWORD shader_code[] = {
7829 0xffff0300, /* ps_3_0 */
7830 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7831 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7832 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7833 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7834 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7835 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7836 0x0000ffff /* END */
7838 IDirect3DPixelShader9 *shader;
7839 IDirect3DTexture9 *texture;
7840 IDirect3DSurface9 *surface, *backbuffer;
7841 const float quad[] = {
7842 -1.0, -1.0, 0.1,
7843 1.0, -1.0, 0.1,
7844 -1.0, 0.0, 0.1,
7846 1.0, -1.0, 0.1,
7847 1.0, 0.0, 0.1,
7848 -1.0, 0.0, 0.1,
7850 -1.0, 0.0, 0.1,
7851 -1.0, 1.0, 0.1,
7852 1.0, 0.0, 0.1,
7854 1.0, 0.0, 0.1,
7855 -1.0, 1.0, 0.1,
7856 1.0, 1.0, 0.1,
7858 const float blit[] = {
7859 0.0, -1.0, 0.1, 0.0, 0.0,
7860 1.0, -1.0, 0.1, 1.0, 0.0,
7861 0.0, 1.0, 0.1, 0.0, 1.0,
7862 1.0, 1.0, 0.1, 1.0, 1.0,
7865 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7866 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7867 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7868 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7869 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7870 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7871 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7872 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7874 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7875 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7876 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7878 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7881 hr = IDirect3DDevice9_BeginScene(device);
7882 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7883 if(SUCCEEDED(hr)) {
7884 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7885 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7888 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7890 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7891 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7893 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7896 /* Blit the texture onto the back buffer to make it visible */
7897 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7898 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7899 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7901 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7902 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7903 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7904 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7905 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7906 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7908 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7909 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7911 hr = IDirect3DDevice9_EndScene(device);
7912 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7915 color = getPixelColor(device, 160, 360);
7916 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7917 color = getPixelColor(device, 160, 120);
7918 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7919 color = getPixelColor(device, 480, 360);
7920 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7921 color = getPixelColor(device, 480, 120);
7922 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7923 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7925 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7926 IDirect3DDevice9_SetTexture(device, 0, NULL);
7927 IDirect3DPixelShader9_Release(shader);
7928 IDirect3DSurface9_Release(surface);
7929 IDirect3DSurface9_Release(backbuffer);
7930 IDirect3DTexture9_Release(texture);
7933 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7935 HRESULT hr;
7936 DWORD color;
7937 int i;
7938 D3DCAPS9 caps;
7939 BOOL L6V5U5_supported = FALSE;
7940 IDirect3DTexture9 *tex1, *tex2;
7941 D3DLOCKED_RECT locked_rect;
7943 static const float quad[][7] = {
7944 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7945 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7946 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7947 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7950 static const D3DVERTEXELEMENT9 decl_elements[] = {
7951 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7952 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7953 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7954 D3DDECL_END()
7957 /* use asymmetric matrix to test loading */
7958 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7959 float scale, offset;
7961 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7962 IDirect3DTexture9 *texture = NULL;
7964 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.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7968 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7969 return;
7970 } else {
7971 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7972 * They report that it is not supported, but after that bump mapping works properly. So just test
7973 * if the format is generally supported, and check the BUMPENVMAP flag
7975 IDirect3D9 *d3d9;
7977 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7978 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7979 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7980 L6V5U5_supported = SUCCEEDED(hr);
7981 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7982 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7983 IDirect3D9_Release(d3d9);
7984 if(FAILED(hr)) {
7985 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7986 return;
7990 /* Generate the textures */
7991 generate_bumpmap_textures(device);
7993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7994 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7996 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7997 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7998 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7999 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8000 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8002 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8003 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8004 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8005 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8006 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8007 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8009 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8010 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8011 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8012 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8013 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8014 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8016 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8017 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8019 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8020 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8022 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8023 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8026 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8027 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8028 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8029 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8031 hr = IDirect3DDevice9_BeginScene(device);
8032 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8035 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8037 hr = IDirect3DDevice9_EndScene(device);
8038 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8040 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8041 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8042 * But since testing the color match is not the purpose of the test don't be too picky
8044 color = getPixelColor(device, 320-32, 240);
8045 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8046 color = getPixelColor(device, 320+32, 240);
8047 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8048 color = getPixelColor(device, 320, 240-32);
8049 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8050 color = getPixelColor(device, 320, 240+32);
8051 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8052 color = getPixelColor(device, 320, 240);
8053 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8054 color = getPixelColor(device, 320+32, 240+32);
8055 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8056 color = getPixelColor(device, 320-32, 240+32);
8057 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8058 color = getPixelColor(device, 320+32, 240-32);
8059 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8060 color = getPixelColor(device, 320-32, 240-32);
8061 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8062 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8063 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8065 for(i = 0; i < 2; i++) {
8066 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8067 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8068 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8069 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8070 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8071 IDirect3DTexture9_Release(texture); /* To destroy it */
8074 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8075 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8076 goto cleanup;
8078 if(L6V5U5_supported == FALSE) {
8079 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8080 goto cleanup;
8083 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8084 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8085 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8086 * would only make this test more complicated
8088 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8089 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8090 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8091 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8093 memset(&locked_rect, 0, sizeof(locked_rect));
8094 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8095 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8096 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8097 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8098 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8100 memset(&locked_rect, 0, sizeof(locked_rect));
8101 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8102 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8103 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8104 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8105 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8107 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8108 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8109 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8110 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8112 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8113 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8114 scale = 2.0;
8115 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8116 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8117 offset = 0.1;
8118 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8119 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8121 hr = IDirect3DDevice9_BeginScene(device);
8122 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8123 if(SUCCEEDED(hr)) {
8124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8125 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8126 hr = IDirect3DDevice9_EndScene(device);
8127 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8130 color = getPixelColor(device, 320, 240);
8131 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8132 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8133 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8135 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8136 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8137 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8139 /* Check a result scale factor > 1.0 */
8140 scale = 10;
8141 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8142 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8143 offset = 10;
8144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8145 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8147 hr = IDirect3DDevice9_BeginScene(device);
8148 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8149 if(SUCCEEDED(hr)) {
8150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8151 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8152 hr = IDirect3DDevice9_EndScene(device);
8153 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8155 color = getPixelColor(device, 320, 240);
8156 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8157 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8158 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8160 /* Check clamping in the scale factor calculation */
8161 scale = 1000;
8162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8163 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8164 offset = -1;
8165 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8166 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8168 hr = IDirect3DDevice9_BeginScene(device);
8169 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8170 if(SUCCEEDED(hr)) {
8171 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8172 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8173 hr = IDirect3DDevice9_EndScene(device);
8174 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8176 color = getPixelColor(device, 320, 240);
8177 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8178 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8179 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8181 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8182 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8183 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8184 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8186 IDirect3DTexture9_Release(tex1);
8187 IDirect3DTexture9_Release(tex2);
8189 cleanup:
8190 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8191 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8192 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8193 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8195 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8196 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8197 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8200 static void stencil_cull_test(IDirect3DDevice9 *device) {
8201 HRESULT hr;
8202 IDirect3DSurface9 *depthstencil = NULL;
8203 D3DSURFACE_DESC desc;
8204 float quad1[] = {
8205 -1.0, -1.0, 0.1,
8206 0.0, -1.0, 0.1,
8207 -1.0, 0.0, 0.1,
8208 0.0, 0.0, 0.1,
8210 float quad2[] = {
8211 0.0, -1.0, 0.1,
8212 1.0, -1.0, 0.1,
8213 0.0, 0.0, 0.1,
8214 1.0, 0.0, 0.1,
8216 float quad3[] = {
8217 0.0, 0.0, 0.1,
8218 1.0, 0.0, 0.1,
8219 0.0, 1.0, 0.1,
8220 1.0, 1.0, 0.1,
8222 float quad4[] = {
8223 -1.0, 0.0, 0.1,
8224 0.0, 0.0, 0.1,
8225 -1.0, 1.0, 0.1,
8226 0.0, 1.0, 0.1,
8228 struct vertex painter[] = {
8229 {-1.0, -1.0, 0.0, 0x00000000},
8230 { 1.0, -1.0, 0.0, 0x00000000},
8231 {-1.0, 1.0, 0.0, 0x00000000},
8232 { 1.0, 1.0, 0.0, 0x00000000},
8234 WORD indices_cw[] = {0, 1, 3};
8235 WORD indices_ccw[] = {0, 2, 3};
8236 unsigned int i;
8237 DWORD color;
8239 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8240 if(depthstencil == NULL) {
8241 skip("No depth stencil buffer\n");
8242 return;
8244 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8245 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8246 IDirect3DSurface9_Release(depthstencil);
8247 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8248 skip("No 4 or 8 bit stencil surface\n");
8249 return;
8252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8253 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8254 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8257 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8258 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8259 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8266 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8267 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8268 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8277 /* First pass: Fill the stencil buffer with some values... */
8278 hr = IDirect3DDevice9_BeginScene(device);
8279 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8280 if(SUCCEEDED(hr))
8282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8284 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8285 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8286 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8287 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8288 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8289 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8295 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8296 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8297 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8298 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8299 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8300 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8304 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8305 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8306 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8307 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8308 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8309 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8312 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8313 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8314 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8315 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8317 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8318 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8320 hr = IDirect3DDevice9_EndScene(device);
8321 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8324 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8326 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8328 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8332 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8336 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8338 /* 2nd pass: Make the stencil values visible */
8339 hr = IDirect3DDevice9_BeginScene(device);
8340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8341 if(SUCCEEDED(hr))
8343 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8344 for(i = 0; i < 16; i++) {
8345 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8346 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8348 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8349 painter[1].diffuse = (i * 16);
8350 painter[2].diffuse = (i * 16);
8351 painter[3].diffuse = (i * 16);
8352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8353 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8355 hr = IDirect3DDevice9_EndScene(device);
8356 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8360 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8362 color = getPixelColor(device, 160, 420);
8363 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8364 color = getPixelColor(device, 160, 300);
8365 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8367 color = getPixelColor(device, 480, 420);
8368 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8369 color = getPixelColor(device, 480, 300);
8370 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8372 color = getPixelColor(device, 160, 180);
8373 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8374 color = getPixelColor(device, 160, 60);
8375 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8377 color = getPixelColor(device, 480, 180);
8378 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8379 color = getPixelColor(device, 480, 60);
8380 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8382 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8383 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8386 static void vpos_register_test(IDirect3DDevice9 *device)
8388 HRESULT hr;
8389 DWORD color;
8390 const DWORD shader_code[] = {
8391 0xffff0300, /* ps_3_0 */
8392 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8393 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8394 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8395 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8396 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8397 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8398 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8399 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8400 0x0000ffff /* end */
8402 const DWORD shader_frac_code[] = {
8403 0xffff0300, /* ps_3_0 */
8404 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8405 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8406 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8407 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8408 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8409 0x0000ffff /* end */
8411 IDirect3DPixelShader9 *shader, *shader_frac;
8412 IDirect3DSurface9 *surface = NULL, *backbuffer;
8413 const float quad[] = {
8414 -1.0, -1.0, 0.1, 0.0, 0.0,
8415 1.0, -1.0, 0.1, 1.0, 0.0,
8416 -1.0, 1.0, 0.1, 0.0, 1.0,
8417 1.0, 1.0, 0.1, 1.0, 1.0,
8419 D3DLOCKED_RECT lr;
8420 float constant[4] = {1.0, 0.0, 320, 240};
8421 DWORD *pos;
8423 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8424 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8425 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8426 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8427 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8428 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8429 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8430 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8431 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8432 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8433 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8434 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8436 hr = IDirect3DDevice9_BeginScene(device);
8437 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8438 if(SUCCEEDED(hr)) {
8439 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8440 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8442 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8443 hr = IDirect3DDevice9_EndScene(device);
8444 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8447 /* This has to be pixel exact */
8448 color = getPixelColor(device, 319, 239);
8449 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8450 color = getPixelColor(device, 320, 239);
8451 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8452 color = getPixelColor(device, 319, 240);
8453 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8454 color = getPixelColor(device, 320, 240);
8455 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8456 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8458 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8459 &surface, NULL);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8461 hr = IDirect3DDevice9_BeginScene(device);
8462 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8463 if(SUCCEEDED(hr)) {
8464 constant[2] = 16; constant[3] = 16;
8465 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8466 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8467 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8468 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8470 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8471 hr = IDirect3DDevice9_EndScene(device);
8472 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8474 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8475 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8477 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8478 color = *pos & 0x00ffffff;
8479 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8480 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8481 color = *pos & 0x00ffffff;
8482 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8483 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8484 color = *pos & 0x00ffffff;
8485 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8486 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8487 color = *pos & 0x00ffffff;
8488 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8490 hr = IDirect3DSurface9_UnlockRect(surface);
8491 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8493 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8494 * have full control over the multisampling setting inside this test
8496 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8497 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8498 hr = IDirect3DDevice9_BeginScene(device);
8499 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8500 if(SUCCEEDED(hr)) {
8501 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8504 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8505 hr = IDirect3DDevice9_EndScene(device);
8506 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8508 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8509 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8511 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8512 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8514 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8515 color = *pos & 0x00ffffff;
8516 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8518 hr = IDirect3DSurface9_UnlockRect(surface);
8519 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8521 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8522 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8523 IDirect3DPixelShader9_Release(shader);
8524 IDirect3DPixelShader9_Release(shader_frac);
8525 if(surface) IDirect3DSurface9_Release(surface);
8526 IDirect3DSurface9_Release(backbuffer);
8529 static void pointsize_test(IDirect3DDevice9 *device)
8531 HRESULT hr;
8532 D3DCAPS9 caps;
8533 D3DMATRIX matrix;
8534 D3DMATRIX identity;
8535 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8536 DWORD color;
8537 IDirect3DTexture9 *tex1, *tex2;
8538 D3DLOCKED_RECT lr;
8539 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8540 0x00000000, 0x00000000};
8541 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8542 0x00000000, 0x0000ff00};
8544 const float vertices[] = {
8545 64, 64, 0.1,
8546 128, 64, 0.1,
8547 192, 64, 0.1,
8548 256, 64, 0.1,
8549 320, 64, 0.1,
8550 384, 64, 0.1,
8551 448, 64, 0.1,
8552 512, 64, 0.1,
8553 576, 64, 0.1,
8556 /* 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 */
8557 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;
8558 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;
8559 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;
8560 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;
8562 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;
8563 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;
8564 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;
8565 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;
8567 memset(&caps, 0, sizeof(caps));
8568 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8569 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8570 if(caps.MaxPointSize < 32.0) {
8571 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8572 return;
8575 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8576 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8577 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8578 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8579 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8580 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8581 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8582 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8584 hr = IDirect3DDevice9_BeginScene(device);
8585 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8586 if(SUCCEEDED(hr)) {
8587 ptsize = 16.0;
8588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8589 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8590 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8591 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8593 ptsize = 32.0;
8594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8595 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8597 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8599 ptsize = 31.5;
8600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8601 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8603 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8605 if(caps.MaxPointSize >= 64.0) {
8606 ptsize = 64.0;
8607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8608 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8610 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8612 ptsize = 63.75;
8613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8614 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8615 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8616 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8619 ptsize = 1.0;
8620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8621 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8623 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8625 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8626 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8627 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8628 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8630 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8631 ptsize = 16.0;
8632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8633 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8634 ptsize = 1.0;
8635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8636 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8638 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8640 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8641 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8643 ptsize = 4.0;
8644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8646 ptsize = 16.0;
8647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8650 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8653 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8655 /* pointsize < pointsize_min < pointsize_max?
8656 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8658 ptsize = 1.0;
8659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8660 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8661 ptsize = 16.0;
8662 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8663 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8665 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8670 hr = IDirect3DDevice9_EndScene(device);
8671 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8673 color = getPixelColor(device, 64-9, 64-9);
8674 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8675 color = getPixelColor(device, 64-8, 64-8);
8676 ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8677 color = getPixelColor(device, 64-7, 64-7);
8678 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8679 color = getPixelColor(device, 64+7, 64+7);
8680 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8681 color = getPixelColor(device, 64+8, 64+8);
8682 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8683 color = getPixelColor(device, 64+9, 64+9);
8684 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8686 color = getPixelColor(device, 128-17, 64-17);
8687 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8688 color = getPixelColor(device, 128-16, 64-16);
8689 ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8690 color = getPixelColor(device, 128-15, 64-15);
8691 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8692 color = getPixelColor(device, 128+15, 64+15);
8693 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8694 color = getPixelColor(device, 128+16, 64+16);
8695 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8696 color = getPixelColor(device, 128+17, 64+17);
8697 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8699 color = getPixelColor(device, 192-17, 64-17);
8700 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8701 color = getPixelColor(device, 192-16, 64-16);
8702 todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8703 color = getPixelColor(device, 192-15, 64-15);
8704 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8705 color = getPixelColor(device, 192+15, 64+15);
8706 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8707 color = getPixelColor(device, 192+16, 64+16);
8708 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8709 color = getPixelColor(device, 192+17, 64+17);
8710 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8712 if(caps.MaxPointSize >= 64.0) {
8713 color = getPixelColor(device, 256-33, 64-33);
8714 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8715 color = getPixelColor(device, 256-32, 64-32);
8716 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8717 color = getPixelColor(device, 256-31, 64-31);
8718 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8719 color = getPixelColor(device, 256+31, 64+31);
8720 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8721 color = getPixelColor(device, 256+32, 64+32);
8722 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8723 color = getPixelColor(device, 256+33, 64+33);
8724 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8726 color = getPixelColor(device, 384-33, 64-33);
8727 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8728 color = getPixelColor(device, 384-32, 64-32);
8729 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8730 color = getPixelColor(device, 384-31, 64-31);
8731 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8732 color = getPixelColor(device, 384+31, 64+31);
8733 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8734 color = getPixelColor(device, 384+32, 64+32);
8735 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8736 color = getPixelColor(device, 384+33, 64+33);
8737 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8740 color = getPixelColor(device, 320-1, 64-1);
8741 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8742 color = getPixelColor(device, 320-0, 64-0);
8743 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8744 color = getPixelColor(device, 320+1, 64+1);
8745 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8747 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8748 color = getPixelColor(device, 448-4, 64-4);
8749 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8750 color = getPixelColor(device, 448+4, 64+4);
8751 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8753 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8754 color = getPixelColor(device, 512-4, 64-4);
8755 ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8756 color = getPixelColor(device, 512+4, 64+4);
8757 ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8759 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8760 * Don't be overly picky - just show that the point is bigger than 1 pixel
8762 color = getPixelColor(device, 576-4, 64-4);
8763 ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8764 color = getPixelColor(device, 576+4, 64+4);
8765 ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8767 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8769 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8770 * generates texture coordinates for the point(result: Yes, it does)
8772 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8773 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8774 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8777 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8779 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8780 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8781 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8782 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8783 memset(&lr, 0, sizeof(lr));
8784 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8785 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8786 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8787 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8788 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8789 memset(&lr, 0, sizeof(lr));
8790 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8791 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8792 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8793 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8794 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8795 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8796 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8797 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8798 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8800 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8802 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8803 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8804 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8805 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8806 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8807 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8808 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8811 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8812 ptsize = 32.0;
8813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8814 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8816 hr = IDirect3DDevice9_BeginScene(device);
8817 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8818 if(SUCCEEDED(hr))
8820 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8821 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8822 hr = IDirect3DDevice9_EndScene(device);
8823 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8826 color = getPixelColor(device, 64-4, 64-4);
8827 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8828 color = getPixelColor(device, 64-4, 64+4);
8829 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8830 color = getPixelColor(device, 64+4, 64+4);
8831 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8832 color = getPixelColor(device, 64+4, 64-4);
8833 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8834 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8837 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8838 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8839 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8840 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8841 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8842 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8843 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8844 IDirect3DTexture9_Release(tex1);
8845 IDirect3DTexture9_Release(tex2);
8847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8851 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8852 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8855 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8857 HRESULT hr;
8858 IDirect3DPixelShader9 *ps;
8859 IDirect3DTexture9 *tex1, *tex2;
8860 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8861 D3DCAPS9 caps;
8862 DWORD color;
8863 DWORD shader_code[] = {
8864 0xffff0300, /* ps_3_0 */
8865 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8866 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8867 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8868 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8869 0x0000ffff /* END */
8871 float quad[] = {
8872 -1.0, -1.0, 0.1,
8873 1.0, -1.0, 0.1,
8874 -1.0, 1.0, 0.1,
8875 1.0, 1.0, 0.1,
8877 float texquad[] = {
8878 -1.0, -1.0, 0.1, 0.0, 0.0,
8879 0.0, -1.0, 0.1, 1.0, 0.0,
8880 -1.0, 1.0, 0.1, 0.0, 1.0,
8881 0.0, 1.0, 0.1, 1.0, 1.0,
8883 0.0, -1.0, 0.1, 0.0, 0.0,
8884 1.0, -1.0, 0.1, 1.0, 0.0,
8885 0.0, 1.0, 0.1, 0.0, 1.0,
8886 1.0, 1.0, 0.1, 1.0, 1.0,
8889 memset(&caps, 0, sizeof(caps));
8890 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8891 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8892 if(caps.NumSimultaneousRTs < 2) {
8893 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8894 return;
8897 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8898 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8900 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8901 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8902 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8903 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8904 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8905 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8907 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8908 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8909 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8910 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8911 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8912 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8914 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8915 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8916 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8918 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8919 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8921 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8923 hr = IDirect3DDevice9_BeginScene(device);
8924 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8925 if(SUCCEEDED(hr)) {
8926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8927 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8929 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8930 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8931 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8932 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8933 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8934 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8935 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8936 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8938 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8939 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8941 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8943 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8944 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8946 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8948 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8951 hr = IDirect3DDevice9_EndScene(device);
8952 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8955 color = getPixelColor(device, 160, 240);
8956 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8957 color = getPixelColor(device, 480, 240);
8958 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8959 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8961 IDirect3DPixelShader9_Release(ps);
8962 IDirect3DTexture9_Release(tex1);
8963 IDirect3DTexture9_Release(tex2);
8964 IDirect3DSurface9_Release(surf1);
8965 IDirect3DSurface9_Release(surf2);
8966 IDirect3DSurface9_Release(backbuf);
8969 struct formats {
8970 const char *fmtName;
8971 D3DFORMAT textureFormat;
8972 DWORD resultColorBlending;
8973 DWORD resultColorNoBlending;
8976 const struct formats test_formats[] = {
8977 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8978 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8979 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8980 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8981 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8982 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8983 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8984 { NULL, 0 }
8987 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8989 HRESULT hr;
8990 IDirect3DTexture9 *offscreenTexture = NULL;
8991 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8992 IDirect3D9 *d3d = NULL;
8993 DWORD color;
8994 DWORD r0, g0, b0, r1, g1, b1;
8995 int fmt_index;
8997 static const float quad[][5] = {
8998 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8999 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9000 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9001 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9004 /* Quad with R=0x10, G=0x20 */
9005 static const struct vertex quad1[] = {
9006 {-1.0f, -1.0f, 0.1f, 0x80102000},
9007 {-1.0f, 1.0f, 0.1f, 0x80102000},
9008 { 1.0f, -1.0f, 0.1f, 0x80102000},
9009 { 1.0f, 1.0f, 0.1f, 0x80102000},
9012 /* Quad with R=0x20, G=0x10 */
9013 static const struct vertex quad2[] = {
9014 {-1.0f, -1.0f, 0.1f, 0x80201000},
9015 {-1.0f, 1.0f, 0.1f, 0x80201000},
9016 { 1.0f, -1.0f, 0.1f, 0x80201000},
9017 { 1.0f, 1.0f, 0.1f, 0x80201000},
9020 IDirect3DDevice9_GetDirect3D(device, &d3d);
9022 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9023 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9024 if(!backbuffer) {
9025 goto out;
9028 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9030 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9031 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9032 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9033 continue;
9036 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9037 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9039 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9040 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9041 if(!offscreenTexture) {
9042 continue;
9045 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9046 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9047 if(!offscreen) {
9048 continue;
9051 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9052 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9054 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9055 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9057 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9058 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9059 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9060 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9061 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9063 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9065 /* Below we will draw two quads with different colors and try to blend them together.
9066 * The result color is compared with the expected outcome.
9068 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9069 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9070 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9071 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9072 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9077 /* Draw a quad using color 0x0010200 */
9078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9079 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9081 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9083 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9085 /* Draw a quad using color 0x0020100 */
9086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9089 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9091 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9093 /* We don't want to blend the result on the backbuffer */
9094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9097 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9098 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9099 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9100 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9101 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9103 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9104 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9106 /* This time with the texture */
9107 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9108 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9110 IDirect3DDevice9_EndScene(device);
9113 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9114 /* Compare the color of the center quad with our expectation */
9115 color = getPixelColor(device, 320, 240);
9116 r0 = (color & 0x00ff0000) >> 16;
9117 g0 = (color & 0x0000ff00) >> 8;
9118 b0 = (color & 0x000000ff) >> 0;
9120 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9121 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9122 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9124 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9125 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9126 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9127 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9128 } else {
9129 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9130 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9131 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9132 color = getPixelColor(device, 320, 240);
9133 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);
9135 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9137 IDirect3DDevice9_SetTexture(device, 0, NULL);
9138 if(offscreenTexture) {
9139 IDirect3DTexture9_Release(offscreenTexture);
9141 if(offscreen) {
9142 IDirect3DSurface9_Release(offscreen);
9146 out:
9147 /* restore things */
9148 if(backbuffer) {
9149 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9150 IDirect3DSurface9_Release(backbuffer);
9154 static void tssargtemp_test(IDirect3DDevice9 *device)
9156 HRESULT hr;
9157 DWORD color;
9158 static const struct vertex quad[] = {
9159 {-1.0, -1.0, 0.1, 0x00ff0000},
9160 { 1.0, -1.0, 0.1, 0x00ff0000},
9161 {-1.0, 1.0, 0.1, 0x00ff0000},
9162 { 1.0, 1.0, 0.1, 0x00ff0000}
9164 D3DCAPS9 caps;
9166 memset(&caps, 0, sizeof(caps));
9167 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9168 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9169 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9170 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9171 return;
9174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9175 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9178 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9179 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9180 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9182 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9183 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9184 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9185 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9186 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9187 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9189 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9190 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9191 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9192 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9193 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9194 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9196 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9197 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9200 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9201 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9202 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9204 hr = IDirect3DDevice9_BeginScene(device);
9205 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9206 if(SUCCEEDED(hr)) {
9207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9208 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9209 hr = IDirect3DDevice9_EndScene(device);
9210 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9212 color = getPixelColor(device, 320, 240);
9213 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9214 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9216 /* Set stage 1 back to default */
9217 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9218 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9219 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9220 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9221 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9222 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9223 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9224 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9225 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9226 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9229 struct testdata
9231 DWORD idxVertex; /* number of instances in the first stream */
9232 DWORD idxColor; /* number of instances in the second stream */
9233 DWORD idxInstance; /* should be 1 ?? */
9234 DWORD color1; /* color 1 instance */
9235 DWORD color2; /* color 2 instance */
9236 DWORD color3; /* color 3 instance */
9237 DWORD color4; /* color 4 instance */
9238 WORD strVertex; /* specify which stream to use 0-2*/
9239 WORD strColor;
9240 WORD strInstance;
9243 static const struct testdata testcases[]=
9245 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9246 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9247 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9248 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9249 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9250 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9251 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9252 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9253 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9254 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9255 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9256 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9257 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9258 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9259 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9261 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9262 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9266 /* Drawing Indexed Geometry with instances*/
9267 static void stream_test(IDirect3DDevice9 *device)
9269 IDirect3DVertexBuffer9 *vb = NULL;
9270 IDirect3DVertexBuffer9 *vb2 = NULL;
9271 IDirect3DVertexBuffer9 *vb3 = NULL;
9272 IDirect3DIndexBuffer9 *ib = NULL;
9273 IDirect3DVertexDeclaration9 *pDecl = NULL;
9274 IDirect3DVertexShader9 *shader = NULL;
9275 HRESULT hr;
9276 BYTE *data;
9277 DWORD color;
9278 DWORD ind;
9279 unsigned i;
9281 const DWORD shader_code[] =
9283 0xfffe0101, /* vs_1_1 */
9284 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9285 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9286 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9287 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9288 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9289 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9290 0x0000ffff
9293 const float quad[][3] =
9295 {-0.5f, -0.5f, 1.1f}, /*0 */
9296 {-0.5f, 0.5f, 1.1f}, /*1 */
9297 { 0.5f, -0.5f, 1.1f}, /*2 */
9298 { 0.5f, 0.5f, 1.1f}, /*3 */
9301 const float vertcolor[][4] =
9303 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9304 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9305 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9306 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9309 /* 4 position for 4 instances */
9310 const float instancepos[][3] =
9312 {-0.6f,-0.6f, 0.0f},
9313 { 0.6f,-0.6f, 0.0f},
9314 { 0.6f, 0.6f, 0.0f},
9315 {-0.6f, 0.6f, 0.0f},
9318 short indices[] = {0, 1, 2, 1, 2, 3};
9320 D3DVERTEXELEMENT9 decl[] =
9322 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9323 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9324 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9325 D3DDECL_END()
9328 /* set the default value because it isn't done in wine? */
9329 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9330 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9332 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9333 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9334 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9336 /* check wrong cases */
9337 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9338 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9339 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9340 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9341 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9342 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9343 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9344 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9345 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9346 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9347 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9348 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9349 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9350 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9351 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9352 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9353 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9354 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9355 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9356 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9358 /* set the default value back */
9359 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9360 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9362 /* create all VertexBuffers*/
9363 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9364 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9365 if(!vb) {
9366 skip("Failed to create a vertex buffer\n");
9367 return;
9369 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9370 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9371 if(!vb2) {
9372 skip("Failed to create a vertex buffer\n");
9373 goto out;
9375 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9376 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9377 if(!vb3) {
9378 skip("Failed to create a vertex buffer\n");
9379 goto out;
9382 /* create IndexBuffer*/
9383 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9385 if(!ib) {
9386 skip("Failed to create a index buffer\n");
9387 goto out;
9390 /* copy all Buffers (Vertex + Index)*/
9391 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9392 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9393 memcpy(data, quad, sizeof(quad));
9394 hr = IDirect3DVertexBuffer9_Unlock(vb);
9395 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9396 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9397 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9398 memcpy(data, vertcolor, sizeof(vertcolor));
9399 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9400 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9401 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9402 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9403 memcpy(data, instancepos, sizeof(instancepos));
9404 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9405 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9406 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9407 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9408 memcpy(data, indices, sizeof(indices));
9409 hr = IDirect3DIndexBuffer9_Unlock(ib);
9410 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9412 /* create VertexShader */
9413 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9414 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9415 if(!shader) {
9416 skip("Failed to create a vetex shader\n");
9417 goto out;
9420 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9421 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9423 hr = IDirect3DDevice9_SetIndices(device, ib);
9424 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9426 /* run all tests */
9427 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9429 struct testdata act = testcases[i];
9430 decl[0].Stream = act.strVertex;
9431 decl[1].Stream = act.strColor;
9432 decl[2].Stream = act.strInstance;
9433 /* create VertexDeclarations */
9434 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9435 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9438 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9440 hr = IDirect3DDevice9_BeginScene(device);
9441 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9442 if(SUCCEEDED(hr))
9444 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9445 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9447 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9448 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9449 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9450 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9452 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9453 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9454 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9455 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9457 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9458 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9459 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9460 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9462 /* don't know if this is right (1*3 and 4*1)*/
9463 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9465 hr = IDirect3DDevice9_EndScene(device);
9466 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9468 /* set all StreamSource && StreamSourceFreq back to default */
9469 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9470 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9471 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9472 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9473 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9474 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9475 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9476 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9477 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9478 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9479 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9480 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9483 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9484 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9486 color = getPixelColor(device, 160, 360);
9487 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9488 color = getPixelColor(device, 480, 360);
9489 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9490 color = getPixelColor(device, 480, 120);
9491 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9492 color = getPixelColor(device, 160, 120);
9493 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9496 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9499 hr = IDirect3DDevice9_SetIndices(device, NULL);
9500 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9502 out:
9503 if(vb) IDirect3DVertexBuffer9_Release(vb);
9504 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9505 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9506 if(ib)IDirect3DIndexBuffer9_Release(ib);
9507 if(shader)IDirect3DVertexShader9_Release(shader);
9510 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9511 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9512 IDirect3DTexture9 *dsttex = NULL;
9513 HRESULT hr;
9514 DWORD color;
9515 D3DRECT r1 = {0, 0, 50, 50 };
9516 D3DRECT r2 = {50, 0, 100, 50 };
9517 D3DRECT r3 = {50, 50, 100, 100};
9518 D3DRECT r4 = {0, 50, 50, 100};
9519 const float quad[] = {
9520 -1.0, -1.0, 0.1, 0.0, 0.0,
9521 1.0, -1.0, 0.1, 1.0, 0.0,
9522 -1.0, 1.0, 0.1, 0.0, 1.0,
9523 1.0, 1.0, 0.1, 1.0, 1.0,
9526 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9527 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9529 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9530 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9531 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9532 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9534 if(!src || !dsttex) {
9535 skip("One or more test resources could not be created\n");
9536 goto cleanup;
9539 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9540 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9542 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9543 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9545 /* Clear the StretchRect destination for debugging */
9546 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9548 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9549 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9551 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9552 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9554 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9556 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9557 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9558 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9559 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9560 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9561 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9563 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9564 * the target -> texture GL blit path
9566 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9567 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9568 IDirect3DSurface9_Release(dst);
9570 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9573 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9574 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9576 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9577 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9578 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9579 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9580 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9582 hr = IDirect3DDevice9_BeginScene(device);
9583 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9584 if(SUCCEEDED(hr)) {
9585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9586 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9587 hr = IDirect3DDevice9_EndScene(device);
9588 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9591 color = getPixelColor(device, 160, 360);
9592 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9593 color = getPixelColor(device, 480, 360);
9594 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9595 color = getPixelColor(device, 480, 120);
9596 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9597 color = getPixelColor(device, 160, 120);
9598 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9600 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9602 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9603 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9604 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9605 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9607 cleanup:
9608 if(src) IDirect3DSurface9_Release(src);
9609 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9610 if(dsttex) IDirect3DTexture9_Release(dsttex);
9613 static void texop_test(IDirect3DDevice9 *device)
9615 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9616 IDirect3DTexture9 *texture = NULL;
9617 D3DLOCKED_RECT locked_rect;
9618 D3DCOLOR color;
9619 D3DCAPS9 caps;
9620 HRESULT hr;
9621 unsigned i;
9623 static const struct {
9624 float x, y, z;
9625 float s, t;
9626 D3DCOLOR diffuse;
9627 } quad[] = {
9628 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9629 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9630 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9631 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9634 static const D3DVERTEXELEMENT9 decl_elements[] = {
9635 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9636 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9637 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9638 D3DDECL_END()
9641 static const struct {
9642 D3DTEXTUREOP op;
9643 const char *name;
9644 DWORD caps_flag;
9645 D3DCOLOR result;
9646 } test_data[] = {
9647 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9648 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9649 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9650 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9651 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9652 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9653 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9654 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9655 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9656 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9657 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9658 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9659 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9660 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9661 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9662 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9663 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9664 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9665 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9666 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9667 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9668 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9669 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9672 memset(&caps, 0, sizeof(caps));
9673 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9674 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9676 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9677 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9678 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9679 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9681 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9682 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9683 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9684 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9685 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9686 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9687 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9688 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9689 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9691 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9692 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9693 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9694 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9695 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9696 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9698 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9699 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9702 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9703 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9704 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9706 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9708 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9709 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9711 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9713 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9715 skip("tex operation %s not supported\n", test_data[i].name);
9716 continue;
9719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9720 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9722 hr = IDirect3DDevice9_BeginScene(device);
9723 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9726 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9728 hr = IDirect3DDevice9_EndScene(device);
9729 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9731 color = getPixelColor(device, 320, 240);
9732 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9733 test_data[i].name, color, test_data[i].result);
9735 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9736 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9739 if (texture) IDirect3DTexture9_Release(texture);
9740 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9743 static void yuv_color_test(IDirect3DDevice9 *device) {
9744 HRESULT hr;
9745 IDirect3DSurface9 *surface = NULL, *target = NULL;
9746 unsigned int fmt, i;
9747 D3DFORMAT format;
9748 const char *fmt_string;
9749 D3DLOCKED_RECT lr;
9750 IDirect3D9 *d3d;
9751 HRESULT color;
9752 DWORD ref_color_left, ref_color_right;
9754 struct {
9755 DWORD in; /* The input color */
9756 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9757 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9758 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9759 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9760 } test_data[] = {
9761 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9762 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9763 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9764 * that
9766 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9767 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9768 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9769 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9770 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9771 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9772 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9773 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9774 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9775 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9776 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9777 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9778 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9779 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9781 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9782 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9783 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9784 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9787 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9788 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9789 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9790 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9792 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9793 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9795 for(fmt = 0; fmt < 2; fmt++) {
9796 if(fmt == 0) {
9797 format = D3DFMT_UYVY;
9798 fmt_string = "D3DFMT_UYVY";
9799 } else {
9800 format = D3DFMT_YUY2;
9801 fmt_string = "D3DFMT_YUY2";
9804 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9805 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9807 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9808 D3DRTYPE_SURFACE, format) != D3D_OK) {
9809 skip("%s is not supported\n", fmt_string);
9810 continue;
9813 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9814 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9815 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9817 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9818 if(fmt == 0) {
9819 ref_color_left = test_data[i].uyvy_left;
9820 ref_color_right = test_data[i].uyvy_right;
9821 } else {
9822 ref_color_left = test_data[i].yuy2_left;
9823 ref_color_right = test_data[i].yuy2_right;
9826 memset(&lr, 0, sizeof(lr));
9827 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9828 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9829 *((DWORD *) lr.pBits) = test_data[i].in;
9830 hr = IDirect3DSurface9_UnlockRect(surface);
9831 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9834 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9835 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9836 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9838 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9839 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9840 * want to add tests for the filtered pixels as well.
9842 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9843 * differently, so we need a max diff of 16
9845 color = getPixelColor(device, 40, 240);
9846 ok(color_match(color, ref_color_left, 18),
9847 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9848 test_data[i].in, color, ref_color_left, fmt_string);
9849 color = getPixelColor(device, 600, 240);
9850 ok(color_match(color, ref_color_right, 18),
9851 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9852 test_data[i].in, color, ref_color_right, fmt_string);
9853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9854 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9856 IDirect3DSurface9_Release(surface);
9858 IDirect3DSurface9_Release(target);
9859 IDirect3D9_Release(d3d);
9862 static void texop_range_test(IDirect3DDevice9 *device)
9864 static const struct {
9865 float x, y, z;
9866 D3DCOLOR diffuse;
9867 } quad[] = {
9868 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9869 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9870 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9871 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9873 HRESULT hr;
9874 IDirect3DTexture9 *texture;
9875 D3DLOCKED_RECT locked_rect;
9876 D3DCAPS9 caps;
9877 DWORD color;
9879 /* We need ADD and SUBTRACT operations */
9880 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9881 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9882 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9883 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9884 return;
9886 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9887 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9888 return;
9891 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9892 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9893 /* Stage 1: result = diffuse(=1.0) + diffuse
9894 * stage 2: result = result - tfactor(= 0.5)
9896 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9897 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9898 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9899 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9900 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9901 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9903 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9904 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9905 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9906 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9907 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9908 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9909 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9911 hr = IDirect3DDevice9_BeginScene(device);
9912 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9913 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9914 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9915 hr = IDirect3DDevice9_EndScene(device);
9916 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9918 color = getPixelColor(device, 320, 240);
9919 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9920 color);
9921 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9922 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9924 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9925 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9926 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9927 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9928 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9929 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9930 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9931 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9932 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9934 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9935 * stage 2: result = result + diffuse(1.0)
9937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9938 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9939 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9940 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9941 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9942 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9943 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9944 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9945 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9946 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9947 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9948 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9949 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9950 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9952 hr = IDirect3DDevice9_BeginScene(device);
9953 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9955 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9956 hr = IDirect3DDevice9_EndScene(device);
9957 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9959 color = getPixelColor(device, 320, 240);
9960 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9961 color);
9962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9965 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9966 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9967 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9968 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9969 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9970 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9971 IDirect3DTexture9_Release(texture);
9974 static void alphareplicate_test(IDirect3DDevice9 *device) {
9975 struct vertex quad[] = {
9976 { -1.0, -1.0, 0.1, 0x80ff00ff },
9977 { 1.0, -1.0, 0.1, 0x80ff00ff },
9978 { -1.0, 1.0, 0.1, 0x80ff00ff },
9979 { 1.0, 1.0, 0.1, 0x80ff00ff },
9981 HRESULT hr;
9982 DWORD color;
9984 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9985 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9987 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9988 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9990 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9991 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9992 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9993 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9995 hr = IDirect3DDevice9_BeginScene(device);
9996 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9997 if(SUCCEEDED(hr)) {
9998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10000 hr = IDirect3DDevice9_EndScene(device);
10001 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10004 color = getPixelColor(device, 320, 240);
10005 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10006 color);
10007 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10008 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10010 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10011 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10015 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10016 HRESULT hr;
10017 D3DCAPS9 caps;
10018 DWORD color;
10019 struct vertex quad[] = {
10020 { -1.0, -1.0, 0.1, 0x408080c0 },
10021 { 1.0, -1.0, 0.1, 0x408080c0 },
10022 { -1.0, 1.0, 0.1, 0x408080c0 },
10023 { 1.0, 1.0, 0.1, 0x408080c0 },
10026 memset(&caps, 0, sizeof(caps));
10027 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10028 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10029 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10030 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10031 return;
10034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10035 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10037 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10038 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10040 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10041 * mov r0.a, diffuse.a
10042 * mov r0, r0.a
10044 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10045 * 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
10046 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10048 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10049 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10050 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10051 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10052 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10053 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10054 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10055 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10057 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10058 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10059 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10060 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10061 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10062 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10065 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10067 hr = IDirect3DDevice9_BeginScene(device);
10068 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10069 if(SUCCEEDED(hr)) {
10070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10071 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10072 hr = IDirect3DDevice9_EndScene(device);
10073 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10076 color = getPixelColor(device, 320, 240);
10077 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10078 color);
10079 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10080 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10082 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10083 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10084 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10085 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10086 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10087 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10090 static void zwriteenable_test(IDirect3DDevice9 *device) {
10091 HRESULT hr;
10092 DWORD color;
10093 struct vertex quad1[] = {
10094 { -1.0, -1.0, 0.1, 0x00ff0000},
10095 { -1.0, 1.0, 0.1, 0x00ff0000},
10096 { 1.0, -1.0, 0.1, 0x00ff0000},
10097 { 1.0, 1.0, 0.1, 0x00ff0000},
10099 struct vertex quad2[] = {
10100 { -1.0, -1.0, 0.9, 0x0000ff00},
10101 { -1.0, 1.0, 0.9, 0x0000ff00},
10102 { 1.0, -1.0, 0.9, 0x0000ff00},
10103 { 1.0, 1.0, 0.9, 0x0000ff00},
10106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10107 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10109 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10110 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10114 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10118 hr = IDirect3DDevice9_BeginScene(device);
10119 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10120 if(SUCCEEDED(hr)) {
10121 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10122 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10123 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10124 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10125 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10126 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10129 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10135 hr = IDirect3DDevice9_EndScene(device);
10136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10139 color = getPixelColor(device, 320, 240);
10140 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10141 color);
10142 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10143 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10149 static void alphatest_test(IDirect3DDevice9 *device) {
10150 #define ALPHATEST_PASSED 0x0000ff00
10151 #define ALPHATEST_FAILED 0x00ff0000
10152 struct {
10153 D3DCMPFUNC func;
10154 DWORD color_less;
10155 DWORD color_equal;
10156 DWORD color_greater;
10157 } testdata[] = {
10158 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10159 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10160 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10161 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10162 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10163 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10164 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10165 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10167 unsigned int i, j;
10168 HRESULT hr;
10169 DWORD color;
10170 struct vertex quad[] = {
10171 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10172 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10173 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10174 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10176 D3DCAPS9 caps;
10178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10179 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10180 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10181 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10183 for(j = 0; j < 2; j++) {
10184 if(j == 1) {
10185 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10186 * the alpha test either for performance reasons(floating point RTs) or to work
10187 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10188 * codepath for ffp and shader in this case, and the test should cover both
10190 IDirect3DPixelShader9 *ps;
10191 DWORD shader_code[] = {
10192 0xffff0101, /* ps_1_1 */
10193 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10194 0x0000ffff /* end */
10196 memset(&caps, 0, sizeof(caps));
10197 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10199 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10200 break;
10203 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10204 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10205 IDirect3DDevice9_SetPixelShader(device, ps);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10207 IDirect3DPixelShader9_Release(ps);
10210 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10212 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10215 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10217 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState 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);
10226 color = getPixelColor(device, 320, 240);
10227 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10228 color, testdata[i].color_less, testdata[i].func);
10229 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10230 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10232 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10233 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10235 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10236 hr = IDirect3DDevice9_BeginScene(device);
10237 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10238 if(SUCCEEDED(hr)) {
10239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10240 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10241 hr = IDirect3DDevice9_EndScene(device);
10242 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10244 color = getPixelColor(device, 320, 240);
10245 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10246 color, testdata[i].color_equal, testdata[i].func);
10247 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10248 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10251 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10252 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10253 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10254 hr = IDirect3DDevice9_BeginScene(device);
10255 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10256 if(SUCCEEDED(hr)) {
10257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10258 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10259 hr = IDirect3DDevice9_EndScene(device);
10260 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10262 color = getPixelColor(device, 320, 240);
10263 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10264 color, testdata[i].color_greater, testdata[i].func);
10265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10266 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10272 IDirect3DDevice9_SetPixelShader(device, NULL);
10273 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10276 static void sincos_test(IDirect3DDevice9 *device) {
10277 const DWORD sin_shader_code[] = {
10278 0xfffe0200, /* vs_2_0 */
10279 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10280 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10281 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10282 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10283 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10284 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10285 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10286 0x0000ffff /* end */
10288 const DWORD cos_shader_code[] = {
10289 0xfffe0200, /* vs_2_0 */
10290 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10291 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10292 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10293 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10294 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10295 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10296 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10297 0x0000ffff /* end */
10299 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10300 HRESULT hr;
10301 struct {
10302 float x, y, z;
10303 } data[1280];
10304 unsigned int i;
10305 float sincosc1[4] = {D3DSINCOSCONST1};
10306 float sincosc2[4] = {D3DSINCOSCONST2};
10308 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10311 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10312 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10313 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10314 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10315 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10316 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10317 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10318 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10319 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10322 /* Generate a point from -1 to 1 every 0.5 pixels */
10323 for(i = 0; i < 1280; i++) {
10324 data[i].x = (-640.0 + i) / 640.0;
10325 data[i].y = 0.0;
10326 data[i].z = 0.1;
10329 hr = IDirect3DDevice9_BeginScene(device);
10330 if(SUCCEEDED(hr)) {
10331 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10332 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10333 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10334 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10336 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10337 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10339 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10341 hr = IDirect3DDevice9_EndScene(device);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10344 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10345 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10346 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10348 IDirect3DDevice9_SetVertexShader(device, NULL);
10349 IDirect3DVertexShader9_Release(sin_shader);
10350 IDirect3DVertexShader9_Release(cos_shader);
10353 static void loop_index_test(IDirect3DDevice9 *device) {
10354 const DWORD shader_code[] = {
10355 0xfffe0200, /* vs_2_0 */
10356 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10357 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10358 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10359 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10360 0x0000001d, /* endloop */
10361 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10362 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10363 0x0000ffff /* END */
10365 IDirect3DVertexShader9 *shader;
10366 HRESULT hr;
10367 DWORD color;
10368 const float quad[] = {
10369 -1.0, -1.0, 0.1,
10370 1.0, -1.0, 0.1,
10371 -1.0, 1.0, 0.1,
10372 1.0, 1.0, 0.1
10374 const float zero[4] = {0, 0, 0, 0};
10375 const float one[4] = {1, 1, 1, 1};
10376 int i0[4] = {2, 10, -3, 0};
10377 float values[4];
10379 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10380 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10381 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10382 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10383 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10384 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10388 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10389 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10390 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10391 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10392 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10393 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10394 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10395 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10396 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10397 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10398 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10399 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10400 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10401 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10402 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10403 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10404 values[0] = 1.0;
10405 values[1] = 1.0;
10406 values[2] = 0.0;
10407 values[3] = 0.0;
10408 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10409 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10410 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10411 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10412 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10413 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10414 values[0] = -1.0;
10415 values[1] = 0.0;
10416 values[2] = 0.0;
10417 values[3] = 0.0;
10418 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10419 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10420 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10421 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10422 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10423 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10424 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10425 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10426 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10429 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10430 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10432 hr = IDirect3DDevice9_BeginScene(device);
10433 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10434 if(SUCCEEDED(hr))
10436 trace("going to draw index\n");
10437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10438 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10439 hr = IDirect3DDevice9_EndScene(device);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10442 color = getPixelColor(device, 320, 240);
10443 ok(color_match(color, 0x0000ff00, 1),
10444 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10448 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10449 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10450 IDirect3DVertexShader9_Release(shader);
10453 static void sgn_test(IDirect3DDevice9 *device) {
10454 const DWORD shader_code[] = {
10455 0xfffe0200, /* vs_2_0 */
10456 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10457 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10458 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10459 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10460 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10461 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10462 0x0000ffff /* end */
10464 IDirect3DVertexShader9 *shader;
10465 HRESULT hr;
10466 DWORD color;
10467 const float quad[] = {
10468 -1.0, -1.0, 0.1,
10469 1.0, -1.0, 0.1,
10470 -1.0, 1.0, 0.1,
10471 1.0, 1.0, 0.1
10474 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10475 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10476 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10477 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10478 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10479 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10481 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10483 hr = IDirect3DDevice9_BeginScene(device);
10484 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10485 if(SUCCEEDED(hr))
10487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10488 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10489 hr = IDirect3DDevice9_EndScene(device);
10490 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10492 color = getPixelColor(device, 320, 240);
10493 ok(color_match(color, 0x008000ff, 1),
10494 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10496 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10498 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10500 IDirect3DVertexShader9_Release(shader);
10503 static void viewport_test(IDirect3DDevice9 *device) {
10504 HRESULT hr;
10505 DWORD color;
10506 D3DVIEWPORT9 vp, old_vp;
10507 const float quad[] =
10509 -0.5, -0.5, 0.1,
10510 0.5, -0.5, 0.1,
10511 -0.5, 0.5, 0.1,
10512 0.5, 0.5, 0.1
10515 memset(&old_vp, 0, sizeof(old_vp));
10516 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10517 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10519 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10520 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10522 /* Test a viewport with Width and Height bigger than the surface dimensions
10524 * TODO: Test Width < surface.width, but X + Width > surface.width
10525 * TODO: Test Width < surface.width, what happens with the height?
10527 memset(&vp, 0, sizeof(vp));
10528 vp.X = 0;
10529 vp.Y = 0;
10530 vp.Width = 10000;
10531 vp.Height = 10000;
10532 vp.MinZ = 0.0;
10533 vp.MaxZ = 0.0;
10534 hr = IDirect3DDevice9_SetViewport(device, &vp);
10535 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10537 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10538 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10539 hr = IDirect3DDevice9_BeginScene(device);
10540 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10541 if(SUCCEEDED(hr))
10543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10544 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10545 hr = IDirect3DDevice9_EndScene(device);
10546 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10549 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10550 color = getPixelColor(device, 158, 118);
10551 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10552 color = getPixelColor(device, 162, 118);
10553 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10554 color = getPixelColor(device, 158, 122);
10555 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10556 color = getPixelColor(device, 162, 122);
10557 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10559 color = getPixelColor(device, 478, 358);
10560 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10561 color = getPixelColor(device, 482, 358);
10562 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10563 color = getPixelColor(device, 478, 362);
10564 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10565 color = getPixelColor(device, 482, 362);
10566 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10569 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10571 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10572 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10575 START_TEST(visual)
10577 IDirect3DDevice9 *device_ptr;
10578 D3DCAPS9 caps;
10579 HRESULT hr;
10580 DWORD color;
10582 d3d9_handle = LoadLibraryA("d3d9.dll");
10583 if (!d3d9_handle)
10585 skip("Could not load d3d9.dll\n");
10586 return;
10589 device_ptr = init_d3d9();
10590 if (!device_ptr)
10592 skip("Creating the device failed\n");
10593 return;
10596 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10598 /* Check for the reliability of the returned data */
10599 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10600 if(FAILED(hr))
10602 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10603 goto cleanup;
10606 color = getPixelColor(device_ptr, 1, 1);
10607 if(color !=0x00ff0000)
10609 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10610 goto cleanup;
10612 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10614 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10615 if(FAILED(hr))
10617 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10618 goto cleanup;
10621 color = getPixelColor(device_ptr, 639, 479);
10622 if(color != 0x0000ddee)
10624 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10625 goto cleanup;
10627 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10629 /* Now execute the real tests */
10630 stretchrect_test(device_ptr);
10631 lighting_test(device_ptr);
10632 clear_test(device_ptr);
10633 fog_test(device_ptr);
10634 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10636 test_cube_wrap(device_ptr);
10637 } else {
10638 skip("No cube texture support\n");
10640 z_range_test(device_ptr);
10641 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10643 maxmip_test(device_ptr);
10645 else
10647 skip("No mipmap support\n");
10649 offscreen_test(device_ptr);
10650 alpha_test(device_ptr);
10651 shademode_test(device_ptr);
10652 srgbtexture_test(device_ptr);
10653 release_buffer_test(device_ptr);
10654 float_texture_test(device_ptr);
10655 g16r16_texture_test(device_ptr);
10656 pixelshader_blending_test(device_ptr);
10657 texture_transform_flags_test(device_ptr);
10658 autogen_mipmap_test(device_ptr);
10659 fixed_function_decl_test(device_ptr);
10660 conditional_np2_repeat_test(device_ptr);
10661 fixed_function_bumpmap_test(device_ptr);
10662 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10663 stencil_cull_test(device_ptr);
10664 } else {
10665 skip("No two sided stencil support\n");
10667 pointsize_test(device_ptr);
10668 tssargtemp_test(device_ptr);
10669 np2_stretch_rect_test(device_ptr);
10670 yuv_color_test(device_ptr);
10671 zwriteenable_test(device_ptr);
10672 alphatest_test(device_ptr);
10673 viewport_test(device_ptr);
10675 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10677 test_constant_clamp_vs(device_ptr);
10678 test_compare_instructions(device_ptr);
10680 else skip("No vs_1_1 support\n");
10682 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10684 test_mova(device_ptr);
10685 loop_index_test(device_ptr);
10686 sincos_test(device_ptr);
10687 sgn_test(device_ptr);
10688 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10689 test_vshader_input(device_ptr);
10690 test_vshader_float16(device_ptr);
10691 stream_test(device_ptr);
10692 } else {
10693 skip("No vs_3_0 support\n");
10696 else skip("No vs_2_0 support\n");
10698 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10700 fog_with_shader_test(device_ptr);
10701 fog_srgbwrite_test(device_ptr);
10703 else skip("No vs_1_1 and ps_1_1 support\n");
10705 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10707 texbem_test(device_ptr);
10708 texdepth_test(device_ptr);
10709 texkill_test(device_ptr);
10710 x8l8v8u8_test(device_ptr);
10711 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10712 constant_clamp_ps_test(device_ptr);
10713 cnd_test(device_ptr);
10714 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10715 dp2add_ps_test(device_ptr);
10716 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10717 nested_loop_test(device_ptr);
10718 fixed_function_varying_test(device_ptr);
10719 vFace_register_test(device_ptr);
10720 vpos_register_test(device_ptr);
10721 multiple_rendertargets_test(device_ptr);
10722 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10723 vshader_version_varying_test(device_ptr);
10724 pshader_version_varying_test(device_ptr);
10725 } else {
10726 skip("No vs_3_0 support\n");
10728 } else {
10729 skip("No ps_3_0 support\n");
10731 } else {
10732 skip("No ps_2_0 support\n");
10736 else skip("No ps_1_1 support\n");
10738 texop_test(device_ptr);
10739 texop_range_test(device_ptr);
10740 alphareplicate_test(device_ptr);
10741 dp3_alpha_test(device_ptr);
10743 cleanup:
10744 if(device_ptr) {
10745 D3DPRESENT_PARAMETERS present_parameters;
10746 IDirect3DSwapChain9 *swapchain;
10747 ULONG ref;
10749 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10750 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10751 IDirect3DSwapChain9_Release(swapchain);
10752 ref = IDirect3DDevice9_Release(device_ptr);
10753 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10754 DestroyWindow(present_parameters.hDeviceWindow);