Release 1.3.7.
[wine/gsoc-2012-control.git] / dlls / d3d9 / tests / visual.c
blob887f302fb150bcb1f16d995dc23ae7deb3da04da
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114 if(FAILED(hr) || !surf ) /* This is not a test */
116 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117 return 0xdeadbeef;
120 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121 if(FAILED(hr))
123 trace("Can't get the render target, hr=%08x\n", hr);
124 ret = 0xdeadbeed;
125 goto out;
128 hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129 if(FAILED(hr))
131 trace("Can't read the render target data, hr=%08x\n", hr);
132 ret = 0xdeadbeec;
133 goto out;
136 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137 if(FAILED(hr))
139 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140 ret = 0xdeadbeeb;
141 goto out;
144 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145 * really important for these tests
147 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148 hr = IDirect3DSurface9_UnlockRect(surf);
149 if(FAILED(hr))
151 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
154 out:
155 if(target) IDirect3DSurface9_Release(target);
156 if(surf) IDirect3DSurface9_Release(surf);
157 return ret;
160 static IDirect3DDevice9 *init_d3d9(void)
162 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163 IDirect3D9 *d3d9_ptr = 0;
164 IDirect3DDevice9 *device_ptr = 0;
165 D3DPRESENT_PARAMETERS present_parameters;
166 HRESULT hr;
167 D3DADAPTER_IDENTIFIER9 identifier;
169 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171 if (!d3d9_create) return NULL;
173 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174 if (!d3d9_ptr)
176 skip("could not create D3D9\n");
177 return NULL;
180 ZeroMemory(&present_parameters, sizeof(present_parameters));
181 present_parameters.Windowed = TRUE;
182 present_parameters.hDeviceWindow = create_window();
183 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184 present_parameters.BackBufferWidth = 640;
185 present_parameters.BackBufferHeight = 480;
186 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187 present_parameters.EnableAutoDepthStencil = TRUE;
188 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190 memset(&identifier, 0, sizeof(identifier));
191 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193 trace("Driver string: \"%s\"\n", identifier.Driver);
194 trace("Description string: \"%s\"\n", identifier.Description);
195 ok(identifier.Description[0] != '\0', "Empty driver description\n");
196 trace("Device name string: \"%s\"\n", identifier.DeviceName);
197 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
198 trace("Driver version %d.%d.%d.%d\n",
199 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203 if(FAILED(hr)) {
204 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206 if(FAILED(hr)) {
207 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
210 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
212 return device_ptr;
215 struct vertex
217 float x, y, z;
218 DWORD diffuse;
221 struct tvertex
223 float x, y, z, rhw;
224 DWORD diffuse;
227 struct nvertex
229 float x, y, z;
230 float nx, ny, nz;
231 DWORD diffuse;
234 static void lighting_test(IDirect3DDevice9 *device)
236 HRESULT hr;
237 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239 DWORD color;
240 D3DMATERIAL9 material, old_material;
241 DWORD cop, carg;
243 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244 0.0f, 1.0f, 0.0f, 0.0f,
245 0.0f, 0.0f, 1.0f, 0.0f,
246 0.0f, 0.0f, 0.0f, 1.0f };
248 struct vertex unlitquad[] =
250 {-1.0f, -1.0f, 0.1f, 0xffff0000},
251 {-1.0f, 0.0f, 0.1f, 0xffff0000},
252 { 0.0f, 0.0f, 0.1f, 0xffff0000},
253 { 0.0f, -1.0f, 0.1f, 0xffff0000},
255 struct vertex litquad[] =
257 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
258 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
259 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
260 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
262 struct nvertex unlitnquad[] =
264 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
265 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
267 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
269 struct nvertex litnquad[] =
271 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
272 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
274 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
276 WORD Indices[] = {0, 1, 2, 2, 3, 0};
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
281 /* Setup some states that may cause issues */
282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
307 hr = IDirect3DDevice9_SetFVF(device, 0);
308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetFVF(device, fvf);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
313 hr = IDirect3DDevice9_BeginScene(device);
314 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315 if(hr == D3D_OK)
317 /* No lights are defined... That means, lit vertices should be entirely black */
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330 hr = IDirect3DDevice9_SetFVF(device, nfvf);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345 IDirect3DDevice9_EndScene(device);
346 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
349 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
358 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
360 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362 memset(&material, 0, sizeof(material));
363 material.Diffuse.r = 0.0;
364 material.Diffuse.g = 0.0;
365 material.Diffuse.b = 0.0;
366 material.Diffuse.a = 1.0;
367 material.Ambient.r = 0.0;
368 material.Ambient.g = 0.0;
369 material.Ambient.b = 0.0;
370 material.Ambient.a = 0.0;
371 material.Specular.r = 0.0;
372 material.Specular.g = 0.0;
373 material.Specular.b = 0.0;
374 material.Specular.a = 0.0;
375 material.Emissive.r = 0.0;
376 material.Emissive.g = 0.0;
377 material.Emissive.b = 0.0;
378 material.Emissive.a = 0.0;
379 material.Power = 0.0;
380 IDirect3DDevice9_SetMaterial(device, &material);
381 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
388 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
397 hr = IDirect3DDevice9_BeginScene(device);
398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399 if(SUCCEEDED(hr)) {
400 struct vertex lighting_test[] = {
401 {-1.0, -1.0, 0.1, 0x8000ff00},
402 { 1.0, -1.0, 0.1, 0x80000000},
403 {-1.0, 1.0, 0.1, 0x8000ff00},
404 { 1.0, 1.0, 0.1, 0x80000000}
406 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
411 hr = IDirect3DDevice9_EndScene(device);
412 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
415 color = getPixelColor(device, 320, 240);
416 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
433 static void clear_test(IDirect3DDevice9 *device)
435 /* Tests the correctness of clearing parameters */
436 HRESULT hr;
437 D3DRECT rect[2];
438 D3DRECT rect_negneg;
439 DWORD color;
440 D3DVIEWPORT9 old_vp, vp;
441 RECT scissor;
442 DWORD oldColorWrite;
443 BOOL invalid_clear_failed = FALSE;
445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448 /* Positive x, negative y */
449 rect[0].x1 = 0;
450 rect[0].y1 = 480;
451 rect[0].x2 = 320;
452 rect[0].y2 = 240;
454 /* Positive x, positive y */
455 rect[1].x1 = 0;
456 rect[1].y1 = 0;
457 rect[1].x2 = 320;
458 rect[1].y2 = 240;
459 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460 * returns D3D_OK, but ignores the rectangle silently
462 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466 /* negative x, negative y */
467 rect_negneg.x1 = 640;
468 rect_negneg.y1 = 240;
469 rect_negneg.x2 = 320;
470 rect_negneg.y2 = 0;
471 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475 color = getPixelColor(device, 160, 360); /* lower left quad */
476 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477 color = getPixelColor(device, 160, 120); /* upper left quad */
478 if(invalid_clear_failed) {
479 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481 } else {
482 /* If the negative rectangle was dropped silently, the correct ones are cleared */
483 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485 color = getPixelColor(device, 480, 360); /* lower right quad */
486 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487 color = getPixelColor(device, 480, 120); /* upper right quad */
488 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492 /* Test how the viewport affects clears */
493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
498 vp.X = 160;
499 vp.Y = 120;
500 vp.Width = 160;
501 vp.Height = 120;
502 vp.MinZ = 0.0;
503 vp.MaxZ = 1.0;
504 hr = IDirect3DDevice9_SetViewport(device, &vp);
505 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509 vp.X = 320;
510 vp.Y = 240;
511 vp.Width = 320;
512 vp.Height = 240;
513 vp.MinZ = 0.0;
514 vp.MaxZ = 1.0;
515 hr = IDirect3DDevice9_SetViewport(device, &vp);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 rect[0].x1 = 160;
518 rect[0].y1 = 120;
519 rect[0].x2 = 480;
520 rect[0].y2 = 360;
521 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
524 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
527 color = getPixelColor(device, 158, 118);
528 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529 color = getPixelColor(device, 162, 118);
530 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531 color = getPixelColor(device, 158, 122);
532 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533 color = getPixelColor(device, 162, 122);
534 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
536 color = getPixelColor(device, 318, 238);
537 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538 color = getPixelColor(device, 322, 238);
539 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540 color = getPixelColor(device, 318, 242);
541 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542 color = getPixelColor(device, 322, 242);
543 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
545 color = getPixelColor(device, 478, 358);
546 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547 color = getPixelColor(device, 482, 358);
548 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549 color = getPixelColor(device, 478, 362);
550 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551 color = getPixelColor(device, 482, 362);
552 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
554 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 scissor.left = 160;
560 scissor.right = 480;
561 scissor.top = 120;
562 scissor.bottom = 360;
563 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576 color = getPixelColor(device, 158, 118);
577 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578 color = getPixelColor(device, 162, 118);
579 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580 color = getPixelColor(device, 158, 122);
581 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582 color = getPixelColor(device, 162, 122);
583 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
585 color = getPixelColor(device, 158, 358);
586 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587 color = getPixelColor(device, 162, 358);
588 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589 color = getPixelColor(device, 158, 358);
590 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591 color = getPixelColor(device, 162, 362);
592 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
594 color = getPixelColor(device, 478, 118);
595 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596 color = getPixelColor(device, 478, 122);
597 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598 color = getPixelColor(device, 482, 122);
599 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600 color = getPixelColor(device, 482, 358);
601 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
603 color = getPixelColor(device, 478, 358);
604 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605 color = getPixelColor(device, 478, 362);
606 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607 color = getPixelColor(device, 482, 358);
608 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609 color = getPixelColor(device, 482, 362);
610 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612 color = getPixelColor(device, 318, 238);
613 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614 color = getPixelColor(device, 318, 242);
615 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616 color = getPixelColor(device, 322, 238);
617 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618 color = getPixelColor(device, 322, 242);
619 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
621 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
634 /* Colorwriteenable does not affect the clear */
635 color = getPixelColor(device, 320, 240);
636 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
638 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
641 static void color_fill_test(IDirect3DDevice9 *device)
643 HRESULT hr;
644 IDirect3DSurface9 *backbuffer = NULL;
645 IDirect3DSurface9 *rt_surface = NULL;
646 IDirect3DSurface9 *offscreen_surface = NULL;
647 DWORD fill_color, color;
649 /* Test ColorFill on a the backbuffer (should pass) */
650 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652 if(backbuffer)
654 fill_color = 0x112233;
655 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
657 color = getPixelColor(device, 0, 0);
658 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
660 IDirect3DSurface9_Release(backbuffer);
663 /* Test ColorFill on a render target surface (should pass) */
664 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666 if(rt_surface)
668 fill_color = 0x445566;
669 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
671 color = getPixelColorFromSurface(rt_surface, 0, 0);
672 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
674 IDirect3DSurface9_Release(rt_surface);
677 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681 if(offscreen_surface)
683 fill_color = 0x778899;
684 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
686 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
689 IDirect3DSurface9_Release(offscreen_surface);
692 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693 offscreen_surface = NULL;
694 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697 if(offscreen_surface)
699 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
702 IDirect3DSurface9_Release(offscreen_surface);
706 typedef struct {
707 float in[4];
708 DWORD out;
709 } test_data_t;
712 * c7 mova ARGB mov ARGB
713 * -2.4 -2 0x00ffff00 -3 0x00ff0000
714 * -1.6 -2 0x00ffff00 -2 0x00ffff00
715 * -0.4 0 0x0000ffff -1 0x0000ff00
716 * 0.4 0 0x0000ffff 0 0x0000ffff
717 * 1.6 2 0x00ff00ff 1 0x000000ff
718 * 2.4 2 0x00ff00ff 2 0x00ff00ff
720 static void test_mova(IDirect3DDevice9 *device)
722 static const DWORD mova_test[] = {
723 0xfffe0200, /* vs_2_0 */
724 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
725 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
726 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
727 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
728 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
729 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
730 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
731 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
732 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
733 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
734 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
735 0x0000ffff /* END */
737 static const DWORD mov_test[] = {
738 0xfffe0101, /* vs_1_1 */
739 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
740 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
741 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
742 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
743 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
744 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
745 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
746 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
747 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
748 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
749 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
750 0x0000ffff /* END */
753 static const test_data_t test_data[2][6] = {
755 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
763 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
772 static const float quad[][3] = {
773 {-1.0f, -1.0f, 0.0f},
774 {-1.0f, 1.0f, 0.0f},
775 { 1.0f, -1.0f, 0.0f},
776 { 1.0f, 1.0f, 0.0f},
779 static const D3DVERTEXELEMENT9 decl_elements[] = {
780 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781 D3DDECL_END()
784 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785 IDirect3DVertexShader9 *mova_shader = NULL;
786 IDirect3DVertexShader9 *mov_shader = NULL;
787 HRESULT hr;
788 UINT i, j;
790 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
799 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801 for(j = 0; j < 2; ++j)
803 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
805 DWORD color;
807 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
810 hr = IDirect3DDevice9_BeginScene(device);
811 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
816 hr = IDirect3DDevice9_EndScene(device);
817 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
819 color = getPixelColor(device, 320, 240);
820 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
823 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
829 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
833 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836 IDirect3DVertexDeclaration9_Release(vertex_declaration);
837 IDirect3DVertexShader9_Release(mova_shader);
838 IDirect3DVertexShader9_Release(mov_shader);
841 struct sVertex {
842 float x, y, z;
843 DWORD diffuse;
844 DWORD specular;
847 struct sVertexT {
848 float x, y, z, rhw;
849 DWORD diffuse;
850 DWORD specular;
853 static void fog_test(IDirect3DDevice9 *device)
855 HRESULT hr;
856 D3DCOLOR color;
857 float start = 0.0f, end = 1.0f;
858 D3DCAPS9 caps;
859 int i;
861 /* Gets full z based fog with linear fog, no fog with specular color */
862 struct sVertex unstransformed_1[] = {
863 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
864 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
865 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
866 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
868 /* Ok, I am too lazy to deal with transform matrices */
869 struct sVertex unstransformed_2[] = {
870 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
871 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
872 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
873 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
875 /* Untransformed ones. Give them a different diffuse color to make the test look
876 * nicer. It also makes making sure that they are drawn correctly easier.
878 struct sVertexT transformed_1[] = {
879 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
880 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
881 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
882 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
884 struct sVertexT transformed_2[] = {
885 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
886 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
887 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
888 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
890 struct vertex rev_fog_quads[] = {
891 {-1.0, -1.0, 0.1, 0x000000ff},
892 {-1.0, 0.0, 0.1, 0x000000ff},
893 { 0.0, 0.0, 0.1, 0x000000ff},
894 { 0.0, -1.0, 0.1, 0x000000ff},
896 { 0.0, -1.0, 0.9, 0x000000ff},
897 { 0.0, 0.0, 0.9, 0x000000ff},
898 { 1.0, 0.0, 0.9, 0x000000ff},
899 { 1.0, -1.0, 0.9, 0x000000ff},
901 { 0.0, 0.0, 0.4, 0x000000ff},
902 { 0.0, 1.0, 0.4, 0x000000ff},
903 { 1.0, 1.0, 0.4, 0x000000ff},
904 { 1.0, 0.0, 0.4, 0x000000ff},
906 {-1.0, 0.0, 0.7, 0x000000ff},
907 {-1.0, 1.0, 0.7, 0x000000ff},
908 { 0.0, 1.0, 0.7, 0x000000ff},
909 { 0.0, 0.0, 0.7, 0x000000ff},
911 WORD Indices[] = {0, 1, 2, 2, 3, 0};
913 memset(&caps, 0, sizeof(caps));
914 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
919 /* Setup initial states: No lighting, fog on, fog color */
920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
927 /* First test: Both table fog and vertex fog off */
928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
933 /* Start = 0, end = 1. Should be default, but set them */
934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
939 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
941 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946 sizeof(unstransformed_1[0]));
947 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
949 /* That makes it use the Z value */
950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952 /* Untransformed, vertex fog != none (or table fog != none):
953 * Use the Z value as input into the equation
955 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957 sizeof(unstransformed_1[0]));
958 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960 /* transformed verts */
961 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966 sizeof(transformed_1[0]));
967 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972 * equation
974 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976 sizeof(transformed_2[0]));
977 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
979 hr = IDirect3DDevice9_EndScene(device);
980 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
982 else
984 ok(FALSE, "BeginScene failed\n");
987 color = getPixelColor(device, 160, 360);
988 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989 color = getPixelColor(device, 160, 120);
990 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991 color = getPixelColor(device, 480, 120);
992 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
995 color = getPixelColor(device, 480, 360);
996 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
998 else
1000 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001 * The settings above result in no fogging with vertex fog
1003 color = getPixelColor(device, 480, 120);
1004 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005 trace("Info: Table fog not supported by this device\n");
1007 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1009 /* Now test the special case fogstart == fogend */
1010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1013 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1015 start = 512;
1016 end = 512;
1017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1022 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1029 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033 * color and has fixed fogstart and fogend.
1035 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037 sizeof(unstransformed_1[0]));
1038 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041 sizeof(unstransformed_1[0]));
1042 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049 sizeof(transformed_1[0]));
1050 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1052 hr = IDirect3DDevice9_EndScene(device);
1053 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1055 else
1057 ok(FALSE, "BeginScene failed\n");
1059 color = getPixelColor(device, 160, 360);
1060 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061 color = getPixelColor(device, 160, 120);
1062 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063 color = getPixelColor(device, 480, 120);
1064 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1067 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068 * but without shaders it seems to work everywhere
1070 end = 0.2;
1071 start = 0.8;
1072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1079 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081 * so skip this for now
1083 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084 const char *mode = (i ? "table" : "vertex");
1085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091 hr = IDirect3DDevice9_BeginScene(device);
1092 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093 if(SUCCEEDED(hr)) {
1094 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1095 4, 5, 6, 6, 7, 4,
1096 8, 9, 10, 10, 11, 8,
1097 12, 13, 14, 14, 15, 12};
1099 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101 sizeof(rev_fog_quads[0]));
1102 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1104 hr = IDirect3DDevice9_EndScene(device);
1105 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1107 color = getPixelColor(device, 160, 360);
1108 ok(color_match(color, 0x0000ff00, 1),
1109 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1111 color = getPixelColor(device, 160, 120);
1112 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1115 color = getPixelColor(device, 480, 120);
1116 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1119 color = getPixelColor(device, 480, 360);
1120 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126 break;
1129 /* Turn off the fog master switch to avoid confusing other tests */
1130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132 start = 0.0;
1133 end = 1.0;
1134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146 * regardless of the actual addressing mode set. The way this test works is
1147 * that we sample in one of the corners of the cubemap with filtering enabled,
1148 * and check the interpolated color. There are essentially two reasonable
1149 * things an implementation can do: Either pick one of the faces and
1150 * interpolate the edge texel with itself (i.e., clamp within the face), or
1151 * interpolate between the edge texels of the three involved faces. It should
1152 * never involve the border color or the other side (texcoord wrapping) of a
1153 * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1156 static const float quad[][6] = {
1157 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1163 static const D3DVERTEXELEMENT9 decl_elements[] = {
1164 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166 D3DDECL_END()
1169 static const struct {
1170 D3DTEXTUREADDRESS mode;
1171 const char *name;
1172 } address_modes[] = {
1173 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1180 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181 IDirect3DCubeTexture9 *texture = NULL;
1182 IDirect3DSurface9 *surface = NULL;
1183 IDirect3DSurface9 *face_surface;
1184 D3DLOCKED_RECT locked_rect;
1185 HRESULT hr;
1186 UINT x;
1187 INT y, face;
1189 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1194 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1198 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199 D3DPOOL_DEFAULT, &texture, NULL);
1200 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1202 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1205 for (y = 0; y < 128; ++y)
1207 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208 for (x = 0; x < 64; ++x)
1210 *ptr++ = 0xff0000ff;
1212 for (x = 64; x < 128; ++x)
1214 *ptr++ = 0xffff0000;
1218 hr = IDirect3DSurface9_UnlockRect(surface);
1219 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1221 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1224 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1227 IDirect3DSurface9_Release(face_surface);
1229 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1232 for (y = 0; y < 128; ++y)
1234 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235 for (x = 0; x < 64; ++x)
1237 *ptr++ = 0xffff0000;
1239 for (x = 64; x < 128; ++x)
1241 *ptr++ = 0xff0000ff;
1245 hr = IDirect3DSurface9_UnlockRect(surface);
1246 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1248 /* Create cube faces */
1249 for (face = 1; face < 6; ++face)
1251 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1254 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1257 IDirect3DSurface9_Release(face_surface);
1260 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1263 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1273 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1275 DWORD color;
1277 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1282 hr = IDirect3DDevice9_BeginScene(device);
1283 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1288 hr = IDirect3DDevice9_EndScene(device);
1289 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1291 color = getPixelColor(device, 320, 240);
1292 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294 color, address_modes[x].name);
1296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1303 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1306 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307 IDirect3DCubeTexture9_Release(texture);
1308 IDirect3DSurface9_Release(surface);
1311 static void offscreen_test(IDirect3DDevice9 *device)
1313 HRESULT hr;
1314 IDirect3DTexture9 *offscreenTexture = NULL;
1315 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316 DWORD color;
1318 static const float quad[][5] = {
1319 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1321 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1325 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1328 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330 if(!offscreenTexture) {
1331 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334 if(!offscreenTexture) {
1335 skip("Cannot create an offscreen render target\n");
1336 goto out;
1340 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342 if(!backbuffer) {
1343 goto out;
1346 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348 if(!offscreen) {
1349 goto out;
1352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1366 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1372 /* Draw without textures - Should result in a white quad */
1373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1376 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1381 /* This time with the texture */
1382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1385 IDirect3DDevice9_EndScene(device);
1388 /* Center quad - should be white */
1389 color = getPixelColor(device, 320, 240);
1390 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391 /* Some quad in the cleared part of the texture */
1392 color = getPixelColor(device, 170, 240);
1393 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394 /* Part of the originally cleared back buffer */
1395 color = getPixelColor(device, 10, 10);
1396 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397 if(0) {
1398 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400 * the offscreen rendering mode this test would succeed or fail
1402 color = getPixelColor(device, 10, 470);
1403 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1406 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1408 out:
1409 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1412 /* restore things */
1413 if(backbuffer) {
1414 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416 IDirect3DSurface9_Release(backbuffer);
1418 if(offscreenTexture) {
1419 IDirect3DTexture9_Release(offscreenTexture);
1421 if(offscreen) {
1422 IDirect3DSurface9_Release(offscreen);
1426 /* This test tests fog in combination with shaders.
1427 * What's tested: linear fog (vertex and table) with pixel shader
1428 * linear table fog with non foggy vertex shader
1429 * vertex fog with foggy vertex shader, non-linear
1430 * fog with shader, non-linear fog with foggy shader,
1431 * linear table fog with foggy shader
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1435 HRESULT hr;
1436 DWORD color;
1437 union {
1438 float f;
1439 DWORD i;
1440 } start, end;
1441 unsigned int i, j;
1443 /* basic vertex shader without fog computation ("non foggy") */
1444 static const DWORD vertex_shader_code1[] = {
1445 0xfffe0101, /* vs_1_1 */
1446 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1447 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1448 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1449 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1450 0x0000ffff
1452 /* basic vertex shader with reversed fog computation ("foggy") */
1453 static const DWORD vertex_shader_code2[] = {
1454 0xfffe0101, /* vs_1_1 */
1455 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1456 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1457 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1459 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1460 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1461 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1462 0x0000ffff
1464 /* basic pixel shader */
1465 static const DWORD pixel_shader_code[] = {
1466 0xffff0101, /* ps_1_1 */
1467 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1468 0x0000ffff
1471 static struct vertex quad[] = {
1472 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1473 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1474 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1475 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1478 static const D3DVERTEXELEMENT9 decl_elements[] = {
1479 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1481 D3DDECL_END()
1484 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1486 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1488 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489 static const struct test_data_t {
1490 int vshader;
1491 int pshader;
1492 D3DFOGMODE vfog;
1493 D3DFOGMODE tfog;
1494 unsigned int color[11];
1495 } test_data[] = {
1496 /* only pixel shader: */
1497 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1513 /* vertex shader */
1514 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1531 /* vertex shader and pixel shader */
1532 /* The next 4 tests would read the fog coord output, but it isn't available.
1533 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535 * These tests should be disabled if some other hardware behaves differently
1537 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1550 /* These use the Z coordinate with linear table fog */
1551 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1564 /* Non-linear table fog without fog coord */
1565 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1572 #if 0 /* FIXME: these fail on GeForce 8500 */
1573 /* foggy vertex shader */
1574 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1588 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589 * all using the fixed fog-coord linear fog
1591 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 /* These use table fog. Here the shader-provided fog coordinate is
1605 * ignored and the z coordinate used instead
1607 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1618 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619 start.f=0.1f;
1620 end.f=0.9f;
1622 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1631 /* Setup initial states: No lighting, fog on, fog color */
1632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1646 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1652 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1654 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1663 for(j=0; j < 11; j++)
1665 /* Don't use the whole zrange to prevent rounding errors */
1666 quad[0].z = 0.001f + (float)j / 10.02f;
1667 quad[1].z = 0.001f + (float)j / 10.02f;
1668 quad[2].z = 0.001f + (float)j / 10.02f;
1669 quad[3].z = 0.001f + (float)j / 10.02f;
1671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1674 hr = IDirect3DDevice9_BeginScene(device);
1675 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1680 hr = IDirect3DDevice9_EndScene(device);
1681 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1683 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684 color = getPixelColor(device, 128, 240);
1685 ok(color_match(color, test_data[i].color[j], 13),
1686 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1689 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1693 /* reset states */
1694 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1703 IDirect3DVertexShader9_Release(vertex_shader[1]);
1704 IDirect3DVertexShader9_Release(vertex_shader[2]);
1705 IDirect3DPixelShader9_Release(pixel_shader[1]);
1706 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710 unsigned int i, x, y;
1711 HRESULT hr;
1712 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713 D3DLOCKED_RECT locked_rect;
1715 /* Generate the textures */
1716 for(i=0; i<2; i++)
1718 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719 D3DPOOL_MANAGED, &texture[i], NULL);
1720 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1722 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724 for (y = 0; y < 128; ++y)
1726 if(i)
1727 { /* Set up black texture with 2x2 texel white spot in the middle */
1728 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729 for (x = 0; x < 128; ++x)
1731 if(y>62 && y<66 && x>62 && x<66)
1732 *ptr++ = 0xffffffff;
1733 else
1734 *ptr++ = 0xff000000;
1737 else
1738 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739 * (if multiplied with bumpenvmat)
1741 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742 for (x = 0; x < 128; ++x)
1744 if(abs(x-64)>abs(y-64))
1746 if(x < 64)
1747 *ptr++ = 0xc000;
1748 else
1749 *ptr++ = 0x4000;
1751 else
1753 if(y < 64)
1754 *ptr++ = 0x0040;
1755 else
1756 *ptr++ = 0x00c0;
1761 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1764 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1767 /* Disable texture filtering */
1768 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1773 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1780 /* test the behavior of the texbem instruction
1781 * with normal 2D and projective 2D textures
1783 static void texbem_test(IDirect3DDevice9 *device)
1785 HRESULT hr;
1786 DWORD color;
1787 int i;
1789 static const DWORD pixel_shader_code[] = {
1790 0xffff0101, /* ps_1_1*/
1791 0x00000042, 0xb00f0000, /* tex t0*/
1792 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794 0x0000ffff
1796 static const DWORD double_texbem_code[] = {
1797 0xffff0103, /* ps_1_3 */
1798 0x00000042, 0xb00f0000, /* tex t0 */
1799 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1800 0x00000042, 0xb00f0002, /* tex t2 */
1801 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1802 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1803 0x0000ffff /* end */
1807 static const float quad[][7] = {
1808 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1813 static const float quad_proj[][9] = {
1814 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1815 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1816 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1817 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1820 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824 D3DDECL_END()
1826 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829 D3DDECL_END()
1830 } };
1832 /* use asymmetric matrix to test loading */
1833 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1835 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836 IDirect3DPixelShader9 *pixel_shader = NULL;
1837 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1838 D3DLOCKED_RECT locked_rect;
1840 generate_bumpmap_textures(device);
1842 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1848 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1854 for(i=0; i<2; i++)
1856 if(i)
1858 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1862 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1867 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1872 hr = IDirect3DDevice9_BeginScene(device);
1873 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1875 if(!i)
1876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877 else
1878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1881 hr = IDirect3DDevice9_EndScene(device);
1882 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1884 color = getPixelColor(device, 320-32, 240);
1885 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886 color = getPixelColor(device, 320+32, 240);
1887 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888 color = getPixelColor(device, 320, 240-32);
1889 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890 color = getPixelColor(device, 320, 240+32);
1891 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1896 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898 IDirect3DPixelShader9_Release(pixel_shader);
1900 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1905 /* clean up */
1906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1909 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1912 for(i=0; i<2; i++)
1914 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919 IDirect3DTexture9_Release(texture);
1922 /* Test double texbem */
1923 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1932 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1937 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1940 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1948 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex 0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952 static const DWORD pixel_data[] = {
1953 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1958 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1966 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968 for(i = 0; i < 8; i++) {
1969 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1971 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1975 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1988 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1989 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1990 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1999 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2000 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2001 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2027 hr = IDirect3DDevice9_BeginScene(device);
2028 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029 if(SUCCEEDED(hr)) {
2030 static const float double_quad[] = {
2031 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2032 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2033 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2034 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039 hr = IDirect3DDevice9_EndScene(device);
2040 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2042 color = getPixelColor(device, 320, 240);
2043 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2045 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2056 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2059 IDirect3DPixelShader9_Release(pixel_shader);
2060 IDirect3DTexture9_Release(texture);
2061 IDirect3DTexture9_Release(texture1);
2062 IDirect3DTexture9_Release(texture2);
2065 static void z_range_test(IDirect3DDevice9 *device)
2067 const struct vertex quad[] =
2069 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2070 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2071 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2072 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2074 const struct vertex quad2[] =
2076 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2077 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2078 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2079 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2082 const struct tvertex quad3[] =
2084 { 0, 240, 1.1f, 1.0, 0xffffff00},
2085 { 0, 480, 1.1f, 1.0, 0xffffff00},
2086 { 640, 240, -1.1f, 1.0, 0xffffff00},
2087 { 640, 480, -1.1f, 1.0, 0xffffff00},
2089 const struct tvertex quad4[] =
2091 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2092 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2093 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2094 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2096 HRESULT hr;
2097 DWORD color;
2098 IDirect3DVertexShader9 *shader;
2099 IDirect3DVertexDeclaration9 *decl;
2100 D3DCAPS9 caps;
2101 const DWORD shader_code[] = {
2102 0xfffe0101, /* vs_1_1 */
2103 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2104 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2105 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2106 0x0000ffff /* end */
2108 static const D3DVERTEXELEMENT9 decl_elements[] = {
2109 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110 D3DDECL_END()
2112 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113 * then call Present. Then clear the color buffer to make sure it has some defined content
2114 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115 * by the depth value.
2117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2135 hr = IDirect3DDevice9_BeginScene(device);
2136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137 if(hr == D3D_OK)
2139 /* Test the untransformed vertex path */
2140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2147 /* Test the transformed vertex path */
2148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2158 hr = IDirect3DDevice9_EndScene(device);
2159 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2162 /* Do not test the exact corner pixels, but go pretty close to them */
2164 /* Clipped because z > 1.0 */
2165 color = getPixelColor(device, 28, 238);
2166 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167 color = getPixelColor(device, 28, 241);
2168 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2170 /* Not clipped, > z buffer clear value(0.75) */
2171 color = getPixelColor(device, 31, 238);
2172 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173 color = getPixelColor(device, 31, 241);
2174 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175 color = getPixelColor(device, 100, 238);
2176 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177 color = getPixelColor(device, 100, 241);
2178 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2180 /* Not clipped, < z buffer clear value */
2181 color = getPixelColor(device, 104, 238);
2182 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183 color = getPixelColor(device, 104, 241);
2184 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185 color = getPixelColor(device, 318, 238);
2186 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187 color = getPixelColor(device, 318, 241);
2188 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2190 /* Clipped because z < 0.0 */
2191 color = getPixelColor(device, 321, 238);
2192 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193 color = getPixelColor(device, 321, 241);
2194 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2199 /* Test the shader path */
2200 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202 skip("Vertex shaders not supported\n");
2203 goto out;
2205 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2210 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2212 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214 IDirect3DDevice9_SetVertexShader(device, shader);
2215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2217 hr = IDirect3DDevice9_BeginScene(device);
2218 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219 if(hr == D3D_OK)
2221 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2232 hr = IDirect3DDevice9_EndScene(device);
2233 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2236 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238 IDirect3DDevice9_SetVertexShader(device, NULL);
2239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2241 IDirect3DVertexDeclaration9_Release(decl);
2242 IDirect3DVertexShader9_Release(shader);
2244 /* Z < 1.0 */
2245 color = getPixelColor(device, 28, 238);
2246 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2248 /* 1.0 < z < 0.75 */
2249 color = getPixelColor(device, 31, 238);
2250 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251 color = getPixelColor(device, 100, 238);
2252 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2254 /* 0.75 < z < 0.0 */
2255 color = getPixelColor(device, 104, 238);
2256 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257 color = getPixelColor(device, 318, 238);
2258 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2260 /* 0.0 < z */
2261 color = getPixelColor(device, 321, 238);
2262 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2264 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2267 out:
2268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2278 D3DSURFACE_DESC desc;
2279 D3DLOCKED_RECT l;
2280 HRESULT hr;
2281 unsigned int x, y;
2282 DWORD *mem;
2284 memset(&desc, 0, sizeof(desc));
2285 memset(&l, 0, sizeof(l));
2286 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290 if(FAILED(hr)) return;
2292 for(y = 0; y < desc.Height; y++)
2294 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2297 mem[x] = color;
2300 hr = IDirect3DSurface9_UnlockRect(surface);
2301 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2307 HRESULT hr;
2308 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315 IDirect3DSurface9 *orig_rt = NULL;
2316 IDirect3DSurface9 *backbuffer = NULL;
2317 DWORD color;
2319 RECT src_rect64 = {0, 0, 64, 64};
2320 RECT src_rect64_flipy = {0, 64, 64, 0};
2321 RECT dst_rect64 = {0, 0, 64, 64};
2322 RECT dst_rect64_flipy = {0, 64, 64, 0};
2324 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326 if(!orig_rt) {
2327 goto out;
2330 /* Create our temporary surfaces in system memory */
2331 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2336 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2344 /* Create render target surfaces */
2345 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2354 /* Create render target textures */
2355 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363 if (tex_rt32) {
2364 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2367 if (tex_rt64) {
2368 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2371 if (tex_rt_dest64) {
2372 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2375 if (tex_rt_dest64) {
2376 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2380 /* Create regular textures in D3DPOOL_DEFAULT */
2381 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387 if (tex32) {
2388 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2391 if (tex64) {
2392 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2395 if (tex_dest64) {
2396 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2400 /*********************************************************************
2401 * Tests for when the source parameter is an offscreen plain surface *
2402 *********************************************************************/
2404 /* Fill the offscreen 64x64 surface with green */
2405 if (surf_offscreen64)
2406 fill_surface(surf_offscreen64, 0xff00ff00);
2408 /* offscreenplain ==> offscreenplain, same size */
2409 if(surf_offscreen64 && surf_offscreen_dest64) {
2410 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2413 if (hr == D3D_OK) {
2414 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2418 /* Blit without scaling */
2419 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2422 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2426 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2431 /* offscreenplain ==> rendertarget texture, same size */
2432 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2436 /* We can't lock rendertarget textures, so copy to our temp surface first */
2437 if (hr == D3D_OK) {
2438 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2442 if (hr == D3D_OK) {
2443 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2447 /* Blit without scaling */
2448 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2451 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2455 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460 /* offscreenplain ==> rendertarget surface, same size */
2461 if(surf_offscreen64 && surf_rt_dest64) {
2462 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2465 if (hr == D3D_OK) {
2466 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2470 /* Blit without scaling */
2471 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2474 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2478 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2483 /* offscreenplain ==> texture, same size (should fail) */
2484 if(surf_offscreen64 && surf_tex_dest64) {
2485 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2489 /* Fill the smaller offscreen surface with red */
2490 fill_surface(surf_offscreen32, 0xffff0000);
2492 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493 if(surf_offscreen32 && surf_offscreen64) {
2494 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2498 /* offscreenplain ==> rendertarget texture, scaling */
2499 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2503 /* We can't lock rendertarget textures, so copy to our temp surface first */
2504 if (hr == D3D_OK) {
2505 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2509 if (hr == D3D_OK) {
2510 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2515 /* offscreenplain ==> rendertarget surface, scaling */
2516 if(surf_offscreen32 && surf_rt_dest64) {
2517 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2520 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2524 /* offscreenplain ==> texture, scaling (should fail) */
2525 if(surf_offscreen32 && surf_tex_dest64) {
2526 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2530 /************************************************************
2531 * Tests for when the source parameter is a regular texture *
2532 ************************************************************/
2534 /* Fill the surface of the regular texture with blue */
2535 if (surf_tex64 && surf_temp64) {
2536 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537 fill_surface(surf_temp64, 0xff0000ff);
2538 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2542 /* texture ==> offscreenplain, same size */
2543 if(surf_tex64 && surf_offscreen64) {
2544 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2548 /* texture ==> rendertarget texture, same size */
2549 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553 /* We can't lock rendertarget textures, so copy to our temp surface first */
2554 if (hr == D3D_OK) {
2555 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2559 if (hr == D3D_OK) {
2560 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2564 /* Blit without scaling */
2565 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2568 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2572 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2577 /* texture ==> rendertarget surface, same size */
2578 if(surf_tex64 && surf_rt_dest64) {
2579 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2582 if (hr == D3D_OK) {
2583 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2587 /* Blit without scaling */
2588 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2591 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2595 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2600 /* texture ==> texture, same size (should fail) */
2601 if(surf_tex64 && surf_tex_dest64) {
2602 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2606 /* Fill the surface of the smaller regular texture with red */
2607 if (surf_tex32 && surf_temp32) {
2608 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609 fill_surface(surf_temp32, 0xffff0000);
2610 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2614 /* texture ==> offscreenplain, scaling (should fail) */
2615 if(surf_tex32 && surf_offscreen64) {
2616 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2620 /* texture ==> rendertarget texture, scaling */
2621 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625 /* We can't lock rendertarget textures, so copy to our temp surface first */
2626 if (hr == D3D_OK) {
2627 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2631 if (hr == D3D_OK) {
2632 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2637 /* texture ==> rendertarget surface, scaling */
2638 if(surf_tex32 && surf_rt_dest64) {
2639 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2646 /* texture ==> texture, scaling (should fail) */
2647 if(surf_tex32 && surf_tex_dest64) {
2648 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2652 /*****************************************************************
2653 * Tests for when the source parameter is a rendertarget texture *
2654 *****************************************************************/
2656 /* Fill the surface of the rendertarget texture with white */
2657 if (surf_tex_rt64 && surf_temp64) {
2658 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659 fill_surface(surf_temp64, 0xffffffff);
2660 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2664 /* rendertarget texture ==> offscreenplain, same size */
2665 if(surf_tex_rt64 && surf_offscreen64) {
2666 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2670 /* rendertarget texture ==> rendertarget texture, same size */
2671 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2675 /* We can't lock rendertarget textures, so copy to our temp surface first */
2676 if (hr == D3D_OK) {
2677 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2681 if (hr == D3D_OK) {
2682 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2686 /* Blit without scaling */
2687 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2690 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2694 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2699 /* rendertarget texture ==> rendertarget surface, same size */
2700 if(surf_tex_rt64 && surf_rt_dest64) {
2701 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2704 if (hr == D3D_OK) {
2705 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2709 /* Blit without scaling */
2710 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2713 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2717 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2722 /* rendertarget texture ==> texture, same size (should fail) */
2723 if(surf_tex_rt64 && surf_tex_dest64) {
2724 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2728 /* Fill the surface of the smaller rendertarget texture with red */
2729 if (surf_tex_rt32 && surf_temp32) {
2730 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731 fill_surface(surf_temp32, 0xffff0000);
2732 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2736 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737 if(surf_tex_rt32 && surf_offscreen64) {
2738 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2742 /* rendertarget texture ==> rendertarget texture, scaling */
2743 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2747 /* We can't lock rendertarget textures, so copy to our temp surface first */
2748 if (hr == D3D_OK) {
2749 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2753 if (hr == D3D_OK) {
2754 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2759 /* rendertarget texture ==> rendertarget surface, scaling */
2760 if(surf_tex_rt32 && surf_rt_dest64) {
2761 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2768 /* rendertarget texture ==> texture, scaling (should fail) */
2769 if(surf_tex_rt32 && surf_tex_dest64) {
2770 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2774 /*****************************************************************
2775 * Tests for when the source parameter is a rendertarget surface *
2776 *****************************************************************/
2778 /* Fill the surface of the rendertarget surface with black */
2779 if (surf_rt64)
2780 fill_surface(surf_rt64, 0xff000000);
2782 /* rendertarget texture ==> offscreenplain, same size */
2783 if(surf_rt64 && surf_offscreen64) {
2784 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2788 /* rendertarget surface ==> rendertarget texture, same size */
2789 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793 /* We can't lock rendertarget textures, so copy to our temp surface first */
2794 if (hr == D3D_OK) {
2795 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2799 if (hr == D3D_OK) {
2800 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2804 /* Blit without scaling */
2805 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2812 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2817 /* rendertarget surface ==> rendertarget surface, same size */
2818 if(surf_rt64 && surf_rt_dest64) {
2819 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2822 if (hr == D3D_OK) {
2823 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2827 /* Blit without scaling */
2828 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2831 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2840 /* rendertarget surface ==> texture, same size (should fail) */
2841 if(surf_rt64 && surf_tex_dest64) {
2842 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2846 /* Fill the surface of the smaller rendertarget texture with red */
2847 if (surf_rt32)
2848 fill_surface(surf_rt32, 0xffff0000);
2850 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851 if(surf_rt32 && surf_offscreen64) {
2852 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2856 /* rendertarget surface ==> rendertarget texture, scaling */
2857 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861 /* We can't lock rendertarget textures, so copy to our temp surface first */
2862 if (hr == D3D_OK) {
2863 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2867 if (hr == D3D_OK) {
2868 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2873 /* rendertarget surface ==> rendertarget surface, scaling */
2874 if(surf_rt32 && surf_rt_dest64) {
2875 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2882 /* rendertarget surface ==> texture, scaling (should fail) */
2883 if(surf_rt32 && surf_tex_dest64) {
2884 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2888 /* backbuffer ==> surface tests (no scaling) */
2889 if(backbuffer && surf_tex_rt_dest640_480)
2891 RECT src_rect = {0, 0, 640, 480};
2892 RECT src_rect_flipy = {0, 480, 640, 0};
2893 RECT dst_rect = {0, 0, 640, 480};
2894 RECT dst_rect_flipy = {0, 480, 640, 0};
2896 /* Blit with NULL rectangles */
2897 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2900 /* Blit without scaling */
2901 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2913 /* TODO: Test format conversions */
2916 out:
2917 /* Clean up */
2918 if (backbuffer)
2919 IDirect3DSurface9_Release(backbuffer);
2920 if (surf_rt32)
2921 IDirect3DSurface9_Release(surf_rt32);
2922 if (surf_rt64)
2923 IDirect3DSurface9_Release(surf_rt64);
2924 if (surf_rt_dest64)
2925 IDirect3DSurface9_Release(surf_rt_dest64);
2926 if (surf_temp32)
2927 IDirect3DSurface9_Release(surf_temp32);
2928 if (surf_temp64)
2929 IDirect3DSurface9_Release(surf_temp64);
2930 if (surf_offscreen32)
2931 IDirect3DSurface9_Release(surf_offscreen32);
2932 if (surf_offscreen64)
2933 IDirect3DSurface9_Release(surf_offscreen64);
2934 if (surf_offscreen_dest64)
2935 IDirect3DSurface9_Release(surf_offscreen_dest64);
2937 if (tex_rt32) {
2938 if (surf_tex_rt32)
2939 IDirect3DSurface9_Release(surf_tex_rt32);
2940 IDirect3DTexture9_Release(tex_rt32);
2942 if (tex_rt64) {
2943 if (surf_tex_rt64)
2944 IDirect3DSurface9_Release(surf_tex_rt64);
2945 IDirect3DTexture9_Release(tex_rt64);
2947 if (tex_rt_dest64) {
2948 if (surf_tex_rt_dest64)
2949 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950 IDirect3DTexture9_Release(tex_rt_dest64);
2952 if (tex_rt_dest640_480) {
2953 if (surf_tex_rt_dest640_480)
2954 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955 IDirect3DTexture9_Release(tex_rt_dest640_480);
2957 if (tex32) {
2958 if (surf_tex32)
2959 IDirect3DSurface9_Release(surf_tex32);
2960 IDirect3DTexture9_Release(tex32);
2962 if (tex64) {
2963 if (surf_tex64)
2964 IDirect3DSurface9_Release(surf_tex64);
2965 IDirect3DTexture9_Release(tex64);
2967 if (tex_dest64) {
2968 if (surf_tex_dest64)
2969 IDirect3DSurface9_Release(surf_tex_dest64);
2970 IDirect3DTexture9_Release(tex_dest64);
2973 if (orig_rt) {
2974 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976 IDirect3DSurface9_Release(orig_rt);
2980 static void maxmip_test(IDirect3DDevice9 *device)
2982 IDirect3DTexture9 *texture = NULL;
2983 IDirect3DSurface9 *surface = NULL;
2984 HRESULT hr;
2985 DWORD color;
2986 static const struct
2988 struct
2990 float x, y, z;
2991 float s, t;
2993 v[4];
2995 quads[] =
2998 {-1.0, -1.0, 0.0, 0.0, 0.0},
2999 {-1.0, 0.0, 0.0, 0.0, 1.0},
3000 { 0.0, -1.0, 0.0, 1.0, 0.0},
3001 { 0.0, 0.0, 0.0, 1.0, 1.0},
3004 { 0.0, -1.0, 0.0, 0.0, 0.0},
3005 { 0.0, 0.0, 0.0, 0.0, 1.0},
3006 { 1.0, -1.0, 0.0, 1.0, 0.0},
3007 { 1.0, 0.0, 0.0, 1.0, 1.0},
3010 { 0.0, 0.0, 0.0, 0.0, 0.0},
3011 { 0.0, 1.0, 0.0, 0.0, 1.0},
3012 { 1.0, 0.0, 0.0, 1.0, 0.0},
3013 { 1.0, 1.0, 0.0, 1.0, 1.0},
3016 {-1.0, 0.0, 0.0, 0.0, 0.0},
3017 {-1.0, 1.0, 0.0, 0.0, 1.0},
3018 { 0.0, 0.0, 0.0, 1.0, 0.0},
3019 { 0.0, 1.0, 0.0, 1.0, 1.0},
3023 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3024 &texture, NULL);
3025 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3026 if(!texture)
3028 skip("Failed to create test texture\n");
3029 return;
3032 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3033 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3034 fill_surface(surface, 0xffff0000);
3035 IDirect3DSurface9_Release(surface);
3036 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3037 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3038 fill_surface(surface, 0xff00ff00);
3039 IDirect3DSurface9_Release(surface);
3040 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3041 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3042 fill_surface(surface, 0xff0000ff);
3043 IDirect3DSurface9_Release(surface);
3045 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3047 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3048 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3050 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3051 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3053 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3054 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3056 hr = IDirect3DDevice9_BeginScene(device);
3057 if(SUCCEEDED(hr))
3059 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3060 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3064 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3065 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3069 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3070 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3072 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3074 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3075 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3076 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3077 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3078 hr = IDirect3DDevice9_EndScene(device);
3079 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3082 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3083 color = getPixelColor(device, 160, 360);
3084 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3085 color = getPixelColor(device, 480, 360);
3086 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3087 color = getPixelColor(device, 480, 120);
3088 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3089 color = getPixelColor(device, 160, 120);
3090 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3091 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3092 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3094 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3095 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3098 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3100 hr = IDirect3DDevice9_BeginScene(device);
3101 if(SUCCEEDED(hr))
3103 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3104 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3108 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3109 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3110 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3111 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3113 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3114 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3115 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3116 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3118 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3119 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3120 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3121 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3122 hr = IDirect3DDevice9_EndScene(device);
3123 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3126 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3127 * level 3 (> levels in texture) samples from the highest level in the
3128 * texture (level 2). */
3129 color = getPixelColor(device, 160, 360);
3130 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3131 color = getPixelColor(device, 480, 360);
3132 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3133 color = getPixelColor(device, 480, 120);
3134 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3135 color = getPixelColor(device, 160, 120);
3136 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3138 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3140 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3141 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3143 hr = IDirect3DDevice9_BeginScene(device);
3144 if(SUCCEEDED(hr))
3146 DWORD ret;
3148 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3149 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3150 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3152 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153 ret = IDirect3DTexture9_SetLOD(texture, 1);
3154 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3156 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3158 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3160 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3162 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163 ret = IDirect3DTexture9_SetLOD(texture, 2);
3164 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3166 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3168 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3169 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3170 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3171 ret = IDirect3DTexture9_SetLOD(texture, 1);
3172 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3174 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3176 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3177 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3178 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3179 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3180 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3181 ret = IDirect3DTexture9_SetLOD(texture, 1);
3182 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3184 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3185 hr = IDirect3DDevice9_EndScene(device);
3188 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3189 * level 3 (> levels in texture) samples from the highest level in the
3190 * texture (level 2). */
3191 color = getPixelColor(device, 160, 360);
3192 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3193 color = getPixelColor(device, 480, 360);
3194 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3195 color = getPixelColor(device, 480, 120);
3196 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3197 color = getPixelColor(device, 160, 120);
3198 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3201 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3203 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3204 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3205 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3206 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3207 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3208 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3209 IDirect3DTexture9_Release(texture);
3212 static void release_buffer_test(IDirect3DDevice9 *device)
3214 IDirect3DVertexBuffer9 *vb = NULL;
3215 IDirect3DIndexBuffer9 *ib = NULL;
3216 HRESULT hr;
3217 BYTE *data;
3218 LONG ref;
3220 static const struct vertex quad[] = {
3221 {-1.0, -1.0, 0.1, 0xffff0000},
3222 {-1.0, 1.0, 0.1, 0xffff0000},
3223 { 1.0, 1.0, 0.1, 0xffff0000},
3225 {-1.0, -1.0, 0.1, 0xff00ff00},
3226 {-1.0, 1.0, 0.1, 0xff00ff00},
3227 { 1.0, 1.0, 0.1, 0xff00ff00}
3229 short indices[] = {3, 4, 5};
3231 /* Index and vertex buffers should always be creatable */
3232 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3233 D3DPOOL_MANAGED, &vb, NULL);
3234 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3235 if(!vb) {
3236 skip("Failed to create a vertex buffer\n");
3237 return;
3239 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3241 if(!ib) {
3242 skip("Failed to create an index buffer\n");
3243 return;
3246 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3247 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3248 memcpy(data, quad, sizeof(quad));
3249 hr = IDirect3DVertexBuffer9_Unlock(vb);
3250 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3252 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3253 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3254 memcpy(data, indices, sizeof(indices));
3255 hr = IDirect3DIndexBuffer9_Unlock(ib);
3256 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3258 hr = IDirect3DDevice9_SetIndices(device, ib);
3259 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3260 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3261 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3262 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3265 /* Now destroy the bound index buffer and draw again */
3266 ref = IDirect3DIndexBuffer9_Release(ib);
3267 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3269 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3270 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3272 hr = IDirect3DDevice9_BeginScene(device);
3273 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3274 if(SUCCEEDED(hr))
3276 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3277 * making assumptions about the indices or vertices
3279 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3280 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3281 hr = IDirect3DDevice9_EndScene(device);
3282 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3285 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3286 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3288 hr = IDirect3DDevice9_SetIndices(device, NULL);
3289 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3290 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3291 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3293 /* Index buffer was already destroyed as part of the test */
3294 IDirect3DVertexBuffer9_Release(vb);
3297 static void float_texture_test(IDirect3DDevice9 *device)
3299 IDirect3D9 *d3d = NULL;
3300 HRESULT hr;
3301 IDirect3DTexture9 *texture = NULL;
3302 D3DLOCKED_RECT lr;
3303 float *data;
3304 DWORD color;
3305 float quad[] = {
3306 -1.0, -1.0, 0.1, 0.0, 0.0,
3307 -1.0, 1.0, 0.1, 0.0, 1.0,
3308 1.0, -1.0, 0.1, 1.0, 0.0,
3309 1.0, 1.0, 0.1, 1.0, 1.0,
3312 memset(&lr, 0, sizeof(lr));
3313 IDirect3DDevice9_GetDirect3D(device, &d3d);
3314 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3315 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3316 skip("D3DFMT_R32F textures not supported\n");
3317 goto out;
3320 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3321 D3DPOOL_MANAGED, &texture, NULL);
3322 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3323 if(!texture) {
3324 skip("Failed to create R32F texture\n");
3325 goto out;
3328 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3329 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3330 data = lr.pBits;
3331 *data = 0.0;
3332 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3333 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3335 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3336 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3338 hr = IDirect3DDevice9_BeginScene(device);
3339 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3340 if(SUCCEEDED(hr))
3342 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3343 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3346 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3348 hr = IDirect3DDevice9_EndScene(device);
3349 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3351 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3352 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3354 color = getPixelColor(device, 240, 320);
3355 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3357 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3358 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3360 out:
3361 if(texture) IDirect3DTexture9_Release(texture);
3362 IDirect3D9_Release(d3d);
3365 static void g16r16_texture_test(IDirect3DDevice9 *device)
3367 IDirect3D9 *d3d = NULL;
3368 HRESULT hr;
3369 IDirect3DTexture9 *texture = NULL;
3370 D3DLOCKED_RECT lr;
3371 DWORD *data;
3372 DWORD color;
3373 float quad[] = {
3374 -1.0, -1.0, 0.1, 0.0, 0.0,
3375 -1.0, 1.0, 0.1, 0.0, 1.0,
3376 1.0, -1.0, 0.1, 1.0, 0.0,
3377 1.0, 1.0, 0.1, 1.0, 1.0,
3380 memset(&lr, 0, sizeof(lr));
3381 IDirect3DDevice9_GetDirect3D(device, &d3d);
3382 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3383 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3384 skip("D3DFMT_G16R16 textures not supported\n");
3385 goto out;
3388 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3389 D3DPOOL_MANAGED, &texture, NULL);
3390 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3391 if(!texture) {
3392 skip("Failed to create D3DFMT_G16R16 texture\n");
3393 goto out;
3396 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3397 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3398 data = lr.pBits;
3399 *data = 0x0f00f000;
3400 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3401 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3403 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3404 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3406 hr = IDirect3DDevice9_BeginScene(device);
3407 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3408 if(SUCCEEDED(hr))
3410 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3411 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3414 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3416 hr = IDirect3DDevice9_EndScene(device);
3417 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3419 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3422 color = getPixelColor(device, 240, 320);
3423 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3424 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3426 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3427 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3429 out:
3430 if(texture) IDirect3DTexture9_Release(texture);
3431 IDirect3D9_Release(d3d);
3434 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3436 HRESULT hr;
3437 IDirect3D9 *d3d;
3438 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3439 D3DCAPS9 caps;
3440 IDirect3DTexture9 *texture = NULL;
3441 IDirect3DVolumeTexture9 *volume = NULL;
3442 unsigned int x, y, z;
3443 D3DLOCKED_RECT lr;
3444 D3DLOCKED_BOX lb;
3445 DWORD color;
3446 UINT w, h;
3447 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3448 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3449 0.0, 1.0, 0.0, 0.0,
3450 0.0, 0.0, 1.0, 0.0,
3451 0.0, 0.0, 0.0, 1.0};
3452 static const D3DVERTEXELEMENT9 decl_elements[] = {
3453 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3454 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3455 D3DDECL_END()
3457 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3458 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3459 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3460 D3DDECL_END()
3462 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3463 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3464 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3465 D3DDECL_END()
3467 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3468 0x00, 0xff, 0x00, 0x00,
3469 0x00, 0x00, 0x00, 0x00,
3470 0x00, 0x00, 0x00, 0x00};
3472 memset(&lr, 0, sizeof(lr));
3473 memset(&lb, 0, sizeof(lb));
3474 IDirect3DDevice9_GetDirect3D(device, &d3d);
3475 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3476 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3477 fmt = D3DFMT_A16B16G16R16;
3479 IDirect3D9_Release(d3d);
3481 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3482 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3483 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3484 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3485 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3486 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3487 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3489 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3490 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3491 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3492 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3493 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3494 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3495 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3496 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3497 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3498 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3499 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3500 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3502 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3504 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3506 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3507 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3508 w = min(1024, caps.MaxTextureWidth);
3509 h = min(1024, caps.MaxTextureHeight);
3510 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3511 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3512 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3513 if(!texture) {
3514 skip("Failed to create the test texture\n");
3515 return;
3518 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3519 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3520 * 1.0 in red and green for the x and y coords
3522 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3523 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3524 for(y = 0; y < h; y++) {
3525 for(x = 0; x < w; x++) {
3526 double r_f = (double) y / (double) h;
3527 double g_f = (double) x / (double) w;
3528 if(fmt == D3DFMT_A16B16G16R16) {
3529 unsigned short r, g;
3530 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3531 r = (unsigned short) (r_f * 65536.0);
3532 g = (unsigned short) (g_f * 65536.0);
3533 dst[0] = r;
3534 dst[1] = g;
3535 dst[2] = 0;
3536 dst[3] = 65535;
3537 } else {
3538 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3539 unsigned char r = (unsigned char) (r_f * 255.0);
3540 unsigned char g = (unsigned char) (g_f * 255.0);
3541 dst[0] = 0;
3542 dst[1] = g;
3543 dst[2] = r;
3544 dst[3] = 255;
3548 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3549 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3550 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3551 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3553 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3554 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3555 hr = IDirect3DDevice9_BeginScene(device);
3556 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3557 if(SUCCEEDED(hr))
3559 float quad1[] = {
3560 -1.0, -1.0, 0.1, 1.0, 1.0,
3561 -1.0, 0.0, 0.1, 1.0, 1.0,
3562 0.0, -1.0, 0.1, 1.0, 1.0,
3563 0.0, 0.0, 0.1, 1.0, 1.0,
3565 float quad2[] = {
3566 -1.0, 0.0, 0.1, 1.0, 1.0,
3567 -1.0, 1.0, 0.1, 1.0, 1.0,
3568 0.0, 0.0, 0.1, 1.0, 1.0,
3569 0.0, 1.0, 0.1, 1.0, 1.0,
3571 float quad3[] = {
3572 0.0, 0.0, 0.1, 0.5, 0.5,
3573 0.0, 1.0, 0.1, 0.5, 0.5,
3574 1.0, 0.0, 0.1, 0.5, 0.5,
3575 1.0, 1.0, 0.1, 0.5, 0.5,
3577 float quad4[] = {
3578 320, 480, 0.1, 1.0, 0.0, 1.0,
3579 320, 240, 0.1, 1.0, 0.0, 1.0,
3580 640, 480, 0.1, 1.0, 0.0, 1.0,
3581 640, 240, 0.1, 1.0, 0.0, 1.0,
3583 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3584 0.0, 0.0, 0.0, 0.0,
3585 0.0, 0.0, 0.0, 0.0,
3586 0.0, 0.0, 0.0, 0.0};
3588 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3589 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3590 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3592 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3594 /* What happens with transforms enabled? */
3595 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3596 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3597 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3598 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3600 /* What happens if 4 coords are used, but only 2 given ?*/
3601 mat[8] = 1.0;
3602 mat[13] = 1.0;
3603 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3604 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3605 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3606 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3607 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3608 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3610 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3611 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3612 * due to the coords in the vertices. (turns out red, indeed)
3614 memset(mat, 0, sizeof(mat));
3615 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3616 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3617 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3618 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3619 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3622 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3624 hr = IDirect3DDevice9_EndScene(device);
3625 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3627 color = getPixelColor(device, 160, 360);
3628 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3629 color = getPixelColor(device, 160, 120);
3630 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3631 color = getPixelColor(device, 480, 120);
3632 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3633 color = getPixelColor(device, 480, 360);
3634 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3635 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3636 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3639 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3641 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3642 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3643 hr = IDirect3DDevice9_BeginScene(device);
3644 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3645 if(SUCCEEDED(hr))
3647 float quad1[] = {
3648 -1.0, -1.0, 0.1, 0.8, 0.2,
3649 -1.0, 0.0, 0.1, 0.8, 0.2,
3650 0.0, -1.0, 0.1, 0.8, 0.2,
3651 0.0, 0.0, 0.1, 0.8, 0.2,
3653 float quad2[] = {
3654 -1.0, 0.0, 0.1, 0.5, 1.0,
3655 -1.0, 1.0, 0.1, 0.5, 1.0,
3656 0.0, 0.0, 0.1, 0.5, 1.0,
3657 0.0, 1.0, 0.1, 0.5, 1.0,
3659 float quad3[] = {
3660 0.0, 0.0, 0.1, 0.5, 1.0,
3661 0.0, 1.0, 0.1, 0.5, 1.0,
3662 1.0, 0.0, 0.1, 0.5, 1.0,
3663 1.0, 1.0, 0.1, 0.5, 1.0,
3665 float quad4[] = {
3666 0.0, -1.0, 0.1, 0.8, 0.2,
3667 0.0, 0.0, 0.1, 0.8, 0.2,
3668 1.0, -1.0, 0.1, 0.8, 0.2,
3669 1.0, 0.0, 0.1, 0.8, 0.2,
3671 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3672 0.0, 0.0, 0.0, 0.0,
3673 0.0, 1.0, 0.0, 0.0,
3674 0.0, 0.0, 0.0, 0.0};
3676 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3678 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3679 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3680 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3681 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3684 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3686 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3687 * it behaves like COUNT2 because normal textures require 2 coords
3689 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3690 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3692 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3694 /* Just to be sure, the same as quad2 above */
3695 memset(mat, 0, sizeof(mat));
3696 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3697 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3698 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3699 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3701 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3703 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3704 * used? And what happens to the first?
3706 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3707 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3709 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3711 hr = IDirect3DDevice9_EndScene(device);
3712 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3714 color = getPixelColor(device, 160, 360);
3715 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3716 color = getPixelColor(device, 160, 120);
3717 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3718 color = getPixelColor(device, 480, 120);
3719 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3720 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3721 color = getPixelColor(device, 480, 360);
3722 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3723 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3724 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3725 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3727 IDirect3DTexture9_Release(texture);
3729 /* Test projected textures, without any fancy matrices */
3730 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3732 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3733 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3734 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3735 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3736 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3737 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3739 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3740 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3741 for(x = 0; x < 4; x++) {
3742 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3744 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3745 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3746 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3747 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3749 hr = IDirect3DDevice9_BeginScene(device);
3750 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3751 if(SUCCEEDED(hr))
3753 const float proj_quads[] = {
3754 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3755 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3756 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3757 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3758 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3759 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3760 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3761 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3764 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3765 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3767 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3769 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3770 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3771 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3772 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3774 hr = IDirect3DDevice9_EndScene(device);
3775 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3778 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3779 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3780 IDirect3DTexture9_Release(texture);
3782 color = getPixelColor(device, 158, 118);
3783 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3784 color = getPixelColor(device, 162, 118);
3785 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3786 color = getPixelColor(device, 158, 122);
3787 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3788 color = getPixelColor(device, 162, 122);
3789 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3791 color = getPixelColor(device, 158, 178);
3792 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3793 color = getPixelColor(device, 162, 178);
3794 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3795 color = getPixelColor(device, 158, 182);
3796 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3797 color = getPixelColor(device, 162, 182);
3798 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3800 color = getPixelColor(device, 318, 118);
3801 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3802 color = getPixelColor(device, 322, 118);
3803 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3804 color = getPixelColor(device, 318, 122);
3805 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3806 color = getPixelColor(device, 322, 122);
3807 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3809 color = getPixelColor(device, 318, 178);
3810 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3811 color = getPixelColor(device, 322, 178);
3812 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3813 color = getPixelColor(device, 318, 182);
3814 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3815 color = getPixelColor(device, 322, 182);
3816 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3818 color = getPixelColor(device, 238, 298);
3819 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3820 color = getPixelColor(device, 242, 298);
3821 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3822 color = getPixelColor(device, 238, 302);
3823 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3824 color = getPixelColor(device, 242, 302);
3825 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3827 color = getPixelColor(device, 238, 388);
3828 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3829 color = getPixelColor(device, 242, 388);
3830 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3831 color = getPixelColor(device, 238, 392);
3832 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3833 color = getPixelColor(device, 242, 392);
3834 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3836 color = getPixelColor(device, 478, 298);
3837 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3838 color = getPixelColor(device, 482, 298);
3839 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3840 color = getPixelColor(device, 478, 302);
3841 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3842 color = getPixelColor(device, 482, 302);
3843 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3845 color = getPixelColor(device, 478, 388);
3846 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3847 color = getPixelColor(device, 482, 388);
3848 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3849 color = getPixelColor(device, 478, 392);
3850 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3851 color = getPixelColor(device, 482, 392);
3852 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3854 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3855 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3858 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3859 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3860 * Thus watch out if sampling from texels between 0 and 1.
3862 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3863 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3864 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3865 if(!volume) {
3866 skip("Failed to create a volume texture\n");
3867 goto out;
3870 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3871 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3872 for(z = 0; z < 32; z++) {
3873 for(y = 0; y < 32; y++) {
3874 for(x = 0; x < 32; x++) {
3875 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3876 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3877 float r_f = (float) x / 31.0;
3878 float g_f = (float) y / 31.0;
3879 float b_f = (float) z / 31.0;
3881 if(fmt == D3DFMT_A16B16G16R16) {
3882 unsigned short *mem_s = mem;
3883 mem_s[0] = r_f * 65535.0;
3884 mem_s[1] = g_f * 65535.0;
3885 mem_s[2] = b_f * 65535.0;
3886 mem_s[3] = 65535;
3887 } else {
3888 unsigned char *mem_c = mem;
3889 mem_c[0] = b_f * 255.0;
3890 mem_c[1] = g_f * 255.0;
3891 mem_c[2] = r_f * 255.0;
3892 mem_c[3] = 255;
3897 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3898 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3900 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3901 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3903 hr = IDirect3DDevice9_BeginScene(device);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3905 if(SUCCEEDED(hr))
3907 float quad1[] = {
3908 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3909 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3910 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3911 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3913 float quad2[] = {
3914 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3915 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3916 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3917 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3919 float quad3[] = {
3920 0.0, 0.0, 0.1, 0.0, 0.0,
3921 0.0, 1.0, 0.1, 0.0, 0.0,
3922 1.0, 0.0, 0.1, 0.0, 0.0,
3923 1.0, 1.0, 0.1, 0.0, 0.0
3925 float quad4[] = {
3926 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3927 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3928 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3929 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3931 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3932 0.0, 0.0, 1.0, 0.0,
3933 0.0, 1.0, 0.0, 0.0,
3934 0.0, 0.0, 0.0, 1.0};
3935 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3936 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3938 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3939 * values
3941 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3942 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3946 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3948 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3949 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3950 * otherwise the w will be missing(blue).
3951 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3952 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3954 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3955 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3957 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3959 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3960 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3961 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3962 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3963 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3964 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3965 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3967 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3969 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3970 * disable. ATI extends it up to the amount of values needed for the volume texture
3972 memset(mat, 0, sizeof(mat));
3973 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3974 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3975 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3976 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3977 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3978 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3980 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3982 hr = IDirect3DDevice9_EndScene(device);
3983 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3986 color = getPixelColor(device, 160, 360);
3987 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3988 color = getPixelColor(device, 160, 120);
3989 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3990 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3991 color = getPixelColor(device, 480, 120);
3992 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3993 color = getPixelColor(device, 480, 360);
3994 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3997 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4001 hr = IDirect3DDevice9_BeginScene(device);
4002 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4003 if(SUCCEEDED(hr))
4005 float quad1[] = {
4006 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4007 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4008 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4009 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4011 float quad2[] = {
4012 -1.0, 0.0, 0.1,
4013 -1.0, 1.0, 0.1,
4014 0.0, 0.0, 0.1,
4015 0.0, 1.0, 0.1,
4017 float quad3[] = {
4018 0.0, 0.0, 0.1, 1.0,
4019 0.0, 1.0, 0.1, 1.0,
4020 1.0, 0.0, 0.1, 1.0,
4021 1.0, 1.0, 0.1, 1.0
4023 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4024 0.0, 0.0, 0.0, 0.0,
4025 0.0, 0.0, 0.0, 0.0,
4026 0.0, 1.0, 0.0, 0.0};
4027 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4028 1.0, 0.0, 0.0, 0.0,
4029 0.0, 1.0, 0.0, 0.0,
4030 0.0, 0.0, 1.0, 0.0};
4031 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4034 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4035 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4036 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4037 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4038 * 4th *input* coordinate.
4040 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4041 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4042 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4043 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4045 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4047 /* None passed */
4048 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4049 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4050 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4051 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4052 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4053 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4055 /* 4 used, 1 passed */
4056 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4058 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4059 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4061 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4063 hr = IDirect3DDevice9_EndScene(device);
4064 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4066 color = getPixelColor(device, 160, 360);
4067 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4068 color = getPixelColor(device, 160, 120);
4069 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4070 color = getPixelColor(device, 480, 120);
4071 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4072 /* Quad4: unused */
4074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4075 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4077 IDirect3DVolumeTexture9_Release(volume);
4079 out:
4080 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4081 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4082 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4083 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4084 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4085 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4086 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4087 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4088 IDirect3DVertexDeclaration9_Release(decl);
4089 IDirect3DVertexDeclaration9_Release(decl2);
4090 IDirect3DVertexDeclaration9_Release(decl3);
4093 static void texdepth_test(IDirect3DDevice9 *device)
4095 IDirect3DPixelShader9 *shader;
4096 HRESULT hr;
4097 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4098 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4099 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4100 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4101 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4102 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4103 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4104 DWORD shader_code[] = {
4105 0xffff0104, /* ps_1_4 */
4106 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4107 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4108 0x0000fffd, /* phase */
4109 0x00000057, 0x800f0005, /* texdepth r5 */
4110 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4111 0x0000ffff /* end */
4113 DWORD color;
4114 float vertex[] = {
4115 -1.0, -1.0, 0.0,
4116 1.0, -1.0, 1.0,
4117 -1.0, 1.0, 0.0,
4118 1.0, 1.0, 1.0
4121 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4122 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4125 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4132 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4133 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4135 /* Fill the depth buffer with a gradient */
4136 hr = IDirect3DDevice9_BeginScene(device);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4138 if(SUCCEEDED(hr))
4140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4141 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4142 hr = IDirect3DDevice9_EndScene(device);
4143 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4146 /* Now perform the actual tests. Same geometry, but with the shader */
4147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4148 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4151 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4154 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4155 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF 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, 3 * sizeof(float));
4161 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4163 hr = IDirect3DDevice9_EndScene(device);
4164 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4167 color = getPixelColor(device, 158, 240);
4168 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4169 color = getPixelColor(device, 162, 240);
4170 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4173 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4175 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4176 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4178 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4179 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4180 hr = IDirect3DDevice9_BeginScene(device);
4181 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4182 if(SUCCEEDED(hr))
4184 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4185 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4187 hr = IDirect3DDevice9_EndScene(device);
4188 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4191 color = getPixelColor(device, 318, 240);
4192 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4193 color = getPixelColor(device, 322, 240);
4194 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4197 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4199 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4200 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4202 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4203 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4204 hr = IDirect3DDevice9_BeginScene(device);
4205 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4206 if(SUCCEEDED(hr))
4208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4209 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4211 hr = IDirect3DDevice9_EndScene(device);
4212 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4215 color = getPixelColor(device, 1, 240);
4216 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4218 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4222 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4224 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4225 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4226 hr = IDirect3DDevice9_BeginScene(device);
4227 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4228 if(SUCCEEDED(hr))
4230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4231 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4233 hr = IDirect3DDevice9_EndScene(device);
4234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4236 color = getPixelColor(device, 318, 240);
4237 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4238 color = getPixelColor(device, 322, 240);
4239 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4241 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4242 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4244 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4245 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4247 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4248 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4249 hr = IDirect3DDevice9_BeginScene(device);
4250 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4251 if(SUCCEEDED(hr))
4253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4254 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4256 hr = IDirect3DDevice9_EndScene(device);
4257 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4260 color = getPixelColor(device, 1, 240);
4261 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4264 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4267 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4269 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4271 hr = IDirect3DDevice9_BeginScene(device);
4272 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4273 if(SUCCEEDED(hr))
4275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4276 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4278 hr = IDirect3DDevice9_EndScene(device);
4279 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4282 color = getPixelColor(device, 638, 240);
4283 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4285 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4286 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4289 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4291 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4292 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4293 hr = IDirect3DDevice9_BeginScene(device);
4294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4295 if(SUCCEEDED(hr))
4297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4298 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4300 hr = IDirect3DDevice9_EndScene(device);
4301 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4304 color = getPixelColor(device, 638, 240);
4305 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4307 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4308 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4310 /* Cleanup */
4311 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4312 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4313 IDirect3DPixelShader9_Release(shader);
4315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4316 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4318 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4321 static void texkill_test(IDirect3DDevice9 *device)
4323 IDirect3DPixelShader9 *shader;
4324 HRESULT hr;
4325 DWORD color;
4327 const float vertex[] = {
4328 /* bottom top right left */
4329 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4330 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4331 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4332 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4335 DWORD shader_code_11[] = {
4336 0xffff0101, /* ps_1_1 */
4337 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4338 0x00000041, 0xb00f0000, /* texkill t0 */
4339 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4340 0x0000ffff /* end */
4342 DWORD shader_code_20[] = {
4343 0xffff0200, /* ps_2_0 */
4344 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4345 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4346 0x01000041, 0xb00f0000, /* texkill t0 */
4347 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4348 0x0000ffff /* end */
4351 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4352 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4353 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4354 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4356 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4357 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4358 hr = IDirect3DDevice9_BeginScene(device);
4359 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4360 if(SUCCEEDED(hr))
4362 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4363 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4365 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4366 hr = IDirect3DDevice9_EndScene(device);
4367 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4369 color = getPixelColor(device, 63, 46);
4370 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4371 color = getPixelColor(device, 66, 46);
4372 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4373 color = getPixelColor(device, 63, 49);
4374 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4375 color = getPixelColor(device, 66, 49);
4376 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4378 color = getPixelColor(device, 578, 46);
4379 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4380 color = getPixelColor(device, 575, 46);
4381 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4382 color = getPixelColor(device, 578, 49);
4383 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4384 color = getPixelColor(device, 575, 49);
4385 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4387 color = getPixelColor(device, 63, 430);
4388 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4389 color = getPixelColor(device, 63, 433);
4390 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4391 color = getPixelColor(device, 66, 433);
4392 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4393 color = getPixelColor(device, 66, 430);
4394 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4396 color = getPixelColor(device, 578, 430);
4397 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4398 color = getPixelColor(device, 578, 433);
4399 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4400 color = getPixelColor(device, 575, 433);
4401 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4402 color = getPixelColor(device, 575, 430);
4403 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4405 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4406 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4408 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4409 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4410 IDirect3DPixelShader9_Release(shader);
4412 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4413 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4414 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4415 if(FAILED(hr)) {
4416 skip("Failed to create 2.0 test shader, most likely not supported\n");
4417 return;
4420 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4421 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4422 hr = IDirect3DDevice9_BeginScene(device);
4423 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4424 if(SUCCEEDED(hr))
4426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4427 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4428 hr = IDirect3DDevice9_EndScene(device);
4429 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4432 color = getPixelColor(device, 63, 46);
4433 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4434 color = getPixelColor(device, 66, 46);
4435 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4436 color = getPixelColor(device, 63, 49);
4437 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4438 color = getPixelColor(device, 66, 49);
4439 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4441 color = getPixelColor(device, 578, 46);
4442 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4443 color = getPixelColor(device, 575, 46);
4444 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4445 color = getPixelColor(device, 578, 49);
4446 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4447 color = getPixelColor(device, 575, 49);
4448 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4450 color = getPixelColor(device, 63, 430);
4451 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4452 color = getPixelColor(device, 63, 433);
4453 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4454 color = getPixelColor(device, 66, 433);
4455 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4456 color = getPixelColor(device, 66, 430);
4457 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4459 color = getPixelColor(device, 578, 430);
4460 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4461 color = getPixelColor(device, 578, 433);
4462 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4463 color = getPixelColor(device, 575, 433);
4464 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4465 color = getPixelColor(device, 575, 430);
4466 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4469 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4471 /* Cleanup */
4472 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4473 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4474 IDirect3DPixelShader9_Release(shader);
4477 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4479 IDirect3D9 *d3d9;
4480 HRESULT hr;
4481 IDirect3DTexture9 *texture;
4482 IDirect3DPixelShader9 *shader;
4483 IDirect3DPixelShader9 *shader2;
4484 D3DLOCKED_RECT lr;
4485 DWORD color;
4486 DWORD shader_code[] = {
4487 0xffff0101, /* ps_1_1 */
4488 0x00000042, 0xb00f0000, /* tex t0 */
4489 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4490 0x0000ffff /* end */
4492 DWORD shader_code2[] = {
4493 0xffff0101, /* ps_1_1 */
4494 0x00000042, 0xb00f0000, /* tex t0 */
4495 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4496 0x0000ffff /* end */
4499 float quad[] = {
4500 -1.0, -1.0, 0.1, 0.5, 0.5,
4501 1.0, -1.0, 0.1, 0.5, 0.5,
4502 -1.0, 1.0, 0.1, 0.5, 0.5,
4503 1.0, 1.0, 0.1, 0.5, 0.5,
4506 memset(&lr, 0, sizeof(lr));
4507 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4508 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4509 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4510 IDirect3D9_Release(d3d9);
4511 if(FAILED(hr)) {
4512 skip("No D3DFMT_X8L8V8U8 support\n");
4513 return;
4516 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4517 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4519 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4520 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4521 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4522 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4523 *((DWORD *) lr.pBits) = 0x11ca3141;
4524 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4525 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4527 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4528 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4529 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4534 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4535 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4536 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4537 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4539 hr = IDirect3DDevice9_BeginScene(device);
4540 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4541 if(SUCCEEDED(hr))
4543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4544 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4546 hr = IDirect3DDevice9_EndScene(device);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4549 color = getPixelColor(device, 578, 430);
4550 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4551 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4552 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4553 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4555 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4556 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4557 hr = IDirect3DDevice9_BeginScene(device);
4558 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4559 if(SUCCEEDED(hr))
4561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4562 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4564 hr = IDirect3DDevice9_EndScene(device);
4565 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4567 color = getPixelColor(device, 578, 430);
4568 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4569 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4572 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4573 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4574 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4576 IDirect3DPixelShader9_Release(shader);
4577 IDirect3DPixelShader9_Release(shader2);
4578 IDirect3DTexture9_Release(texture);
4581 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4583 HRESULT hr;
4584 IDirect3D9 *d3d;
4585 IDirect3DTexture9 *texture = NULL;
4586 IDirect3DSurface9 *surface;
4587 DWORD color;
4588 const RECT r1 = {256, 256, 512, 512};
4589 const RECT r2 = {512, 256, 768, 512};
4590 const RECT r3 = {256, 512, 512, 768};
4591 const RECT r4 = {512, 512, 768, 768};
4592 unsigned int x, y;
4593 D3DLOCKED_RECT lr;
4594 memset(&lr, 0, sizeof(lr));
4596 IDirect3DDevice9_GetDirect3D(device, &d3d);
4597 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4598 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4599 skip("No autogenmipmap support\n");
4600 IDirect3D9_Release(d3d);
4601 return;
4603 IDirect3D9_Release(d3d);
4605 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4606 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4608 /* Make the mipmap big, so that a smaller mipmap is used
4610 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4611 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4612 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4614 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4615 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4616 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4617 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4618 for(y = 0; y < 1024; y++) {
4619 for(x = 0; x < 1024; x++) {
4620 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4621 POINT pt;
4623 pt.x = x;
4624 pt.y = y;
4625 if(PtInRect(&r1, pt)) {
4626 *dst = 0xffff0000;
4627 } else if(PtInRect(&r2, pt)) {
4628 *dst = 0xff00ff00;
4629 } else if(PtInRect(&r3, pt)) {
4630 *dst = 0xff0000ff;
4631 } else if(PtInRect(&r4, pt)) {
4632 *dst = 0xff000000;
4633 } else {
4634 *dst = 0xffffffff;
4638 hr = IDirect3DSurface9_UnlockRect(surface);
4639 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4640 IDirect3DSurface9_Release(surface);
4642 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4643 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4644 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4645 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4647 hr = IDirect3DDevice9_BeginScene(device);
4648 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4649 if(SUCCEEDED(hr)) {
4650 const float quad[] = {
4651 -0.5, -0.5, 0.1, 0.0, 0.0,
4652 -0.5, 0.5, 0.1, 0.0, 1.0,
4653 0.5, -0.5, 0.1, 1.0, 0.0,
4654 0.5, 0.5, 0.1, 1.0, 1.0
4657 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4658 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4660 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4661 hr = IDirect3DDevice9_EndScene(device);
4662 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4664 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4665 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4666 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4668 IDirect3DTexture9_Release(texture);
4670 color = getPixelColor(device, 200, 200);
4671 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4672 color = getPixelColor(device, 280, 200);
4673 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4674 color = getPixelColor(device, 360, 200);
4675 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4676 color = getPixelColor(device, 440, 200);
4677 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4678 color = getPixelColor(device, 200, 270);
4679 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4680 color = getPixelColor(device, 280, 270);
4681 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4682 color = getPixelColor(device, 360, 270);
4683 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4684 color = getPixelColor(device, 440, 270);
4685 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4686 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4687 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4690 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4692 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4693 IDirect3DVertexDeclaration9 *decl;
4694 HRESULT hr;
4695 DWORD color;
4696 DWORD shader_code_11[] = {
4697 0xfffe0101, /* vs_1_1 */
4698 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4699 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4700 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4701 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4702 0x0000ffff /* end */
4704 DWORD shader_code_11_2[] = {
4705 0xfffe0101, /* vs_1_1 */
4706 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4707 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4708 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4709 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4710 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4711 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4712 0x0000ffff /* end */
4714 DWORD shader_code_20[] = {
4715 0xfffe0200, /* vs_2_0 */
4716 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4717 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4718 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4719 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4720 0x0000ffff /* end */
4722 DWORD shader_code_20_2[] = {
4723 0xfffe0200, /* vs_2_0 */
4724 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4725 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4726 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4727 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4728 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4729 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4730 0x0000ffff /* end */
4732 static const D3DVERTEXELEMENT9 decl_elements[] = {
4733 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4734 D3DDECL_END()
4736 float quad1[] = {
4737 -1.0, -1.0, 0.1,
4738 0.0, -1.0, 0.1,
4739 -1.0, 0.0, 0.1,
4740 0.0, 0.0, 0.1
4742 float quad2[] = {
4743 0.0, -1.0, 0.1,
4744 1.0, -1.0, 0.1,
4745 0.0, 0.0, 0.1,
4746 1.0, 0.0, 0.1
4748 float quad3[] = {
4749 0.0, 0.0, 0.1,
4750 1.0, 0.0, 0.1,
4751 0.0, 1.0, 0.1,
4752 1.0, 1.0, 0.1
4754 float quad4[] = {
4755 -1.0, 0.0, 0.1,
4756 0.0, 0.0, 0.1,
4757 -1.0, 1.0, 0.1,
4758 0.0, 1.0, 0.1
4760 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4761 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4763 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4764 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4766 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4767 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4768 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4770 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4771 if(FAILED(hr)) shader_20 = NULL;
4772 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4773 if(FAILED(hr)) shader_20_2 = NULL;
4774 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4775 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4777 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4779 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4780 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4781 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4782 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4784 hr = IDirect3DDevice9_BeginScene(device);
4785 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4786 if(SUCCEEDED(hr))
4788 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4789 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4791 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4793 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4796 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4798 if(shader_20) {
4799 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4800 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4805 if(shader_20_2) {
4806 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4807 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4809 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4812 hr = IDirect3DDevice9_EndScene(device);
4813 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4816 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4817 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4818 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4819 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4821 color = getPixelColor(device, 160, 360);
4822 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4823 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4824 color = getPixelColor(device, 480, 360);
4825 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4826 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4827 if(shader_20) {
4828 color = getPixelColor(device, 480, 120);
4829 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4830 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4832 if(shader_20_2) {
4833 color = getPixelColor(device, 160, 120);
4834 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4835 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4837 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4840 IDirect3DVertexDeclaration9_Release(decl);
4841 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4842 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4843 IDirect3DVertexShader9_Release(shader_11_2);
4844 IDirect3DVertexShader9_Release(shader_11);
4847 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4849 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4850 HRESULT hr;
4851 DWORD color;
4852 DWORD shader_code_11[] = {
4853 0xffff0101, /* ps_1_1 */
4854 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4855 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4856 0x0000ffff /* end */
4858 DWORD shader_code_12[] = {
4859 0xffff0102, /* ps_1_2 */
4860 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4861 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4862 0x0000ffff /* end */
4864 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4865 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4866 * During development of this test, 1.3 shaders were verified too
4868 DWORD shader_code_14[] = {
4869 0xffff0104, /* ps_1_4 */
4870 /* Try to make one constant local. It gets clamped too, although the binary contains
4871 * the bigger numbers
4873 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4874 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4875 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4876 0x0000ffff /* end */
4878 DWORD shader_code_20[] = {
4879 0xffff0200, /* ps_2_0 */
4880 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4881 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4882 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4883 0x0000ffff /* end */
4885 float quad1[] = {
4886 -1.0, -1.0, 0.1,
4887 0.0, -1.0, 0.1,
4888 -1.0, 0.0, 0.1,
4889 0.0, 0.0, 0.1
4891 float quad2[] = {
4892 0.0, -1.0, 0.1,
4893 1.0, -1.0, 0.1,
4894 0.0, 0.0, 0.1,
4895 1.0, 0.0, 0.1
4897 float quad3[] = {
4898 0.0, 0.0, 0.1,
4899 1.0, 0.0, 0.1,
4900 0.0, 1.0, 0.1,
4901 1.0, 1.0, 0.1
4903 float quad4[] = {
4904 -1.0, 0.0, 0.1,
4905 0.0, 0.0, 0.1,
4906 -1.0, 1.0, 0.1,
4907 0.0, 1.0, 0.1
4909 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4910 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4913 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4915 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4916 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4917 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4918 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4919 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4920 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4921 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4922 if(FAILED(hr)) shader_20 = NULL;
4924 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4925 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4926 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4927 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4928 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4929 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4931 hr = IDirect3DDevice9_BeginScene(device);
4932 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4933 if(SUCCEEDED(hr))
4935 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4936 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4938 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4940 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4941 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4943 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4945 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4946 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4948 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4950 if(shader_20) {
4951 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4952 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4954 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4957 hr = IDirect3DDevice9_EndScene(device);
4958 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4960 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4961 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4963 color = getPixelColor(device, 160, 360);
4964 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4965 "quad 1 has color %08x, expected 0x00808000\n", color);
4966 color = getPixelColor(device, 480, 360);
4967 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4968 "quad 2 has color %08x, expected 0x00808000\n", color);
4969 color = getPixelColor(device, 480, 120);
4970 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4971 "quad 3 has color %08x, expected 0x00808000\n", color);
4972 if(shader_20) {
4973 color = getPixelColor(device, 160, 120);
4974 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4975 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4980 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4981 IDirect3DPixelShader9_Release(shader_14);
4982 IDirect3DPixelShader9_Release(shader_12);
4983 IDirect3DPixelShader9_Release(shader_11);
4986 static void dp2add_ps_test(IDirect3DDevice9 *device)
4988 IDirect3DPixelShader9 *shader_dp2add = NULL;
4989 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4990 HRESULT hr;
4991 DWORD color;
4993 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4994 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4995 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4996 * r0 first.
4997 * The result here for the r,g,b components should be roughly 0.5:
4998 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4999 static const DWORD shader_code_dp2add[] = {
5000 0xffff0200, /* ps_2_0 */
5001 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5003 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5004 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5006 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5007 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5008 0x0000ffff /* end */
5011 /* Test the _sat modifier, too. Result here should be:
5012 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5013 * _SAT: ==> 1.0
5014 * ADD: (1.0 + -0.5) = 0.5
5016 static const DWORD shader_code_dp2add_sat[] = {
5017 0xffff0200, /* ps_2_0 */
5018 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5020 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5021 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5022 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5024 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5025 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5026 0x0000ffff /* end */
5029 const float quad[] = {
5030 -1.0, -1.0, 0.1,
5031 1.0, -1.0, 0.1,
5032 -1.0, 1.0, 0.1,
5033 1.0, 1.0, 0.1
5037 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5038 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5040 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5041 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5043 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5044 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5046 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5047 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5049 if (shader_dp2add) {
5051 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5052 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5054 hr = IDirect3DDevice9_BeginScene(device);
5055 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5056 if(SUCCEEDED(hr))
5058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5059 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5061 hr = IDirect3DDevice9_EndScene(device);
5062 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5065 color = getPixelColor(device, 360, 240);
5066 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5067 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5069 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5070 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5072 IDirect3DPixelShader9_Release(shader_dp2add);
5073 } else {
5074 skip("dp2add shader creation failed\n");
5077 if (shader_dp2add_sat) {
5079 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5080 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5082 hr = IDirect3DDevice9_BeginScene(device);
5083 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5084 if(SUCCEEDED(hr))
5086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5087 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5089 hr = IDirect3DDevice9_EndScene(device);
5090 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5093 color = getPixelColor(device, 360, 240);
5094 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5095 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5097 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5098 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5100 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5101 } else {
5102 skip("dp2add shader creation failed\n");
5105 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5106 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5109 static void cnd_test(IDirect3DDevice9 *device)
5111 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5112 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5113 HRESULT hr;
5114 DWORD color;
5115 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5116 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5117 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5119 DWORD shader_code_11[] = {
5120 0xffff0101, /* ps_1_1 */
5121 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5122 0x00000040, 0xb00f0000, /* texcoord t0 */
5123 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5124 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5125 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5126 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5127 0x0000ffff /* end */
5129 DWORD shader_code_12[] = {
5130 0xffff0102, /* ps_1_2 */
5131 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5132 0x00000040, 0xb00f0000, /* texcoord t0 */
5133 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5134 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5135 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5136 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5137 0x0000ffff /* end */
5139 DWORD shader_code_13[] = {
5140 0xffff0103, /* ps_1_3 */
5141 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5142 0x00000040, 0xb00f0000, /* texcoord t0 */
5143 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5144 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5145 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5146 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5147 0x0000ffff /* end */
5149 DWORD shader_code_14[] = {
5150 0xffff0104, /* ps_1_3 */
5151 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5152 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5153 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5154 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5155 0x0000ffff /* end */
5158 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5159 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5160 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5161 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5162 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5163 * good enough.
5165 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5166 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5167 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5168 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5170 DWORD shader_code_11_coissue[] = {
5171 0xffff0101, /* ps_1_1 */
5172 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5173 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5174 0x00000040, 0xb00f0000, /* texcoord t0 */
5175 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5176 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5177 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5178 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5179 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5180 /* 0x40000000 = D3DSI_COISSUE */
5181 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5182 0x0000ffff /* end */
5184 DWORD shader_code_12_coissue[] = {
5185 0xffff0102, /* ps_1_2 */
5186 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5187 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5188 0x00000040, 0xb00f0000, /* texcoord t0 */
5189 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5190 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5191 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5192 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5193 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5194 /* 0x40000000 = D3DSI_COISSUE */
5195 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5196 0x0000ffff /* end */
5198 DWORD shader_code_13_coissue[] = {
5199 0xffff0103, /* ps_1_3 */
5200 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5201 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5202 0x00000040, 0xb00f0000, /* texcoord t0 */
5203 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5204 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5205 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5206 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5207 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5208 /* 0x40000000 = D3DSI_COISSUE */
5209 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5210 0x0000ffff /* end */
5212 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5213 * compare against 0.5
5215 DWORD shader_code_14_coissue[] = {
5216 0xffff0104, /* ps_1_4 */
5217 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5218 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5219 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5220 /* 0x40000000 = D3DSI_COISSUE */
5221 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5222 0x0000ffff /* end */
5224 float quad1[] = {
5225 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5226 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5227 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5228 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5230 float quad2[] = {
5231 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5232 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5233 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5234 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5236 float quad3[] = {
5237 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5238 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5239 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5240 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5242 float quad4[] = {
5243 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5244 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5245 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5246 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5248 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5249 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5250 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5251 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5253 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5254 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5256 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5257 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5258 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5259 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5260 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5261 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5262 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5263 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5264 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5265 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5266 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5267 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5268 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5269 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5270 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5271 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5273 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5274 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5275 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5276 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5277 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5278 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5280 hr = IDirect3DDevice9_BeginScene(device);
5281 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5282 if(SUCCEEDED(hr))
5284 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5287 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5289 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5290 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5292 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5294 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5297 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5299 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5300 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5301 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5302 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5304 hr = IDirect3DDevice9_EndScene(device);
5305 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5308 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5309 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5311 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5312 color = getPixelColor(device, 158, 118);
5313 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5314 color = getPixelColor(device, 162, 118);
5315 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5316 color = getPixelColor(device, 158, 122);
5317 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5318 color = getPixelColor(device, 162, 122);
5319 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5321 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5322 color = getPixelColor(device, 158, 358);
5323 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5324 color = getPixelColor(device, 162, 358);
5325 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5326 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5327 color = getPixelColor(device, 158, 362);
5328 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5329 color = getPixelColor(device, 162, 362);
5330 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5333 /* 1.2 shader */
5334 color = getPixelColor(device, 478, 358);
5335 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5336 color = getPixelColor(device, 482, 358);
5337 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5338 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5339 color = getPixelColor(device, 478, 362);
5340 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5341 color = getPixelColor(device, 482, 362);
5342 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5343 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5345 /* 1.3 shader */
5346 color = getPixelColor(device, 478, 118);
5347 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5348 color = getPixelColor(device, 482, 118);
5349 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5350 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5351 color = getPixelColor(device, 478, 122);
5352 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5353 color = getPixelColor(device, 482, 122);
5354 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5355 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5357 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5358 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5361 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5362 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5363 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5364 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5365 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5367 hr = IDirect3DDevice9_BeginScene(device);
5368 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5369 if(SUCCEEDED(hr))
5371 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5372 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5374 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5376 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5377 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5379 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5381 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5382 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5384 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5386 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5387 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5389 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5391 hr = IDirect3DDevice9_EndScene(device);
5392 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5395 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5396 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5398 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5399 * that we swapped the values in c1 and c2 to make the other tests return some color
5401 color = getPixelColor(device, 158, 118);
5402 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5403 color = getPixelColor(device, 162, 118);
5404 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5405 color = getPixelColor(device, 158, 122);
5406 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5407 color = getPixelColor(device, 162, 122);
5408 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5410 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5411 * (The Win7 nvidia driver always selects c2)
5413 color = getPixelColor(device, 158, 358);
5414 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5415 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5416 color = getPixelColor(device, 162, 358);
5417 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5418 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5419 color = getPixelColor(device, 158, 362);
5420 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5421 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5422 color = getPixelColor(device, 162, 362);
5423 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5424 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5426 /* 1.2 shader */
5427 color = getPixelColor(device, 478, 358);
5428 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5429 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5430 color = getPixelColor(device, 482, 358);
5431 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5432 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5433 color = getPixelColor(device, 478, 362);
5434 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5435 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5436 color = getPixelColor(device, 482, 362);
5437 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5438 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5440 /* 1.3 shader */
5441 color = getPixelColor(device, 478, 118);
5442 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5443 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5444 color = getPixelColor(device, 482, 118);
5445 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5446 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5447 color = getPixelColor(device, 478, 122);
5448 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5449 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5450 color = getPixelColor(device, 482, 122);
5451 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5452 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5454 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5457 IDirect3DPixelShader9_Release(shader_14_coissue);
5458 IDirect3DPixelShader9_Release(shader_13_coissue);
5459 IDirect3DPixelShader9_Release(shader_12_coissue);
5460 IDirect3DPixelShader9_Release(shader_11_coissue);
5461 IDirect3DPixelShader9_Release(shader_14);
5462 IDirect3DPixelShader9_Release(shader_13);
5463 IDirect3DPixelShader9_Release(shader_12);
5464 IDirect3DPixelShader9_Release(shader_11);
5467 static void nested_loop_test(IDirect3DDevice9 *device) {
5468 const DWORD shader_code[] = {
5469 0xffff0300, /* ps_3_0 */
5470 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5471 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5472 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5473 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5474 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5475 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5476 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5477 0x0000001d, /* endloop */
5478 0x0000001d, /* endloop */
5479 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5480 0x0000ffff /* end */
5482 const DWORD vshader_code[] = {
5483 0xfffe0300, /* vs_3_0 */
5484 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5485 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5486 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5487 0x0000ffff /* end */
5489 IDirect3DPixelShader9 *shader;
5490 IDirect3DVertexShader9 *vshader;
5491 HRESULT hr;
5492 DWORD color;
5493 const float quad[] = {
5494 -1.0, -1.0, 0.1,
5495 1.0, -1.0, 0.1,
5496 -1.0, 1.0, 0.1,
5497 1.0, 1.0, 0.1
5500 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5501 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5502 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5503 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5504 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5505 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5506 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5507 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5508 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5509 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5511 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5513 hr = IDirect3DDevice9_BeginScene(device);
5514 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5515 if(SUCCEEDED(hr))
5517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5518 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5519 hr = IDirect3DDevice9_EndScene(device);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5523 color = getPixelColor(device, 360, 240);
5524 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5525 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5527 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5530 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5532 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5533 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5534 IDirect3DPixelShader9_Release(shader);
5535 IDirect3DVertexShader9_Release(vshader);
5538 struct varying_test_struct
5540 const DWORD *shader_code;
5541 IDirect3DPixelShader9 *shader;
5542 DWORD color, color_rhw;
5543 const char *name;
5544 BOOL todo, todo_rhw;
5547 struct hugeVertex
5549 float pos_x, pos_y, pos_z, rhw;
5550 float weight_1, weight_2, weight_3, weight_4;
5551 float index_1, index_2, index_3, index_4;
5552 float normal_1, normal_2, normal_3, normal_4;
5553 float fog_1, fog_2, fog_3, fog_4;
5554 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5555 float tangent_1, tangent_2, tangent_3, tangent_4;
5556 float binormal_1, binormal_2, binormal_3, binormal_4;
5557 float depth_1, depth_2, depth_3, depth_4;
5558 DWORD diffuse, specular;
5561 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5562 /* dcl_position: fails to compile */
5563 const DWORD blendweight_code[] = {
5564 0xffff0300, /* ps_3_0 */
5565 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5566 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5567 0x0000ffff /* end */
5569 const DWORD blendindices_code[] = {
5570 0xffff0300, /* ps_3_0 */
5571 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5572 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5573 0x0000ffff /* end */
5575 const DWORD normal_code[] = {
5576 0xffff0300, /* ps_3_0 */
5577 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5578 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5579 0x0000ffff /* end */
5581 /* psize: fails? */
5582 const DWORD texcoord0_code[] = {
5583 0xffff0300, /* ps_3_0 */
5584 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5585 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5586 0x0000ffff /* end */
5588 const DWORD tangent_code[] = {
5589 0xffff0300, /* ps_3_0 */
5590 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5591 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5592 0x0000ffff /* end */
5594 const DWORD binormal_code[] = {
5595 0xffff0300, /* ps_3_0 */
5596 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5597 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5598 0x0000ffff /* end */
5600 /* tessfactor: fails */
5601 /* positiont: fails */
5602 const DWORD color_code[] = {
5603 0xffff0300, /* ps_3_0 */
5604 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5605 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5606 0x0000ffff /* end */
5608 const DWORD fog_code[] = {
5609 0xffff0300, /* ps_3_0 */
5610 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5611 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5612 0x0000ffff /* end */
5614 const DWORD depth_code[] = {
5615 0xffff0300, /* ps_3_0 */
5616 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5617 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5618 0x0000ffff /* end */
5620 const DWORD specular_code[] = {
5621 0xffff0300, /* ps_3_0 */
5622 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5623 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5624 0x0000ffff /* end */
5626 /* sample: fails */
5628 struct varying_test_struct tests[] = {
5629 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5630 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5631 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5632 /* Why does dx not forward the texcoord? */
5633 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5634 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5635 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5636 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5637 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5638 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5639 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5641 /* Declare a monster vertex type :-) */
5642 static const D3DVERTEXELEMENT9 decl_elements[] = {
5643 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5644 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5645 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5646 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5647 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5648 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5649 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5650 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5651 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5652 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5653 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5654 D3DDECL_END()
5656 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5657 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5658 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5659 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5660 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5661 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5662 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5663 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5664 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5665 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5666 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5667 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5668 D3DDECL_END()
5670 struct hugeVertex data[4] = {
5672 -1.0, -1.0, 0.1, 1.0,
5673 0.1, 0.1, 0.1, 0.1,
5674 0.2, 0.2, 0.2, 0.2,
5675 0.3, 0.3, 0.3, 0.3,
5676 0.4, 0.4, 0.4, 0.4,
5677 0.50, 0.55, 0.55, 0.55,
5678 0.6, 0.6, 0.6, 0.7,
5679 0.7, 0.7, 0.7, 0.6,
5680 0.8, 0.8, 0.8, 0.8,
5681 0xe6e6e6e6, /* 0.9 * 256 */
5682 0x224488ff /* Nothing special */
5685 1.0, -1.0, 0.1, 1.0,
5686 0.1, 0.1, 0.1, 0.1,
5687 0.2, 0.2, 0.2, 0.2,
5688 0.3, 0.3, 0.3, 0.3,
5689 0.4, 0.4, 0.4, 0.4,
5690 0.50, 0.55, 0.55, 0.55,
5691 0.6, 0.6, 0.6, 0.7,
5692 0.7, 0.7, 0.7, 0.6,
5693 0.8, 0.8, 0.8, 0.8,
5694 0xe6e6e6e6, /* 0.9 * 256 */
5695 0x224488ff /* Nothing special */
5698 -1.0, 1.0, 0.1, 1.0,
5699 0.1, 0.1, 0.1, 0.1,
5700 0.2, 0.2, 0.2, 0.2,
5701 0.3, 0.3, 0.3, 0.3,
5702 0.4, 0.4, 0.4, 0.4,
5703 0.50, 0.55, 0.55, 0.55,
5704 0.6, 0.6, 0.6, 0.7,
5705 0.7, 0.7, 0.7, 0.6,
5706 0.8, 0.8, 0.8, 0.8,
5707 0xe6e6e6e6, /* 0.9 * 256 */
5708 0x224488ff /* Nothing special */
5711 1.0, 1.0, 0.1, 1.0,
5712 0.1, 0.1, 0.1, 0.1,
5713 0.2, 0.2, 0.2, 0.2,
5714 0.3, 0.3, 0.3, 0.3,
5715 0.4, 0.4, 0.4, 0.4,
5716 0.50, 0.55, 0.55, 0.55,
5717 0.6, 0.6, 0.6, 0.7,
5718 0.7, 0.7, 0.7, 0.6,
5719 0.8, 0.8, 0.8, 0.8,
5720 0xe6e6e6e6, /* 0.9 * 256 */
5721 0x224488ff /* Nothing special */
5724 struct hugeVertex data2[4];
5725 IDirect3DVertexDeclaration9 *decl;
5726 IDirect3DVertexDeclaration9 *decl2;
5727 HRESULT hr;
5728 unsigned int i;
5729 DWORD color, r, g, b, r_e, g_e, b_e;
5730 BOOL drawok;
5732 memcpy(data2, data, sizeof(data2));
5733 data2[0].pos_x = 0; data2[0].pos_y = 0;
5734 data2[1].pos_x = 640; data2[1].pos_y = 0;
5735 data2[2].pos_x = 0; data2[2].pos_y = 480;
5736 data2[3].pos_x = 640; data2[3].pos_y = 480;
5738 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5739 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5740 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5741 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5742 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5743 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5745 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5747 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5748 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5749 tests[i].name, hr);
5752 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5754 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5755 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5757 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5758 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5760 hr = IDirect3DDevice9_BeginScene(device);
5761 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5762 drawok = FALSE;
5763 if(SUCCEEDED(hr))
5765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5766 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5767 drawok = SUCCEEDED(hr);
5768 hr = IDirect3DDevice9_EndScene(device);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5772 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5773 * the failure and do not check the color if it failed
5775 if(!drawok) {
5776 continue;
5779 color = getPixelColor(device, 360, 240);
5780 r = color & 0x00ff0000 >> 16;
5781 g = color & 0x0000ff00 >> 8;
5782 b = color & 0x000000ff;
5783 r_e = tests[i].color & 0x00ff0000 >> 16;
5784 g_e = tests[i].color & 0x0000ff00 >> 8;
5785 b_e = tests[i].color & 0x000000ff;
5787 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5790 if(tests[i].todo) {
5791 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5792 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5793 tests[i].name, color, tests[i].color);
5794 } else {
5795 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5796 "Test %s returned color 0x%08x, expected 0x%08x\n",
5797 tests[i].name, color, tests[i].color);
5801 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5802 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5803 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5805 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5806 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5808 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5809 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5811 hr = IDirect3DDevice9_BeginScene(device);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5813 if(SUCCEEDED(hr))
5815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5816 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5817 hr = IDirect3DDevice9_EndScene(device);
5818 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5821 color = getPixelColor(device, 360, 240);
5822 r = color & 0x00ff0000 >> 16;
5823 g = color & 0x0000ff00 >> 8;
5824 b = color & 0x000000ff;
5825 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5826 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5827 b_e = tests[i].color_rhw & 0x000000ff;
5829 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5830 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5832 if(tests[i].todo_rhw) {
5833 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5834 * pipeline
5836 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5837 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5838 tests[i].name, color, tests[i].color_rhw);
5839 } else {
5840 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5841 "Test %s returned color 0x%08x, expected 0x%08x\n",
5842 tests[i].name, color, tests[i].color_rhw);
5846 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5848 IDirect3DPixelShader9_Release(tests[i].shader);
5851 IDirect3DVertexDeclaration9_Release(decl2);
5852 IDirect3DVertexDeclaration9_Release(decl);
5855 static void test_compare_instructions(IDirect3DDevice9 *device)
5857 DWORD shader_sge_vec_code[] = {
5858 0xfffe0101, /* vs_1_1 */
5859 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5860 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5861 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5862 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5863 0x0000ffff /* end */
5865 DWORD shader_slt_vec_code[] = {
5866 0xfffe0101, /* vs_1_1 */
5867 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5868 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5869 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5870 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5871 0x0000ffff /* end */
5873 DWORD shader_sge_scalar_code[] = {
5874 0xfffe0101, /* vs_1_1 */
5875 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5876 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5877 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5878 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5879 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5880 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5881 0x0000ffff /* end */
5883 DWORD shader_slt_scalar_code[] = {
5884 0xfffe0101, /* vs_1_1 */
5885 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5886 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5887 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5888 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5889 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5890 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5891 0x0000ffff /* end */
5893 IDirect3DVertexShader9 *shader_sge_vec;
5894 IDirect3DVertexShader9 *shader_slt_vec;
5895 IDirect3DVertexShader9 *shader_sge_scalar;
5896 IDirect3DVertexShader9 *shader_slt_scalar;
5897 HRESULT hr, color;
5898 float quad1[] = {
5899 -1.0, -1.0, 0.1,
5900 0.0, -1.0, 0.1,
5901 -1.0, 0.0, 0.1,
5902 0.0, 0.0, 0.1
5904 float quad2[] = {
5905 0.0, -1.0, 0.1,
5906 1.0, -1.0, 0.1,
5907 0.0, 0.0, 0.1,
5908 1.0, 0.0, 0.1
5910 float quad3[] = {
5911 -1.0, 0.0, 0.1,
5912 0.0, 0.0, 0.1,
5913 -1.0, 1.0, 0.1,
5914 0.0, 1.0, 0.1
5916 float quad4[] = {
5917 0.0, 0.0, 0.1,
5918 1.0, 0.0, 0.1,
5919 0.0, 1.0, 0.1,
5920 1.0, 1.0, 0.1
5922 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5923 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5926 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5928 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5929 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5930 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5931 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5932 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5933 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5934 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5935 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5936 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5937 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5938 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5939 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5941 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5943 hr = IDirect3DDevice9_BeginScene(device);
5944 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5945 if(SUCCEEDED(hr))
5947 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5948 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5949 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5950 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5952 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5953 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5955 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5957 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5958 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5960 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5962 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5963 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5965 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5966 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5968 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5970 hr = IDirect3DDevice9_EndScene(device);
5971 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5974 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5975 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5977 color = getPixelColor(device, 160, 360);
5978 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5979 color = getPixelColor(device, 480, 360);
5980 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5981 color = getPixelColor(device, 160, 120);
5982 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5983 color = getPixelColor(device, 480, 160);
5984 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5987 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5989 IDirect3DVertexShader9_Release(shader_sge_vec);
5990 IDirect3DVertexShader9_Release(shader_slt_vec);
5991 IDirect3DVertexShader9_Release(shader_sge_scalar);
5992 IDirect3DVertexShader9_Release(shader_slt_scalar);
5995 static void test_vshader_input(IDirect3DDevice9 *device)
5997 DWORD swapped_shader_code_3[] = {
5998 0xfffe0300, /* vs_3_0 */
5999 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6000 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6001 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6002 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6003 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6004 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6005 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6006 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6007 0x0000ffff /* end */
6009 DWORD swapped_shader_code_1[] = {
6010 0xfffe0101, /* vs_1_1 */
6011 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6012 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6013 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6014 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6015 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6016 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6017 0x0000ffff /* end */
6019 DWORD swapped_shader_code_2[] = {
6020 0xfffe0200, /* vs_2_0 */
6021 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6022 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6023 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6024 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6025 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6026 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6027 0x0000ffff /* end */
6029 DWORD texcoord_color_shader_code_3[] = {
6030 0xfffe0300, /* vs_3_0 */
6031 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6032 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6033 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6034 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6035 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6036 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6037 0x0000ffff /* end */
6039 DWORD texcoord_color_shader_code_2[] = {
6040 0xfffe0200, /* vs_2_0 */
6041 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6042 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6043 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6044 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6045 0x0000ffff /* end */
6047 DWORD texcoord_color_shader_code_1[] = {
6048 0xfffe0101, /* vs_1_1 */
6049 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6050 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6051 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6052 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6053 0x0000ffff /* end */
6055 DWORD color_color_shader_code_3[] = {
6056 0xfffe0300, /* vs_3_0 */
6057 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6058 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6059 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6060 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6061 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6062 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6063 0x0000ffff /* end */
6065 DWORD color_color_shader_code_2[] = {
6066 0xfffe0200, /* vs_2_0 */
6067 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6068 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6069 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6070 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6071 0x0000ffff /* end */
6073 DWORD color_color_shader_code_1[] = {
6074 0xfffe0101, /* vs_1_1 */
6075 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6076 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6077 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6078 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6079 0x0000ffff /* end */
6081 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6082 HRESULT hr;
6083 DWORD color;
6084 float quad1[] = {
6085 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6086 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6087 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6088 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6090 float quad2[] = {
6091 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6092 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6093 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6094 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6096 float quad3[] = {
6097 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6098 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6099 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6100 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6102 float quad4[] = {
6103 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6104 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6105 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6106 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6108 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6109 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6110 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6111 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6112 D3DDECL_END()
6114 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6115 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6116 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6117 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6118 D3DDECL_END()
6120 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6121 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6122 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6123 D3DDECL_END()
6125 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6126 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6127 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6128 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6129 D3DDECL_END()
6131 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6132 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6133 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6134 D3DDECL_END()
6136 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6137 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6138 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6139 D3DDECL_END()
6141 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6142 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6143 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6144 D3DDECL_END()
6146 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6147 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6148 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6149 D3DDECL_END()
6151 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6152 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6153 unsigned int i;
6154 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6155 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6157 struct vertex quad1_color[] = {
6158 {-1.0, -1.0, 0.1, 0x00ff8040},
6159 { 0.0, -1.0, 0.1, 0x00ff8040},
6160 {-1.0, 0.0, 0.1, 0x00ff8040},
6161 { 0.0, 0.0, 0.1, 0x00ff8040}
6163 struct vertex quad2_color[] = {
6164 { 0.0, -1.0, 0.1, 0x00ff8040},
6165 { 1.0, -1.0, 0.1, 0x00ff8040},
6166 { 0.0, 0.0, 0.1, 0x00ff8040},
6167 { 1.0, 0.0, 0.1, 0x00ff8040}
6169 struct vertex quad3_color[] = {
6170 {-1.0, 0.0, 0.1, 0x00ff8040},
6171 { 0.0, 0.0, 0.1, 0x00ff8040},
6172 {-1.0, 1.0, 0.1, 0x00ff8040},
6173 { 0.0, 1.0, 0.1, 0x00ff8040}
6175 float quad4_color[] = {
6176 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6177 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6178 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6179 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6182 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6183 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6184 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6185 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6186 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6187 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6188 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6189 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6191 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6192 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6193 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6194 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6195 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6196 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6197 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6198 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6200 for(i = 1; i <= 3; i++) {
6201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6202 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6203 if(i == 3) {
6204 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6205 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6206 } else if(i == 2){
6207 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6209 } else if(i == 1) {
6210 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6214 hr = IDirect3DDevice9_BeginScene(device);
6215 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6216 if(SUCCEEDED(hr))
6218 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6219 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6221 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6222 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6223 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6224 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6226 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6227 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6229 if(i == 3 || i == 2) {
6230 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6231 } else if(i == 1) {
6232 /* Succeeds or fails, depending on SW or HW vertex processing */
6233 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6236 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6238 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6239 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6241 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6244 if(i == 3 || i == 2) {
6245 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6246 } else if(i == 1) {
6247 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6250 hr = IDirect3DDevice9_EndScene(device);
6251 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6254 if(i == 3 || i == 2) {
6255 color = getPixelColor(device, 160, 360);
6256 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6257 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6259 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6260 color = getPixelColor(device, 480, 360);
6261 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6262 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6263 color = getPixelColor(device, 160, 120);
6264 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6265 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6266 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6268 color = getPixelColor(device, 480, 160);
6269 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6270 } else if(i == 1) {
6271 color = getPixelColor(device, 160, 360);
6272 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6273 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6274 color = getPixelColor(device, 480, 360);
6275 /* Accept the clear color as well in this case, since SW VP returns an error */
6276 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6277 color = getPixelColor(device, 160, 120);
6278 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6279 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6280 color = getPixelColor(device, 480, 160);
6281 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6285 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6288 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6290 /* Now find out if the whole streams are re-read, or just the last active value for the
6291 * vertices is used.
6293 hr = IDirect3DDevice9_BeginScene(device);
6294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295 if(SUCCEEDED(hr))
6297 float quad1_modified[] = {
6298 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6299 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6300 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6301 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6303 float quad2_modified[] = {
6304 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6305 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6306 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6307 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6310 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6313 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6314 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6315 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6316 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6318 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6319 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6321 if(i == 3 || i == 2) {
6322 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6323 } else if(i == 1) {
6324 /* Succeeds or fails, depending on SW or HW vertex processing */
6325 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6328 hr = IDirect3DDevice9_EndScene(device);
6329 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6332 color = getPixelColor(device, 480, 350);
6333 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6334 * as well.
6336 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6337 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6338 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6339 * refrast's result.
6341 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6343 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6344 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6346 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6349 IDirect3DDevice9_SetVertexShader(device, NULL);
6350 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6352 IDirect3DVertexShader9_Release(swapped_shader);
6355 for(i = 1; i <= 3; i++) {
6356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6357 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6358 if(i == 3) {
6359 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6360 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6361 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6362 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6363 } else if(i == 2){
6364 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6365 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6366 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6367 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6368 } else if(i == 1) {
6369 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6370 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6371 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6372 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6375 hr = IDirect3DDevice9_BeginScene(device);
6376 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6377 if(SUCCEEDED(hr))
6379 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6380 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6381 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6382 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6384 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6386 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6387 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6389 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6390 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6391 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6392 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6394 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6396 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6397 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6398 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6399 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6401 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6403 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6404 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6406 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6408 hr = IDirect3DDevice9_EndScene(device);
6409 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6411 IDirect3DDevice9_SetVertexShader(device, NULL);
6412 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6414 color = getPixelColor(device, 160, 360);
6415 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6416 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6417 color = getPixelColor(device, 480, 360);
6418 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6419 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6420 color = getPixelColor(device, 160, 120);
6421 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6422 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6423 color = getPixelColor(device, 480, 160);
6424 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6425 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6427 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6428 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6430 IDirect3DVertexShader9_Release(texcoord_color_shader);
6431 IDirect3DVertexShader9_Release(color_color_shader);
6434 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6435 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6436 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6437 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6439 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6440 IDirect3DVertexDeclaration9_Release(decl_color_color);
6441 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6442 IDirect3DVertexDeclaration9_Release(decl_color_float);
6445 static void srgbtexture_test(IDirect3DDevice9 *device)
6447 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6448 * texture stage state to render a quad using that texture. The resulting
6449 * color components should be 0x36 (~ 0.21), per this formula:
6450 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6451 * This is true where srgb_color > 0.04045.
6453 IDirect3D9 *d3d = NULL;
6454 HRESULT hr;
6455 LPDIRECT3DTEXTURE9 texture = NULL;
6456 LPDIRECT3DSURFACE9 surface = NULL;
6457 D3DLOCKED_RECT lr;
6458 DWORD color;
6459 float quad[] = {
6460 -1.0, 1.0, 0.0, 0.0, 0.0,
6461 1.0, 1.0, 0.0, 1.0, 0.0,
6462 -1.0, -1.0, 0.0, 0.0, 1.0,
6463 1.0, -1.0, 0.0, 1.0, 1.0,
6467 memset(&lr, 0, sizeof(lr));
6468 IDirect3DDevice9_GetDirect3D(device, &d3d);
6469 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6470 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6471 D3DFMT_A8R8G8B8) != D3D_OK) {
6472 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6473 goto out;
6476 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6477 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6478 &texture, NULL);
6479 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6480 if(!texture) {
6481 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6482 goto out;
6484 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6485 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6487 fill_surface(surface, 0xff7f7f7f);
6488 IDirect3DSurface9_Release(surface);
6490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6491 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6492 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6493 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6495 hr = IDirect3DDevice9_BeginScene(device);
6496 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6497 if(SUCCEEDED(hr))
6499 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6500 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6502 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6503 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6507 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6509 hr = IDirect3DDevice9_EndScene(device);
6510 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6513 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6514 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6515 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6516 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6518 color = getPixelColor(device, 320, 240);
6519 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6521 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6522 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6524 out:
6525 if(texture) IDirect3DTexture9_Release(texture);
6526 IDirect3D9_Release(d3d);
6529 static void shademode_test(IDirect3DDevice9 *device)
6531 /* Render a quad and try all of the different fixed function shading models. */
6532 HRESULT hr;
6533 DWORD color0, color1;
6534 DWORD color0_gouraud = 0, color1_gouraud = 0;
6535 DWORD shademode = D3DSHADE_FLAT;
6536 DWORD primtype = D3DPT_TRIANGLESTRIP;
6537 LPVOID data = NULL;
6538 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6539 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6540 UINT i, j;
6541 struct vertex quad_strip[] =
6543 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6544 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6545 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6546 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6548 struct vertex quad_list[] =
6550 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6551 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6552 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6554 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6555 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6556 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6559 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6560 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6561 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6562 if (FAILED(hr)) goto bail;
6564 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6565 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6566 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6567 if (FAILED(hr)) goto bail;
6569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6570 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6575 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6576 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6577 memcpy(data, quad_strip, sizeof(quad_strip));
6578 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6579 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6581 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6582 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6583 memcpy(data, quad_list, sizeof(quad_list));
6584 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6585 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6587 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6588 * the color fixups we have to do for FLAT shading will be dependent on that. */
6589 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6590 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6592 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6593 for (j=0; j<2; j++) {
6595 /* Inner loop just changes the D3DRS_SHADEMODE */
6596 for (i=0; i<3; i++) {
6597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6598 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6601 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6603 hr = IDirect3DDevice9_BeginScene(device);
6604 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6605 if(SUCCEEDED(hr))
6607 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6608 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6610 hr = IDirect3DDevice9_EndScene(device);
6611 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6614 /* Sample two spots from the output */
6615 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6616 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6617 switch(shademode) {
6618 case D3DSHADE_FLAT:
6619 /* Should take the color of the first vertex of each triangle */
6620 if (0)
6622 /* This test depends on EXT_provoking_vertex being
6623 * available. This extension is currently (20090810)
6624 * not common enough to let the test fail if it isn't
6625 * present. */
6626 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6627 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6629 shademode = D3DSHADE_GOURAUD;
6630 break;
6631 case D3DSHADE_GOURAUD:
6632 /* Should be an interpolated blend */
6634 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6635 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6636 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6637 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6639 color0_gouraud = color0;
6640 color1_gouraud = color1;
6642 shademode = D3DSHADE_PHONG;
6643 break;
6644 case D3DSHADE_PHONG:
6645 /* Should be the same as GOURAUD, since no hardware implements this */
6646 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6647 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6648 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6649 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6651 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6652 color0_gouraud, color0);
6653 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6654 color1_gouraud, color1);
6655 break;
6659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6660 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6662 /* Now, do it all over again with a TRIANGLELIST */
6663 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6664 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6665 primtype = D3DPT_TRIANGLELIST;
6666 shademode = D3DSHADE_FLAT;
6669 bail:
6670 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6671 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6673 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6675 if (vb_strip)
6676 IDirect3DVertexBuffer9_Release(vb_strip);
6677 if (vb_list)
6678 IDirect3DVertexBuffer9_Release(vb_list);
6681 static void alpha_test(IDirect3DDevice9 *device)
6683 HRESULT hr;
6684 IDirect3DTexture9 *offscreenTexture;
6685 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6686 DWORD color;
6688 struct vertex quad1[] =
6690 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6691 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6692 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6693 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6695 struct vertex quad2[] =
6697 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6698 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6699 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6700 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6702 static const float composite_quad[][5] = {
6703 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6704 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6705 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6706 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6709 /* Clear the render target with alpha = 0.5 */
6710 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6711 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6713 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6714 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6716 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6717 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6718 if(!backbuffer) {
6719 goto out;
6722 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6723 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6724 if(!offscreen) {
6725 goto out;
6728 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6729 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6731 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6732 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6733 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6734 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6735 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6736 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6737 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6738 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6744 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6746 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6748 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6749 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6752 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6755 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6757 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6759 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6761 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6762 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6763 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6764 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6765 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6767 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6770 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6772 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6774 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6777 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6778 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6779 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6780 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6781 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6783 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6784 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6786 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6787 * Disable alpha blending for the final composition
6789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6790 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6791 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6792 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6794 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6795 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6797 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6798 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6799 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6801 hr = IDirect3DDevice9_EndScene(device);
6802 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6805 color = getPixelColor(device, 160, 360);
6806 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6807 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6809 color = getPixelColor(device, 160, 120);
6810 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6811 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6813 color = getPixelColor(device, 480, 360);
6814 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6815 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6817 color = getPixelColor(device, 480, 120);
6818 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6819 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6821 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6823 out:
6824 /* restore things */
6825 if(backbuffer) {
6826 IDirect3DSurface9_Release(backbuffer);
6828 if(offscreenTexture) {
6829 IDirect3DTexture9_Release(offscreenTexture);
6831 if(offscreen) {
6832 IDirect3DSurface9_Release(offscreen);
6836 struct vertex_shortcolor {
6837 float x, y, z;
6838 unsigned short r, g, b, a;
6840 struct vertex_floatcolor {
6841 float x, y, z;
6842 float r, g, b, a;
6845 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6847 HRESULT hr;
6848 BOOL s_ok, ub_ok, f_ok;
6849 DWORD color, size, i;
6850 void *data;
6851 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6852 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6853 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6854 D3DDECL_END()
6856 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6857 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6858 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6859 D3DDECL_END()
6861 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6862 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6863 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6864 D3DDECL_END()
6866 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6867 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6868 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6869 D3DDECL_END()
6871 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6872 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6873 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6874 D3DDECL_END()
6876 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6877 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6878 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6879 D3DDECL_END()
6881 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6882 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6883 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6884 D3DDECL_END()
6886 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6887 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6888 IDirect3DVertexBuffer9 *vb, *vb2;
6889 struct vertex quad1[] = /* D3DCOLOR */
6891 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6892 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6893 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6894 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6896 struct vertex quad2[] = /* UBYTE4N */
6898 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6899 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6900 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6901 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6903 struct vertex_shortcolor quad3[] = /* short */
6905 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6906 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6907 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6908 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6910 struct vertex_floatcolor quad4[] =
6912 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6913 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6914 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6915 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6917 DWORD colors[] = {
6918 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6919 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6920 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6921 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6922 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6923 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6924 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6925 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6926 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6927 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6928 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6929 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6930 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6931 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6932 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6933 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6935 float quads[] = {
6936 -1.0, -1.0, 0.1,
6937 -1.0, 0.0, 0.1,
6938 0.0, -1.0, 0.1,
6939 0.0, 0.0, 0.1,
6941 0.0, -1.0, 0.1,
6942 0.0, 0.0, 0.1,
6943 1.0, -1.0, 0.1,
6944 1.0, 0.0, 0.1,
6946 0.0, 0.0, 0.1,
6947 0.0, 1.0, 0.1,
6948 1.0, 0.0, 0.1,
6949 1.0, 1.0, 0.1,
6951 -1.0, 0.0, 0.1,
6952 -1.0, 1.0, 0.1,
6953 0.0, 0.0, 0.1,
6954 0.0, 1.0, 0.1
6956 struct tvertex quad_transformed[] = {
6957 { 90, 110, 0.1, 2.0, 0x00ffff00},
6958 { 570, 110, 0.1, 2.0, 0x00ffff00},
6959 { 90, 300, 0.1, 2.0, 0x00ffff00},
6960 { 570, 300, 0.1, 2.0, 0x00ffff00}
6962 D3DCAPS9 caps;
6964 memset(&caps, 0, sizeof(caps));
6965 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6966 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6969 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6971 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6972 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6973 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6974 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6975 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6976 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6977 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6978 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6979 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6980 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6981 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6982 } else {
6983 trace("D3DDTCAPS_UBYTE4N not supported\n");
6984 dcl_ubyte_2 = NULL;
6985 dcl_ubyte = NULL;
6987 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6988 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6989 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6990 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6992 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6993 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6994 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6995 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6997 hr = IDirect3DDevice9_BeginScene(device);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6999 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7000 if(SUCCEEDED(hr)) {
7001 if(dcl_color) {
7002 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7003 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7005 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7008 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7009 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7010 * using software vertex processing. Doh!
7012 if(dcl_ubyte) {
7013 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7014 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7016 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7017 ub_ok = SUCCEEDED(hr);
7020 if(dcl_short) {
7021 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7022 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7024 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7025 s_ok = SUCCEEDED(hr);
7028 if(dcl_float) {
7029 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7030 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7032 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7033 f_ok = SUCCEEDED(hr);
7036 hr = IDirect3DDevice9_EndScene(device);
7037 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7040 if(dcl_short) {
7041 color = getPixelColor(device, 480, 360);
7042 ok(color == 0x000000ff || !s_ok,
7043 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7045 if(dcl_ubyte) {
7046 color = getPixelColor(device, 160, 120);
7047 ok(color == 0x0000ffff || !ub_ok,
7048 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7050 if(dcl_color) {
7051 color = getPixelColor(device, 160, 360);
7052 ok(color == 0x00ffff00,
7053 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7055 if(dcl_float) {
7056 color = getPixelColor(device, 480, 120);
7057 ok(color == 0x00ff0000 || !f_ok,
7058 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7060 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7062 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7063 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7064 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7065 * whether the immediate mode code works
7067 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7068 hr = IDirect3DDevice9_BeginScene(device);
7069 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7070 if(SUCCEEDED(hr)) {
7071 if(dcl_color) {
7072 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7073 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7074 memcpy(data, quad1, sizeof(quad1));
7075 hr = IDirect3DVertexBuffer9_Unlock(vb);
7076 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7077 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7078 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7079 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7080 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7081 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7085 if(dcl_ubyte) {
7086 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7087 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7088 memcpy(data, quad2, sizeof(quad2));
7089 hr = IDirect3DVertexBuffer9_Unlock(vb);
7090 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7091 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7092 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7093 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7094 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7095 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7096 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7097 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7098 ub_ok = SUCCEEDED(hr);
7101 if(dcl_short) {
7102 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7103 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7104 memcpy(data, quad3, sizeof(quad3));
7105 hr = IDirect3DVertexBuffer9_Unlock(vb);
7106 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7107 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7108 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7109 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7110 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7111 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7112 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7113 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7114 s_ok = SUCCEEDED(hr);
7117 if(dcl_float) {
7118 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7119 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7120 memcpy(data, quad4, sizeof(quad4));
7121 hr = IDirect3DVertexBuffer9_Unlock(vb);
7122 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7123 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7124 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7125 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7126 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7127 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7128 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7129 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7130 f_ok = SUCCEEDED(hr);
7133 hr = IDirect3DDevice9_EndScene(device);
7134 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7137 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7138 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7139 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7140 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7142 if(dcl_short) {
7143 color = getPixelColor(device, 480, 360);
7144 ok(color == 0x000000ff || !s_ok,
7145 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7147 if(dcl_ubyte) {
7148 color = getPixelColor(device, 160, 120);
7149 ok(color == 0x0000ffff || !ub_ok,
7150 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7152 if(dcl_color) {
7153 color = getPixelColor(device, 160, 360);
7154 ok(color == 0x00ffff00,
7155 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7157 if(dcl_float) {
7158 color = getPixelColor(device, 480, 120);
7159 ok(color == 0x00ff0000 || !f_ok,
7160 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7162 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7165 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7167 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7168 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7169 memcpy(data, quad_transformed, sizeof(quad_transformed));
7170 hr = IDirect3DVertexBuffer9_Unlock(vb);
7171 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7173 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7174 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7176 hr = IDirect3DDevice9_BeginScene(device);
7177 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7178 if(SUCCEEDED(hr)) {
7179 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7180 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7181 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7182 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7184 hr = IDirect3DDevice9_EndScene(device);
7185 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7188 color = getPixelColor(device, 88, 108);
7189 ok(color == 0x000000ff,
7190 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7191 color = getPixelColor(device, 92, 108);
7192 ok(color == 0x000000ff,
7193 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7194 color = getPixelColor(device, 88, 112);
7195 ok(color == 0x000000ff,
7196 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7197 color = getPixelColor(device, 92, 112);
7198 ok(color == 0x00ffff00,
7199 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7201 color = getPixelColor(device, 568, 108);
7202 ok(color == 0x000000ff,
7203 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7204 color = getPixelColor(device, 572, 108);
7205 ok(color == 0x000000ff,
7206 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7207 color = getPixelColor(device, 568, 112);
7208 ok(color == 0x00ffff00,
7209 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7210 color = getPixelColor(device, 572, 112);
7211 ok(color == 0x000000ff,
7212 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7214 color = getPixelColor(device, 88, 298);
7215 ok(color == 0x000000ff,
7216 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7217 color = getPixelColor(device, 92, 298);
7218 ok(color == 0x00ffff00,
7219 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7220 color = getPixelColor(device, 88, 302);
7221 ok(color == 0x000000ff,
7222 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7223 color = getPixelColor(device, 92, 302);
7224 ok(color == 0x000000ff,
7225 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7227 color = getPixelColor(device, 568, 298);
7228 ok(color == 0x00ffff00,
7229 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7230 color = getPixelColor(device, 572, 298);
7231 ok(color == 0x000000ff,
7232 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7233 color = getPixelColor(device, 568, 302);
7234 ok(color == 0x000000ff,
7235 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7236 color = getPixelColor(device, 572, 302);
7237 ok(color == 0x000000ff,
7238 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7240 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7242 /* This test is pointless without those two declarations: */
7243 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7244 skip("color-ubyte switching test declarations aren't supported\n");
7245 goto out;
7248 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7249 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7250 memcpy(data, quads, sizeof(quads));
7251 hr = IDirect3DVertexBuffer9_Unlock(vb);
7252 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7253 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7254 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7255 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7256 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7257 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7258 memcpy(data, colors, sizeof(colors));
7259 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7260 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7262 for(i = 0; i < 2; i++) {
7263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7264 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7266 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7267 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7268 if(i == 0) {
7269 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7270 } else {
7271 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7273 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7275 hr = IDirect3DDevice9_BeginScene(device);
7276 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7277 ub_ok = FALSE;
7278 if(SUCCEEDED(hr)) {
7279 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7280 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7281 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7282 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7283 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7284 ub_ok = SUCCEEDED(hr);
7286 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7287 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7288 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7289 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7291 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7292 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7293 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7294 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7295 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7296 ub_ok = (SUCCEEDED(hr) && ub_ok);
7298 hr = IDirect3DDevice9_EndScene(device);
7299 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7302 if(i == 0) {
7303 color = getPixelColor(device, 480, 360);
7304 ok(color == 0x00ff0000,
7305 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7306 color = getPixelColor(device, 160, 120);
7307 ok(color == 0x00ffffff,
7308 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7309 color = getPixelColor(device, 160, 360);
7310 ok(color == 0x000000ff || !ub_ok,
7311 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7312 color = getPixelColor(device, 480, 120);
7313 ok(color == 0x000000ff || !ub_ok,
7314 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7315 } else {
7316 color = getPixelColor(device, 480, 360);
7317 ok(color == 0x000000ff,
7318 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7319 color = getPixelColor(device, 160, 120);
7320 ok(color == 0x00ffffff,
7321 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7322 color = getPixelColor(device, 160, 360);
7323 ok(color == 0x00ff0000 || !ub_ok,
7324 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7325 color = getPixelColor(device, 480, 120);
7326 ok(color == 0x00ff0000 || !ub_ok,
7327 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7329 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7332 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7333 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7334 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7335 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7336 IDirect3DVertexBuffer9_Release(vb2);
7338 out:
7339 IDirect3DVertexBuffer9_Release(vb);
7340 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7341 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7342 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7343 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7344 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7345 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7346 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7349 struct vertex_float16color {
7350 float x, y, z;
7351 DWORD c1, c2;
7354 static void test_vshader_float16(IDirect3DDevice9 *device)
7356 HRESULT hr;
7357 DWORD color;
7358 void *data;
7359 static const D3DVERTEXELEMENT9 decl_elements[] = {
7360 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7361 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7362 D3DDECL_END()
7364 IDirect3DVertexDeclaration9 *vdecl = NULL;
7365 IDirect3DVertexBuffer9 *buffer = NULL;
7366 IDirect3DVertexShader9 *shader;
7367 DWORD shader_code[] = {
7368 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7369 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7370 0x90e40001, 0x0000ffff
7372 struct vertex_float16color quad[] = {
7373 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7374 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7375 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7376 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7378 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7379 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7380 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7381 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7383 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7384 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7385 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7386 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7388 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7389 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7390 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7391 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7395 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7397 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7398 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7399 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7400 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7401 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7402 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7404 hr = IDirect3DDevice9_BeginScene(device);
7405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7406 if(SUCCEEDED(hr)) {
7407 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7408 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7410 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7412 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7414 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7416 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7418 hr = IDirect3DDevice9_EndScene(device);
7419 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7421 color = getPixelColor(device, 480, 360);
7422 ok(color == 0x00ff0000,
7423 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7424 color = getPixelColor(device, 160, 120);
7425 ok(color == 0x00000000,
7426 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7427 color = getPixelColor(device, 160, 360);
7428 ok(color == 0x0000ff00,
7429 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7430 color = getPixelColor(device, 480, 120);
7431 ok(color == 0x000000ff,
7432 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7433 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7436 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7438 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7439 D3DPOOL_MANAGED, &buffer, NULL);
7440 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7441 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7442 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7443 memcpy(data, quad, sizeof(quad));
7444 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7445 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7446 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7447 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7449 hr = IDirect3DDevice9_BeginScene(device);
7450 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7451 if(SUCCEEDED(hr)) {
7452 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7453 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7454 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7455 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7456 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7457 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7458 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7459 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7461 hr = IDirect3DDevice9_EndScene(device);
7462 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7465 color = getPixelColor(device, 480, 360);
7466 ok(color == 0x00ff0000,
7467 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7468 color = getPixelColor(device, 160, 120);
7469 ok(color == 0x00000000,
7470 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7471 color = getPixelColor(device, 160, 360);
7472 ok(color == 0x0000ff00,
7473 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7474 color = getPixelColor(device, 480, 120);
7475 ok(color == 0x000000ff,
7476 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7477 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7479 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7480 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7481 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7482 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7483 IDirect3DDevice9_SetVertexShader(device, NULL);
7484 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7486 IDirect3DVertexDeclaration9_Release(vdecl);
7487 IDirect3DVertexShader9_Release(shader);
7488 IDirect3DVertexBuffer9_Release(buffer);
7491 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7493 D3DCAPS9 caps;
7494 IDirect3DTexture9 *texture;
7495 HRESULT hr;
7496 D3DLOCKED_RECT rect;
7497 unsigned int x, y;
7498 DWORD *dst, color;
7499 const float quad[] = {
7500 -1.0, -1.0, 0.1, -0.2, -0.2,
7501 1.0, -1.0, 0.1, 1.2, -0.2,
7502 -1.0, 1.0, 0.1, -0.2, 1.2,
7503 1.0, 1.0, 0.1, 1.2, 1.2
7505 memset(&caps, 0, sizeof(caps));
7507 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7508 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7509 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7510 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7511 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7512 "Card has conditional NP2 support without power of two restriction set\n");
7513 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7514 return;
7515 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7516 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7517 return;
7520 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7521 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7523 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7524 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7526 memset(&rect, 0, sizeof(rect));
7527 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7528 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7529 for(y = 0; y < 10; y++) {
7530 for(x = 0; x < 10; x++) {
7531 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7532 if(x == 0 || x == 9 || y == 0 || y == 9) {
7533 *dst = 0x00ff0000;
7534 } else {
7535 *dst = 0x000000ff;
7539 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7540 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7542 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7543 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7544 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7545 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7546 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7547 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7548 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7549 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7551 hr = IDirect3DDevice9_BeginScene(device);
7552 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7553 if(SUCCEEDED(hr)) {
7554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7555 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7557 hr = IDirect3DDevice9_EndScene(device);
7558 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7561 color = getPixelColor(device, 1, 1);
7562 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7563 color = getPixelColor(device, 639, 479);
7564 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7566 color = getPixelColor(device, 135, 101);
7567 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7568 color = getPixelColor(device, 140, 101);
7569 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7570 color = getPixelColor(device, 135, 105);
7571 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7572 color = getPixelColor(device, 140, 105);
7573 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7575 color = getPixelColor(device, 135, 376);
7576 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7577 color = getPixelColor(device, 140, 376);
7578 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7579 color = getPixelColor(device, 135, 379);
7580 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7581 color = getPixelColor(device, 140, 379);
7582 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7584 color = getPixelColor(device, 500, 101);
7585 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7586 color = getPixelColor(device, 504, 101);
7587 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7588 color = getPixelColor(device, 500, 105);
7589 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7590 color = getPixelColor(device, 504, 105);
7591 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7593 color = getPixelColor(device, 500, 376);
7594 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7595 color = getPixelColor(device, 504, 376);
7596 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7597 color = getPixelColor(device, 500, 380);
7598 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7599 color = getPixelColor(device, 504, 380);
7600 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7602 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7604 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7605 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7606 IDirect3DTexture9_Release(texture);
7609 static void vFace_register_test(IDirect3DDevice9 *device)
7611 HRESULT hr;
7612 DWORD color;
7613 const DWORD shader_code[] = {
7614 0xffff0300, /* ps_3_0 */
7615 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7616 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7617 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7618 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7619 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7620 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7621 0x0000ffff /* END */
7623 const DWORD vshader_code[] = {
7624 0xfffe0300, /* vs_3_0 */
7625 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7626 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7627 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7628 0x0000ffff /* end */
7630 IDirect3DPixelShader9 *shader;
7631 IDirect3DVertexShader9 *vshader;
7632 IDirect3DTexture9 *texture;
7633 IDirect3DSurface9 *surface, *backbuffer;
7634 const float quad[] = {
7635 -1.0, -1.0, 0.1,
7636 1.0, -1.0, 0.1,
7637 -1.0, 0.0, 0.1,
7639 1.0, -1.0, 0.1,
7640 1.0, 0.0, 0.1,
7641 -1.0, 0.0, 0.1,
7643 -1.0, 0.0, 0.1,
7644 -1.0, 1.0, 0.1,
7645 1.0, 0.0, 0.1,
7647 1.0, 0.0, 0.1,
7648 -1.0, 1.0, 0.1,
7649 1.0, 1.0, 0.1,
7651 const float blit[] = {
7652 0.0, -1.0, 0.1, 0.0, 0.0,
7653 1.0, -1.0, 0.1, 1.0, 0.0,
7654 0.0, 1.0, 0.1, 0.0, 1.0,
7655 1.0, 1.0, 0.1, 1.0, 1.0,
7658 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7659 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7660 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7661 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7662 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7663 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7664 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7665 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7666 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7667 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7668 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7669 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7672 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7673 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7676 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7678 hr = IDirect3DDevice9_BeginScene(device);
7679 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7680 if(SUCCEEDED(hr)) {
7681 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7682 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7683 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7685 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7688 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7689 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7690 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7691 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7693 /* Blit the texture onto the back buffer to make it visible */
7694 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7695 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7696 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7697 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7698 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7699 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7700 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7701 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7703 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7705 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7707 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7708 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7710 hr = IDirect3DDevice9_EndScene(device);
7711 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7714 color = getPixelColor(device, 160, 360);
7715 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7716 color = getPixelColor(device, 160, 120);
7717 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7718 color = getPixelColor(device, 480, 360);
7719 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7720 color = getPixelColor(device, 480, 120);
7721 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7722 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7724 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7725 IDirect3DDevice9_SetTexture(device, 0, NULL);
7726 IDirect3DPixelShader9_Release(shader);
7727 IDirect3DVertexShader9_Release(vshader);
7728 IDirect3DSurface9_Release(surface);
7729 IDirect3DSurface9_Release(backbuffer);
7730 IDirect3DTexture9_Release(texture);
7733 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7735 HRESULT hr;
7736 DWORD color;
7737 int i;
7738 D3DCAPS9 caps;
7739 BOOL L6V5U5_supported = FALSE;
7740 IDirect3DTexture9 *tex1, *tex2;
7741 D3DLOCKED_RECT locked_rect;
7743 static const float quad[][7] = {
7744 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7745 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7746 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7747 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7750 static const D3DVERTEXELEMENT9 decl_elements[] = {
7751 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7752 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7753 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7754 D3DDECL_END()
7757 /* use asymmetric matrix to test loading */
7758 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7759 float scale, offset;
7761 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7762 IDirect3DTexture9 *texture = NULL;
7764 memset(&caps, 0, sizeof(caps));
7765 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7766 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7767 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7768 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7769 return;
7770 } else {
7771 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7772 * They report that it is not supported, but after that bump mapping works properly. So just test
7773 * if the format is generally supported, and check the BUMPENVMAP flag
7775 IDirect3D9 *d3d9;
7777 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7778 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7779 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7780 L6V5U5_supported = SUCCEEDED(hr);
7781 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7782 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7783 IDirect3D9_Release(d3d9);
7784 if(FAILED(hr)) {
7785 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7786 return;
7790 /* Generate the textures */
7791 generate_bumpmap_textures(device);
7793 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7794 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7795 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7796 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7797 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7798 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7800 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7802 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7803 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7805 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7809 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7810 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7811 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7812 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7814 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7816 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7817 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7819 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7820 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7822 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7823 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7826 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7827 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7828 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7829 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7831 hr = IDirect3DDevice9_BeginScene(device);
7832 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7835 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7837 hr = IDirect3DDevice9_EndScene(device);
7838 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7840 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7841 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7842 * But since testing the color match is not the purpose of the test don't be too picky
7844 color = getPixelColor(device, 320-32, 240);
7845 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7846 color = getPixelColor(device, 320+32, 240);
7847 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7848 color = getPixelColor(device, 320, 240-32);
7849 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7850 color = getPixelColor(device, 320, 240+32);
7851 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7852 color = getPixelColor(device, 320, 240);
7853 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7854 color = getPixelColor(device, 320+32, 240+32);
7855 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7856 color = getPixelColor(device, 320-32, 240+32);
7857 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7858 color = getPixelColor(device, 320+32, 240-32);
7859 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7860 color = getPixelColor(device, 320-32, 240-32);
7861 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7862 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7863 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7865 for(i = 0; i < 2; i++) {
7866 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7867 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7868 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7869 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7870 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7871 IDirect3DTexture9_Release(texture); /* To destroy it */
7874 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7875 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7876 goto cleanup;
7878 if(L6V5U5_supported == FALSE) {
7879 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7880 goto cleanup;
7883 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7884 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7885 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7886 * would only make this test more complicated
7888 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7889 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7890 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7891 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7893 memset(&locked_rect, 0, sizeof(locked_rect));
7894 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7895 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7896 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7897 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7898 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7900 memset(&locked_rect, 0, sizeof(locked_rect));
7901 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7902 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7903 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7904 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7905 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7907 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7908 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7909 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7910 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7912 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7913 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7914 scale = 2.0;
7915 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7916 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7917 offset = 0.1;
7918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7919 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921 hr = IDirect3DDevice9_BeginScene(device);
7922 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7923 if(SUCCEEDED(hr)) {
7924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7925 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7926 hr = IDirect3DDevice9_EndScene(device);
7927 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7930 color = getPixelColor(device, 320, 240);
7931 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7932 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7933 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7935 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7937 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7939 /* Check a result scale factor > 1.0 */
7940 scale = 10;
7941 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7942 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7943 offset = 10;
7944 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7945 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7947 hr = IDirect3DDevice9_BeginScene(device);
7948 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7949 if(SUCCEEDED(hr)) {
7950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7951 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7952 hr = IDirect3DDevice9_EndScene(device);
7953 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7955 color = getPixelColor(device, 320, 240);
7956 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7957 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7958 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7960 /* Check clamping in the scale factor calculation */
7961 scale = 1000;
7962 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7963 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7964 offset = -1;
7965 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7966 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7968 hr = IDirect3DDevice9_BeginScene(device);
7969 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7970 if(SUCCEEDED(hr)) {
7971 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7972 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7973 hr = IDirect3DDevice9_EndScene(device);
7974 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7976 color = getPixelColor(device, 320, 240);
7977 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7978 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7979 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7981 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7982 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7983 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7984 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7986 IDirect3DTexture9_Release(tex1);
7987 IDirect3DTexture9_Release(tex2);
7989 cleanup:
7990 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7991 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7992 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7993 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7996 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7997 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8000 static void stencil_cull_test(IDirect3DDevice9 *device) {
8001 HRESULT hr;
8002 IDirect3DSurface9 *depthstencil = NULL;
8003 D3DSURFACE_DESC desc;
8004 float quad1[] = {
8005 -1.0, -1.0, 0.1,
8006 0.0, -1.0, 0.1,
8007 -1.0, 0.0, 0.1,
8008 0.0, 0.0, 0.1,
8010 float quad2[] = {
8011 0.0, -1.0, 0.1,
8012 1.0, -1.0, 0.1,
8013 0.0, 0.0, 0.1,
8014 1.0, 0.0, 0.1,
8016 float quad3[] = {
8017 0.0, 0.0, 0.1,
8018 1.0, 0.0, 0.1,
8019 0.0, 1.0, 0.1,
8020 1.0, 1.0, 0.1,
8022 float quad4[] = {
8023 -1.0, 0.0, 0.1,
8024 0.0, 0.0, 0.1,
8025 -1.0, 1.0, 0.1,
8026 0.0, 1.0, 0.1,
8028 struct vertex painter[] = {
8029 {-1.0, -1.0, 0.0, 0x00000000},
8030 { 1.0, -1.0, 0.0, 0x00000000},
8031 {-1.0, 1.0, 0.0, 0x00000000},
8032 { 1.0, 1.0, 0.0, 0x00000000},
8034 WORD indices_cw[] = {0, 1, 3};
8035 WORD indices_ccw[] = {0, 2, 3};
8036 unsigned int i;
8037 DWORD color;
8039 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8040 if(depthstencil == NULL) {
8041 skip("No depth stencil buffer\n");
8042 return;
8044 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8045 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8046 IDirect3DSurface9_Release(depthstencil);
8047 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8048 skip("No 4 or 8 bit stencil surface\n");
8049 return;
8052 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8053 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8054 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8057 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8059 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8061 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8063 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8066 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8068 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8070 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8075 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077 /* First pass: Fill the stencil buffer with some values... */
8078 hr = IDirect3DDevice9_BeginScene(device);
8079 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8080 if(SUCCEEDED(hr))
8082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8083 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8084 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8085 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8086 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8087 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8088 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8089 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8092 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8094 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8095 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8096 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8097 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8098 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8099 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8100 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8103 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8104 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8105 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8106 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8107 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8108 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8109 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8113 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8114 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8115 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8116 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8117 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8118 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8120 hr = IDirect3DDevice9_EndScene(device);
8121 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8124 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8126 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8128 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8130 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8132 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8136 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8138 /* 2nd pass: Make the stencil values visible */
8139 hr = IDirect3DDevice9_BeginScene(device);
8140 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8141 if(SUCCEEDED(hr))
8143 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8144 for(i = 0; i < 16; i++) {
8145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8148 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8149 painter[1].diffuse = (i * 16);
8150 painter[2].diffuse = (i * 16);
8151 painter[3].diffuse = (i * 16);
8152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8153 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8155 hr = IDirect3DDevice9_EndScene(device);
8156 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8159 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8160 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8162 color = getPixelColor(device, 160, 420);
8163 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8164 color = getPixelColor(device, 160, 300);
8165 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8167 color = getPixelColor(device, 480, 420);
8168 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8169 color = getPixelColor(device, 480, 300);
8170 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8172 color = getPixelColor(device, 160, 180);
8173 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8174 color = getPixelColor(device, 160, 60);
8175 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8177 color = getPixelColor(device, 480, 180);
8178 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8179 color = getPixelColor(device, 480, 60);
8180 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8182 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8183 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8186 static void vpos_register_test(IDirect3DDevice9 *device)
8188 HRESULT hr;
8189 DWORD color;
8190 const DWORD shader_code[] = {
8191 0xffff0300, /* ps_3_0 */
8192 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8193 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8194 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8195 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8196 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8197 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8198 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8199 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8200 0x0000ffff /* end */
8202 const DWORD shader_frac_code[] = {
8203 0xffff0300, /* ps_3_0 */
8204 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8205 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8206 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8207 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8208 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8209 0x0000ffff /* end */
8211 const DWORD vshader_code[] = {
8212 0xfffe0300, /* vs_3_0 */
8213 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8214 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8215 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8216 0x0000ffff /* end */
8218 IDirect3DVertexShader9 *vshader;
8219 IDirect3DPixelShader9 *shader, *shader_frac;
8220 IDirect3DSurface9 *surface = NULL, *backbuffer;
8221 const float quad[] = {
8222 -1.0, -1.0, 0.1, 0.0, 0.0,
8223 1.0, -1.0, 0.1, 1.0, 0.0,
8224 -1.0, 1.0, 0.1, 0.0, 1.0,
8225 1.0, 1.0, 0.1, 1.0, 1.0,
8227 D3DLOCKED_RECT lr;
8228 float constant[4] = {1.0, 0.0, 320, 240};
8229 DWORD *pos;
8231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8233 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8234 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8235 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8236 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8237 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8238 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8239 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8240 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8241 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8244 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8245 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8246 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8248 hr = IDirect3DDevice9_BeginScene(device);
8249 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8250 if(SUCCEEDED(hr)) {
8251 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8252 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8254 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8255 hr = IDirect3DDevice9_EndScene(device);
8256 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8259 /* This has to be pixel exact */
8260 color = getPixelColor(device, 319, 239);
8261 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8262 color = getPixelColor(device, 320, 239);
8263 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8264 color = getPixelColor(device, 319, 240);
8265 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8266 color = getPixelColor(device, 320, 240);
8267 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8268 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8270 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8271 &surface, NULL);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8273 hr = IDirect3DDevice9_BeginScene(device);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8275 if(SUCCEEDED(hr)) {
8276 constant[2] = 16; constant[3] = 16;
8277 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8278 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8279 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8280 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8282 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8283 hr = IDirect3DDevice9_EndScene(device);
8284 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8286 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8287 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8289 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8290 color = *pos & 0x00ffffff;
8291 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8292 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8293 color = *pos & 0x00ffffff;
8294 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8295 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8296 color = *pos & 0x00ffffff;
8297 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8298 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8299 color = *pos & 0x00ffffff;
8300 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8302 hr = IDirect3DSurface9_UnlockRect(surface);
8303 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8305 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8306 * have full control over the multisampling setting inside this test
8308 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8309 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8310 hr = IDirect3DDevice9_BeginScene(device);
8311 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8312 if(SUCCEEDED(hr)) {
8313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8314 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8315 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8316 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8317 hr = IDirect3DDevice9_EndScene(device);
8318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8320 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8323 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8324 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8326 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8327 color = *pos & 0x00ffffff;
8328 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8330 hr = IDirect3DSurface9_UnlockRect(surface);
8331 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8333 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8334 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8335 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8336 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8337 IDirect3DPixelShader9_Release(shader);
8338 IDirect3DPixelShader9_Release(shader_frac);
8339 IDirect3DVertexShader9_Release(vshader);
8340 if(surface) IDirect3DSurface9_Release(surface);
8341 IDirect3DSurface9_Release(backbuffer);
8344 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8346 D3DCOLOR color;
8348 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8349 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8350 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8351 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8352 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8354 ++r;
8355 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8356 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8357 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8358 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8359 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8361 return TRUE;
8364 static void pointsize_test(IDirect3DDevice9 *device)
8366 HRESULT hr;
8367 D3DCAPS9 caps;
8368 D3DMATRIX matrix;
8369 D3DMATRIX identity;
8370 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8371 DWORD color;
8372 IDirect3DSurface9 *rt, *backbuffer;
8373 IDirect3DTexture9 *tex1, *tex2;
8374 RECT rect = {0, 0, 128, 128};
8375 D3DLOCKED_RECT lr;
8376 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8377 0x00000000, 0x00000000};
8378 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8379 0x00000000, 0x0000ff00};
8381 const float vertices[] = {
8382 64, 64, 0.1,
8383 128, 64, 0.1,
8384 192, 64, 0.1,
8385 256, 64, 0.1,
8386 320, 64, 0.1,
8387 384, 64, 0.1,
8388 448, 64, 0.1,
8389 512, 64, 0.1,
8392 /* 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 */
8393 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;
8394 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;
8395 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;
8396 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;
8398 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;
8399 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;
8400 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;
8401 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;
8403 memset(&caps, 0, sizeof(caps));
8404 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8405 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8406 if(caps.MaxPointSize < 32.0) {
8407 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8408 return;
8411 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8412 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8413 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8414 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8415 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8416 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8417 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8418 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8420 hr = IDirect3DDevice9_BeginScene(device);
8421 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8422 if (SUCCEEDED(hr))
8424 ptsize = 15.0;
8425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8428 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8430 ptsize = 31.0;
8431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8432 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8434 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8436 ptsize = 30.75;
8437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8438 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8440 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8442 if (caps.MaxPointSize >= 63.0)
8444 ptsize = 63.0;
8445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8446 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8447 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8448 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8450 ptsize = 62.75;
8451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8457 ptsize = 1.0;
8458 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8459 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8461 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8464 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8465 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8466 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8468 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8469 ptsize = 15.0;
8470 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8471 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8472 ptsize = 1.0;
8473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8474 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8475 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8476 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8478 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8479 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8481 /* pointsize < pointsize_min < pointsize_max?
8482 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8483 ptsize = 1.0;
8484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8485 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8486 ptsize = 15.0;
8487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8488 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8490 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8493 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8495 hr = IDirect3DDevice9_EndScene(device);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8499 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8500 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8501 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8503 if (caps.MaxPointSize >= 63.0)
8505 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8506 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8509 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8510 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8511 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8512 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8513 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8515 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8517 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8518 * generates texture coordinates for the point(result: Yes, it does)
8520 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8521 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8522 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8525 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8527 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8528 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8529 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8530 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8531 memset(&lr, 0, sizeof(lr));
8532 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8533 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8534 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8535 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8536 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8537 memset(&lr, 0, sizeof(lr));
8538 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8539 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8540 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8541 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8542 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8543 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8544 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8545 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8547 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8548 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8549 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8550 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8551 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8553 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8555 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8556 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8560 ptsize = 32.0;
8561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8562 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8564 hr = IDirect3DDevice9_BeginScene(device);
8565 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8566 if(SUCCEEDED(hr))
8568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8569 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8570 hr = IDirect3DDevice9_EndScene(device);
8571 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8574 color = getPixelColor(device, 64-4, 64-4);
8575 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8576 color = getPixelColor(device, 64-4, 64+4);
8577 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8578 color = getPixelColor(device, 64+4, 64+4);
8579 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8580 color = getPixelColor(device, 64+4, 64-4);
8581 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8582 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8584 U(matrix).m[0][0] = 1.0f / 64.0f;
8585 U(matrix).m[1][1] = -1.0f / 64.0f;
8586 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8587 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8589 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8590 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8592 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8593 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8594 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8596 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8597 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8598 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8599 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8601 hr = IDirect3DDevice9_BeginScene(device);
8602 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8604 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8605 hr = IDirect3DDevice9_EndScene(device);
8606 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8608 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8609 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8610 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8611 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8612 IDirect3DSurface9_Release(backbuffer);
8613 IDirect3DSurface9_Release(rt);
8615 color = getPixelColor(device, 64-4, 64-4);
8616 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8617 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8618 color = getPixelColor(device, 64+4, 64-4);
8619 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8620 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8621 color = getPixelColor(device, 64-4, 64+4);
8622 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8623 "Expected color 0x00000000, got 0x%08x.\n", color);
8624 color = getPixelColor(device, 64+4, 64+4);
8625 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8626 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8628 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8629 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8631 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8632 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8633 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8634 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8635 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8637 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8638 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8639 IDirect3DTexture9_Release(tex1);
8640 IDirect3DTexture9_Release(tex2);
8642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8643 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8646 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8650 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8652 static const DWORD vshader_code[] =
8654 0xfffe0300, /* vs_3_0 */
8655 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8656 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8657 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8658 0x0000ffff /* end */
8660 static const DWORD pshader_code[] =
8662 0xffff0300, /* ps_3_0 */
8663 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8664 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8665 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8666 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8667 0x0000ffff /* end */
8670 HRESULT hr;
8671 IDirect3DVertexShader9 *vs;
8672 IDirect3DPixelShader9 *ps;
8673 IDirect3DTexture9 *tex1, *tex2;
8674 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8675 D3DCAPS9 caps;
8676 DWORD color;
8677 float quad[] = {
8678 -1.0, -1.0, 0.1,
8679 1.0, -1.0, 0.1,
8680 -1.0, 1.0, 0.1,
8681 1.0, 1.0, 0.1,
8683 float texquad[] = {
8684 -1.0, -1.0, 0.1, 0.0, 0.0,
8685 0.0, -1.0, 0.1, 1.0, 0.0,
8686 -1.0, 1.0, 0.1, 0.0, 1.0,
8687 0.0, 1.0, 0.1, 1.0, 1.0,
8689 0.0, -1.0, 0.1, 0.0, 0.0,
8690 1.0, -1.0, 0.1, 1.0, 0.0,
8691 0.0, 1.0, 0.1, 0.0, 1.0,
8692 1.0, 1.0, 0.1, 1.0, 1.0,
8695 memset(&caps, 0, sizeof(caps));
8696 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8697 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8698 if(caps.NumSimultaneousRTs < 2) {
8699 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8700 return;
8703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8704 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8706 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8707 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8708 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8710 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8711 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8712 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8713 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8714 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8715 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8716 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8717 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8718 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8719 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8721 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8722 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8723 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8724 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8725 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8726 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8728 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8729 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8730 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8731 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8732 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8733 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8734 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8735 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8736 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8737 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8740 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8741 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8742 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8743 color = getPixelColorFromSurface(readback, 8, 8);
8744 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8745 "Expected color 0x000000ff, got 0x%08x.\n", color);
8746 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8747 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8748 color = getPixelColorFromSurface(readback, 8, 8);
8749 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8750 "Expected color 0x000000ff, got 0x%08x.\n", color);
8752 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8753 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8754 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8755 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8756 color = getPixelColorFromSurface(readback, 8, 8);
8757 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8758 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8759 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8760 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8761 color = getPixelColorFromSurface(readback, 8, 8);
8762 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8763 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8765 hr = IDirect3DDevice9_BeginScene(device);
8766 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8767 if(SUCCEEDED(hr)) {
8768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8769 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8771 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8772 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8773 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8774 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8775 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8776 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8777 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8778 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8779 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8780 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8782 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8783 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8785 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8787 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8788 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8790 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8792 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8793 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8795 hr = IDirect3DDevice9_EndScene(device);
8796 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8799 color = getPixelColor(device, 160, 240);
8800 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8801 color = getPixelColor(device, 480, 240);
8802 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8803 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8805 IDirect3DPixelShader9_Release(ps);
8806 IDirect3DVertexShader9_Release(vs);
8807 IDirect3DTexture9_Release(tex1);
8808 IDirect3DTexture9_Release(tex2);
8809 IDirect3DSurface9_Release(surf1);
8810 IDirect3DSurface9_Release(surf2);
8811 IDirect3DSurface9_Release(backbuf);
8812 IDirect3DSurface9_Release(readback);
8815 struct formats {
8816 const char *fmtName;
8817 D3DFORMAT textureFormat;
8818 DWORD resultColorBlending;
8819 DWORD resultColorNoBlending;
8822 static const struct formats test_formats[] = {
8823 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8824 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8825 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8826 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8827 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8828 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8829 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8830 { NULL, 0 }
8833 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8835 HRESULT hr;
8836 IDirect3DTexture9 *offscreenTexture = NULL;
8837 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8838 IDirect3D9 *d3d = NULL;
8839 DWORD color;
8840 DWORD r0, g0, b0, r1, g1, b1;
8841 int fmt_index;
8843 static const float quad[][5] = {
8844 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8845 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8846 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8847 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8850 /* Quad with R=0x10, G=0x20 */
8851 static const struct vertex quad1[] = {
8852 {-1.0f, -1.0f, 0.1f, 0x80102000},
8853 {-1.0f, 1.0f, 0.1f, 0x80102000},
8854 { 1.0f, -1.0f, 0.1f, 0x80102000},
8855 { 1.0f, 1.0f, 0.1f, 0x80102000},
8858 /* Quad with R=0x20, G=0x10 */
8859 static const struct vertex quad2[] = {
8860 {-1.0f, -1.0f, 0.1f, 0x80201000},
8861 {-1.0f, 1.0f, 0.1f, 0x80201000},
8862 { 1.0f, -1.0f, 0.1f, 0x80201000},
8863 { 1.0f, 1.0f, 0.1f, 0x80201000},
8866 IDirect3DDevice9_GetDirect3D(device, &d3d);
8868 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8869 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8870 if(!backbuffer) {
8871 goto out;
8874 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8876 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8877 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8878 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8879 continue;
8882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8883 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8885 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8886 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8887 if(!offscreenTexture) {
8888 continue;
8891 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8892 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8893 if(!offscreen) {
8894 continue;
8897 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8898 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8900 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8901 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8903 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8904 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8905 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8906 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8907 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8909 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8911 /* Below we will draw two quads with different colors and try to blend them together.
8912 * The result color is compared with the expected outcome.
8914 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8915 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8916 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8917 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8918 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8921 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8923 /* Draw a quad using color 0x0010200 */
8924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8925 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8927 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8929 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8931 /* Draw a quad using color 0x0020100 */
8932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8933 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8935 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8937 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8939 /* We don't want to blend the result on the backbuffer */
8940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8941 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8943 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8944 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8945 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8946 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8947 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8949 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8950 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8952 /* This time with the texture */
8953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8954 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8956 IDirect3DDevice9_EndScene(device);
8959 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8960 /* Compare the color of the center quad with our expectation */
8961 color = getPixelColor(device, 320, 240);
8962 r0 = (color & 0x00ff0000) >> 16;
8963 g0 = (color & 0x0000ff00) >> 8;
8964 b0 = (color & 0x000000ff) >> 0;
8966 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8967 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8968 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8970 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8971 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8972 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8973 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8974 } else {
8975 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8976 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8977 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8978 color = getPixelColor(device, 320, 240);
8979 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);
8981 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8983 IDirect3DDevice9_SetTexture(device, 0, NULL);
8984 if(offscreenTexture) {
8985 IDirect3DTexture9_Release(offscreenTexture);
8987 if(offscreen) {
8988 IDirect3DSurface9_Release(offscreen);
8992 out:
8993 /* restore things */
8994 if(backbuffer) {
8995 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8996 IDirect3DSurface9_Release(backbuffer);
9000 static void tssargtemp_test(IDirect3DDevice9 *device)
9002 HRESULT hr;
9003 DWORD color;
9004 static const struct vertex quad[] = {
9005 {-1.0, -1.0, 0.1, 0x00ff0000},
9006 { 1.0, -1.0, 0.1, 0x00ff0000},
9007 {-1.0, 1.0, 0.1, 0x00ff0000},
9008 { 1.0, 1.0, 0.1, 0x00ff0000}
9010 D3DCAPS9 caps;
9012 memset(&caps, 0, sizeof(caps));
9013 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9014 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9015 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9016 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9017 return;
9020 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9021 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9024 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9026 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9028 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9029 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9030 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9031 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9032 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9033 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9035 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9036 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9037 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9038 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9039 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9040 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9042 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9043 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9047 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9050 hr = IDirect3DDevice9_BeginScene(device);
9051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9052 if(SUCCEEDED(hr)) {
9053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9054 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9055 hr = IDirect3DDevice9_EndScene(device);
9056 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9058 color = getPixelColor(device, 320, 240);
9059 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9060 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9062 /* Set stage 1 back to default */
9063 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9064 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9065 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9066 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9067 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9068 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9069 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9070 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9071 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9072 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9075 struct testdata
9077 DWORD idxVertex; /* number of instances in the first stream */
9078 DWORD idxColor; /* number of instances in the second stream */
9079 DWORD idxInstance; /* should be 1 ?? */
9080 DWORD color1; /* color 1 instance */
9081 DWORD color2; /* color 2 instance */
9082 DWORD color3; /* color 3 instance */
9083 DWORD color4; /* color 4 instance */
9084 WORD strVertex; /* specify which stream to use 0-2*/
9085 WORD strColor;
9086 WORD strInstance;
9089 static const struct testdata testcases[]=
9091 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9092 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9093 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9094 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9095 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9096 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9097 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9098 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9099 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9100 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9101 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9102 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9103 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9104 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9105 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9107 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9108 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9112 /* Drawing Indexed Geometry with instances*/
9113 static void stream_test(IDirect3DDevice9 *device)
9115 IDirect3DVertexBuffer9 *vb = NULL;
9116 IDirect3DVertexBuffer9 *vb2 = NULL;
9117 IDirect3DVertexBuffer9 *vb3 = NULL;
9118 IDirect3DIndexBuffer9 *ib = NULL;
9119 IDirect3DVertexDeclaration9 *pDecl = NULL;
9120 IDirect3DVertexShader9 *shader = NULL;
9121 HRESULT hr;
9122 BYTE *data;
9123 DWORD color;
9124 DWORD ind;
9125 unsigned i;
9127 const DWORD shader_code[] =
9129 0xfffe0101, /* vs_1_1 */
9130 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9131 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9132 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9133 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9134 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9135 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9136 0x0000ffff
9139 const float quad[][3] =
9141 {-0.5f, -0.5f, 1.1f}, /*0 */
9142 {-0.5f, 0.5f, 1.1f}, /*1 */
9143 { 0.5f, -0.5f, 1.1f}, /*2 */
9144 { 0.5f, 0.5f, 1.1f}, /*3 */
9147 const float vertcolor[][4] =
9149 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9150 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9151 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9152 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9155 /* 4 position for 4 instances */
9156 const float instancepos[][3] =
9158 {-0.6f,-0.6f, 0.0f},
9159 { 0.6f,-0.6f, 0.0f},
9160 { 0.6f, 0.6f, 0.0f},
9161 {-0.6f, 0.6f, 0.0f},
9164 short indices[] = {0, 1, 2, 1, 2, 3};
9166 D3DVERTEXELEMENT9 decl[] =
9168 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9169 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9170 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9171 D3DDECL_END()
9174 /* set the default value because it isn't done in wine? */
9175 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9176 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9178 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9179 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9180 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9182 /* check wrong cases */
9183 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9184 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9185 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9186 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9187 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9188 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9189 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9190 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9191 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9192 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9193 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9194 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9195 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9196 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9197 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9198 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9199 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9200 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9201 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9202 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9204 /* set the default value back */
9205 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9206 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9208 /* create all VertexBuffers*/
9209 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9210 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9211 if(!vb) {
9212 skip("Failed to create a vertex buffer\n");
9213 return;
9215 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9216 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9217 if(!vb2) {
9218 skip("Failed to create a vertex buffer\n");
9219 goto out;
9221 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9222 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9223 if(!vb3) {
9224 skip("Failed to create a vertex buffer\n");
9225 goto out;
9228 /* create IndexBuffer*/
9229 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9230 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9231 if(!ib) {
9232 skip("Failed to create a index buffer\n");
9233 goto out;
9236 /* copy all Buffers (Vertex + Index)*/
9237 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9238 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9239 memcpy(data, quad, sizeof(quad));
9240 hr = IDirect3DVertexBuffer9_Unlock(vb);
9241 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9242 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9243 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9244 memcpy(data, vertcolor, sizeof(vertcolor));
9245 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9246 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9247 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9248 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9249 memcpy(data, instancepos, sizeof(instancepos));
9250 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9251 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9252 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9253 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9254 memcpy(data, indices, sizeof(indices));
9255 hr = IDirect3DIndexBuffer9_Unlock(ib);
9256 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9258 /* create VertexShader */
9259 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9260 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9261 if(!shader) {
9262 skip("Failed to create a vetex shader\n");
9263 goto out;
9266 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9267 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9269 hr = IDirect3DDevice9_SetIndices(device, ib);
9270 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9272 /* run all tests */
9273 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9275 struct testdata act = testcases[i];
9276 decl[0].Stream = act.strVertex;
9277 decl[1].Stream = act.strColor;
9278 decl[2].Stream = act.strInstance;
9279 /* create VertexDeclarations */
9280 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9281 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9283 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9284 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9286 hr = IDirect3DDevice9_BeginScene(device);
9287 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9288 if(SUCCEEDED(hr))
9290 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9291 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9293 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9294 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9295 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9296 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9298 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9299 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9300 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9301 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9303 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9304 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9305 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9306 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9308 /* don't know if this is right (1*3 and 4*1)*/
9309 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9310 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9311 hr = IDirect3DDevice9_EndScene(device);
9312 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9314 /* set all StreamSource && StreamSourceFreq back to default */
9315 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9316 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9317 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9318 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9319 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9320 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9321 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9322 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9323 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9324 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9325 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9326 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9329 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9330 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9332 color = getPixelColor(device, 160, 360);
9333 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9334 color = getPixelColor(device, 480, 360);
9335 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9336 color = getPixelColor(device, 480, 120);
9337 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9338 color = getPixelColor(device, 160, 120);
9339 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9341 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9342 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9345 hr = IDirect3DDevice9_SetIndices(device, NULL);
9346 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9348 out:
9349 if(vb) IDirect3DVertexBuffer9_Release(vb);
9350 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9351 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9352 if(ib)IDirect3DIndexBuffer9_Release(ib);
9353 if(shader)IDirect3DVertexShader9_Release(shader);
9356 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9357 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9358 IDirect3DTexture9 *dsttex = NULL;
9359 HRESULT hr;
9360 DWORD color;
9361 D3DRECT r1 = {0, 0, 50, 50 };
9362 D3DRECT r2 = {50, 0, 100, 50 };
9363 D3DRECT r3 = {50, 50, 100, 100};
9364 D3DRECT r4 = {0, 50, 50, 100};
9365 const float quad[] = {
9366 -1.0, -1.0, 0.1, 0.0, 0.0,
9367 1.0, -1.0, 0.1, 1.0, 0.0,
9368 -1.0, 1.0, 0.1, 0.0, 1.0,
9369 1.0, 1.0, 0.1, 1.0, 1.0,
9372 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9373 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9375 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9376 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9377 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9378 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9380 if(!src || !dsttex) {
9381 skip("One or more test resources could not be created\n");
9382 goto cleanup;
9385 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9386 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9388 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9389 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9391 /* Clear the StretchRect destination for debugging */
9392 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9393 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9395 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9397 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9398 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9400 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9401 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9402 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9403 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9404 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9405 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9406 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9407 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9409 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9410 * the target -> texture GL blit path
9412 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9413 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9414 IDirect3DSurface9_Release(dst);
9416 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9417 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9419 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9421 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9422 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9423 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9424 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9425 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9426 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9428 hr = IDirect3DDevice9_BeginScene(device);
9429 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9430 if(SUCCEEDED(hr)) {
9431 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9432 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9433 hr = IDirect3DDevice9_EndScene(device);
9434 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9437 color = getPixelColor(device, 160, 360);
9438 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9439 color = getPixelColor(device, 480, 360);
9440 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9441 color = getPixelColor(device, 480, 120);
9442 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9443 color = getPixelColor(device, 160, 120);
9444 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9448 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9449 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9450 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9451 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9453 cleanup:
9454 if(src) IDirect3DSurface9_Release(src);
9455 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9456 if(dsttex) IDirect3DTexture9_Release(dsttex);
9459 static void texop_test(IDirect3DDevice9 *device)
9461 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9462 IDirect3DTexture9 *texture = NULL;
9463 D3DLOCKED_RECT locked_rect;
9464 D3DCOLOR color;
9465 D3DCAPS9 caps;
9466 HRESULT hr;
9467 unsigned i;
9469 static const struct {
9470 float x, y, z;
9471 float s, t;
9472 D3DCOLOR diffuse;
9473 } quad[] = {
9474 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9475 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9476 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9477 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9480 static const D3DVERTEXELEMENT9 decl_elements[] = {
9481 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9482 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9483 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9484 D3DDECL_END()
9487 static const struct {
9488 D3DTEXTUREOP op;
9489 const char *name;
9490 DWORD caps_flag;
9491 D3DCOLOR result;
9492 } test_data[] = {
9493 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9494 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9495 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9496 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9497 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9498 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9499 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9500 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9501 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9502 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9503 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9504 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9505 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9506 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9507 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9508 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9509 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9510 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9511 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9512 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9513 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9514 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9515 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9518 memset(&caps, 0, sizeof(caps));
9519 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9520 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9522 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9523 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9524 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9525 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9527 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9528 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9529 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9530 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9531 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9532 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9533 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9534 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9535 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9537 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9538 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9539 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9540 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9541 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9542 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9544 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9545 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9548 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9550 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9552 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9554 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9555 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9557 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9559 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9561 skip("tex operation %s not supported\n", test_data[i].name);
9562 continue;
9565 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9566 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9568 hr = IDirect3DDevice9_BeginScene(device);
9569 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9572 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9574 hr = IDirect3DDevice9_EndScene(device);
9575 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9577 color = getPixelColor(device, 320, 240);
9578 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9579 test_data[i].name, color, test_data[i].result);
9581 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9582 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9585 if (texture) IDirect3DTexture9_Release(texture);
9586 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9589 static void yuv_color_test(IDirect3DDevice9 *device) {
9590 HRESULT hr;
9591 IDirect3DSurface9 *surface = NULL, *target = NULL;
9592 unsigned int fmt, i;
9593 D3DFORMAT format;
9594 const char *fmt_string;
9595 D3DLOCKED_RECT lr;
9596 IDirect3D9 *d3d;
9597 HRESULT color;
9598 DWORD ref_color_left, ref_color_right;
9600 struct {
9601 DWORD in; /* The input color */
9602 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9603 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9604 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9605 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9606 } test_data[] = {
9607 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9608 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9609 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9610 * that
9612 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9613 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9614 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9615 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9616 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9617 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9618 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9619 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9620 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9621 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9622 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9623 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9624 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9625 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9627 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9628 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9629 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9630 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9633 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9634 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9635 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9636 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9638 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9639 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9641 for(fmt = 0; fmt < 2; fmt++) {
9642 if(fmt == 0) {
9643 format = D3DFMT_UYVY;
9644 fmt_string = "D3DFMT_UYVY";
9645 } else {
9646 format = D3DFMT_YUY2;
9647 fmt_string = "D3DFMT_YUY2";
9650 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9651 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9653 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9654 D3DRTYPE_SURFACE, format) != D3D_OK) {
9655 skip("%s is not supported\n", fmt_string);
9656 continue;
9659 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9660 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9661 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9663 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9664 if(fmt == 0) {
9665 ref_color_left = test_data[i].uyvy_left;
9666 ref_color_right = test_data[i].uyvy_right;
9667 } else {
9668 ref_color_left = test_data[i].yuy2_left;
9669 ref_color_right = test_data[i].yuy2_right;
9672 memset(&lr, 0, sizeof(lr));
9673 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9674 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9675 *((DWORD *) lr.pBits) = test_data[i].in;
9676 hr = IDirect3DSurface9_UnlockRect(surface);
9677 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9681 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9682 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9684 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9685 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9686 * want to add tests for the filtered pixels as well.
9688 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9689 * differently, so we need a max diff of 16
9691 color = getPixelColor(device, 40, 240);
9692 ok(color_match(color, ref_color_left, 18),
9693 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9694 test_data[i].in, color, ref_color_left, fmt_string);
9695 color = getPixelColor(device, 600, 240);
9696 ok(color_match(color, ref_color_right, 18),
9697 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9698 test_data[i].in, color, ref_color_right, fmt_string);
9699 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9700 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9702 IDirect3DSurface9_Release(surface);
9704 IDirect3DSurface9_Release(target);
9705 IDirect3D9_Release(d3d);
9708 static void texop_range_test(IDirect3DDevice9 *device)
9710 static const struct {
9711 float x, y, z;
9712 D3DCOLOR diffuse;
9713 } quad[] = {
9714 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9715 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9716 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9717 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9719 HRESULT hr;
9720 IDirect3DTexture9 *texture;
9721 D3DLOCKED_RECT locked_rect;
9722 D3DCAPS9 caps;
9723 DWORD color;
9725 /* We need ADD and SUBTRACT operations */
9726 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9727 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9728 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9729 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9730 return;
9732 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9733 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9734 return;
9737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9738 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9739 /* Stage 1: result = diffuse(=1.0) + diffuse
9740 * stage 2: result = result - tfactor(= 0.5)
9742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9743 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9744 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9745 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9746 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9747 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9748 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9749 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9750 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9751 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9752 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9753 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9754 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9755 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9757 hr = IDirect3DDevice9_BeginScene(device);
9758 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9760 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9761 hr = IDirect3DDevice9_EndScene(device);
9762 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9764 color = getPixelColor(device, 320, 240);
9765 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9766 color);
9767 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9768 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9770 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9771 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9772 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9773 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9774 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9775 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9776 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9777 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9778 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9780 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9781 * stage 2: result = result + diffuse(1.0)
9783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9784 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9785 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9786 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9787 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9788 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9789 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9790 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9791 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9792 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9793 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9794 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9795 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9796 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9798 hr = IDirect3DDevice9_BeginScene(device);
9799 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9801 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9802 hr = IDirect3DDevice9_EndScene(device);
9803 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9805 color = getPixelColor(device, 320, 240);
9806 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9807 color);
9808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9809 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9811 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9812 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9814 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9815 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9816 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9817 IDirect3DTexture9_Release(texture);
9820 static void alphareplicate_test(IDirect3DDevice9 *device) {
9821 struct vertex quad[] = {
9822 { -1.0, -1.0, 0.1, 0x80ff00ff },
9823 { 1.0, -1.0, 0.1, 0x80ff00ff },
9824 { -1.0, 1.0, 0.1, 0x80ff00ff },
9825 { 1.0, 1.0, 0.1, 0x80ff00ff },
9827 HRESULT hr;
9828 DWORD color;
9830 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9831 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9833 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9834 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9837 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9838 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9839 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9841 hr = IDirect3DDevice9_BeginScene(device);
9842 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9843 if(SUCCEEDED(hr)) {
9844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9845 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9846 hr = IDirect3DDevice9_EndScene(device);
9847 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9850 color = getPixelColor(device, 320, 240);
9851 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9852 color);
9853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9854 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9856 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9857 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9861 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9862 HRESULT hr;
9863 D3DCAPS9 caps;
9864 DWORD color;
9865 struct vertex quad[] = {
9866 { -1.0, -1.0, 0.1, 0x408080c0 },
9867 { 1.0, -1.0, 0.1, 0x408080c0 },
9868 { -1.0, 1.0, 0.1, 0x408080c0 },
9869 { 1.0, 1.0, 0.1, 0x408080c0 },
9872 memset(&caps, 0, sizeof(caps));
9873 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9874 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9875 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9876 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9877 return;
9880 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9881 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9884 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9886 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9887 * mov r0.a, diffuse.a
9888 * mov r0, r0.a
9890 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9891 * 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
9892 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9894 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9895 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9896 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9897 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9898 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9899 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9900 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9901 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9903 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9905 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9906 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9907 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9908 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9909 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9913 hr = IDirect3DDevice9_BeginScene(device);
9914 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9915 if(SUCCEEDED(hr)) {
9916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9917 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9918 hr = IDirect3DDevice9_EndScene(device);
9919 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9922 color = getPixelColor(device, 320, 240);
9923 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9924 color);
9925 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9926 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9928 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9929 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9930 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9931 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9932 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9933 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9936 static void zwriteenable_test(IDirect3DDevice9 *device) {
9937 HRESULT hr;
9938 DWORD color;
9939 struct vertex quad1[] = {
9940 { -1.0, -1.0, 0.1, 0x00ff0000},
9941 { -1.0, 1.0, 0.1, 0x00ff0000},
9942 { 1.0, -1.0, 0.1, 0x00ff0000},
9943 { 1.0, 1.0, 0.1, 0x00ff0000},
9945 struct vertex quad2[] = {
9946 { -1.0, -1.0, 0.9, 0x0000ff00},
9947 { -1.0, 1.0, 0.9, 0x0000ff00},
9948 { 1.0, -1.0, 0.9, 0x0000ff00},
9949 { 1.0, 1.0, 0.9, 0x0000ff00},
9952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9953 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9955 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9956 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9958 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9962 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9964 hr = IDirect3DDevice9_BeginScene(device);
9965 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9966 if(SUCCEEDED(hr)) {
9967 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9968 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9969 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9970 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9971 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9972 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9975 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9977 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9979 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9981 hr = IDirect3DDevice9_EndScene(device);
9982 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9985 color = getPixelColor(device, 320, 240);
9986 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9987 color);
9988 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9989 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9992 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9995 static void alphatest_test(IDirect3DDevice9 *device) {
9996 #define ALPHATEST_PASSED 0x0000ff00
9997 #define ALPHATEST_FAILED 0x00ff0000
9998 struct {
9999 D3DCMPFUNC func;
10000 DWORD color_less;
10001 DWORD color_equal;
10002 DWORD color_greater;
10003 } testdata[] = {
10004 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10005 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10006 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10007 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10008 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10009 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10010 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10011 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10013 unsigned int i, j;
10014 HRESULT hr;
10015 DWORD color;
10016 struct vertex quad[] = {
10017 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10018 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10019 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10020 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10022 D3DCAPS9 caps;
10024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10025 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10026 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10027 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10029 for(j = 0; j < 2; j++) {
10030 if(j == 1) {
10031 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10032 * the alpha test either for performance reasons(floating point RTs) or to work
10033 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10034 * codepath for ffp and shader in this case, and the test should cover both
10036 IDirect3DPixelShader9 *ps;
10037 DWORD shader_code[] = {
10038 0xffff0101, /* ps_1_1 */
10039 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10040 0x0000ffff /* end */
10042 memset(&caps, 0, sizeof(caps));
10043 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10044 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10045 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10046 break;
10049 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10050 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10051 IDirect3DDevice9_SetPixelShader(device, ps);
10052 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10053 IDirect3DPixelShader9_Release(ps);
10056 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10058 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10060 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10061 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10063 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10064 hr = IDirect3DDevice9_BeginScene(device);
10065 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10066 if(SUCCEEDED(hr)) {
10067 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10068 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10069 hr = IDirect3DDevice9_EndScene(device);
10070 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10072 color = getPixelColor(device, 320, 240);
10073 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10074 color, testdata[i].color_less, testdata[i].func);
10075 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10076 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10078 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10079 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10081 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10082 hr = IDirect3DDevice9_BeginScene(device);
10083 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10084 if(SUCCEEDED(hr)) {
10085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10086 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10087 hr = IDirect3DDevice9_EndScene(device);
10088 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10090 color = getPixelColor(device, 320, 240);
10091 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10092 color, testdata[i].color_equal, testdata[i].func);
10093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10094 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10097 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10100 hr = IDirect3DDevice9_BeginScene(device);
10101 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10102 if(SUCCEEDED(hr)) {
10103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10104 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10105 hr = IDirect3DDevice9_EndScene(device);
10106 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10108 color = getPixelColor(device, 320, 240);
10109 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10110 color, testdata[i].color_greater, testdata[i].func);
10111 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10112 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10117 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10118 IDirect3DDevice9_SetPixelShader(device, NULL);
10119 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10122 static void sincos_test(IDirect3DDevice9 *device) {
10123 const DWORD sin_shader_code[] = {
10124 0xfffe0200, /* vs_2_0 */
10125 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10126 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10127 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10128 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10129 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10130 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10131 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10132 0x0000ffff /* end */
10134 const DWORD cos_shader_code[] = {
10135 0xfffe0200, /* vs_2_0 */
10136 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10137 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10138 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10139 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10140 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10141 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10142 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10143 0x0000ffff /* end */
10145 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10146 HRESULT hr;
10147 struct {
10148 float x, y, z;
10149 } data[1280];
10150 unsigned int i;
10151 float sincosc1[4] = {D3DSINCOSCONST1};
10152 float sincosc2[4] = {D3DSINCOSCONST2};
10154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10157 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10158 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10159 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10160 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10161 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10162 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10163 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10164 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10165 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10166 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10168 /* Generate a point from -1 to 1 every 0.5 pixels */
10169 for(i = 0; i < 1280; i++) {
10170 data[i].x = (-640.0 + i) / 640.0;
10171 data[i].y = 0.0;
10172 data[i].z = 0.1;
10175 hr = IDirect3DDevice9_BeginScene(device);
10176 if(SUCCEEDED(hr)) {
10177 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10178 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10180 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10182 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10183 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10184 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10185 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10187 hr = IDirect3DDevice9_EndScene(device);
10188 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10190 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10191 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10192 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10194 IDirect3DDevice9_SetVertexShader(device, NULL);
10195 IDirect3DVertexShader9_Release(sin_shader);
10196 IDirect3DVertexShader9_Release(cos_shader);
10199 static void loop_index_test(IDirect3DDevice9 *device) {
10200 const DWORD shader_code[] = {
10201 0xfffe0200, /* vs_2_0 */
10202 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10203 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10204 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10205 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10206 0x0000001d, /* endloop */
10207 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10208 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10209 0x0000ffff /* END */
10211 IDirect3DVertexShader9 *shader;
10212 HRESULT hr;
10213 DWORD color;
10214 const float quad[] = {
10215 -1.0, -1.0, 0.1,
10216 1.0, -1.0, 0.1,
10217 -1.0, 1.0, 0.1,
10218 1.0, 1.0, 0.1
10220 const float zero[4] = {0, 0, 0, 0};
10221 const float one[4] = {1, 1, 1, 1};
10222 int i0[4] = {2, 10, -3, 0};
10223 float values[4];
10225 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10226 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10227 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10228 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10229 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10230 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10232 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10234 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10236 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10238 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10240 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10242 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10243 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10244 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10245 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10246 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10247 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10248 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10249 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10250 values[0] = 1.0;
10251 values[1] = 1.0;
10252 values[2] = 0.0;
10253 values[3] = 0.0;
10254 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10256 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10258 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10260 values[0] = -1.0;
10261 values[1] = 0.0;
10262 values[2] = 0.0;
10263 values[3] = 0.0;
10264 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10266 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10267 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10268 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10269 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10270 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10271 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10272 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10273 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10275 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10276 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10278 hr = IDirect3DDevice9_BeginScene(device);
10279 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10280 if(SUCCEEDED(hr))
10282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10283 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10284 hr = IDirect3DDevice9_EndScene(device);
10285 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10287 color = getPixelColor(device, 320, 240);
10288 ok(color_match(color, 0x0000ff00, 1),
10289 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10290 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10291 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10293 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10294 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10295 IDirect3DVertexShader9_Release(shader);
10298 static void sgn_test(IDirect3DDevice9 *device) {
10299 const DWORD shader_code[] = {
10300 0xfffe0200, /* vs_2_0 */
10301 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10302 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10303 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10304 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10305 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10306 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10307 0x0000ffff /* end */
10309 IDirect3DVertexShader9 *shader;
10310 HRESULT hr;
10311 DWORD color;
10312 const float quad[] = {
10313 -1.0, -1.0, 0.1,
10314 1.0, -1.0, 0.1,
10315 -1.0, 1.0, 0.1,
10316 1.0, 1.0, 0.1
10319 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10320 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10321 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10322 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10324 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10325 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10326 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10328 hr = IDirect3DDevice9_BeginScene(device);
10329 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10330 if(SUCCEEDED(hr))
10332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10333 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10334 hr = IDirect3DDevice9_EndScene(device);
10335 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10337 color = getPixelColor(device, 320, 240);
10338 ok(color_match(color, 0x008000ff, 1),
10339 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10340 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10341 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10343 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10344 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10345 IDirect3DVertexShader9_Release(shader);
10348 static void viewport_test(IDirect3DDevice9 *device) {
10349 HRESULT hr;
10350 DWORD color;
10351 D3DVIEWPORT9 vp, old_vp;
10352 BOOL draw_failed = TRUE;
10353 const float quad[] =
10355 -0.5, -0.5, 0.1,
10356 0.5, -0.5, 0.1,
10357 -0.5, 0.5, 0.1,
10358 0.5, 0.5, 0.1
10361 memset(&old_vp, 0, sizeof(old_vp));
10362 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10363 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10365 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10366 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10368 /* Test a viewport with Width and Height bigger than the surface dimensions
10370 * TODO: Test Width < surface.width, but X + Width > surface.width
10371 * TODO: Test Width < surface.width, what happens with the height?
10373 * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10374 * and Height fields bigger than the framebuffer. However, it later refuses
10375 * to draw.
10377 memset(&vp, 0, sizeof(vp));
10378 vp.X = 0;
10379 vp.Y = 0;
10380 vp.Width = 10000;
10381 vp.Height = 10000;
10382 vp.MinZ = 0.0;
10383 vp.MaxZ = 0.0;
10384 hr = IDirect3DDevice9_SetViewport(device, &vp);
10385 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10387 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10388 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10389 hr = IDirect3DDevice9_BeginScene(device);
10390 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10391 if(SUCCEEDED(hr))
10393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10394 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10395 draw_failed = FAILED(hr);
10396 hr = IDirect3DDevice9_EndScene(device);
10397 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10400 if(!draw_failed)
10402 color = getPixelColor(device, 158, 118);
10403 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10404 color = getPixelColor(device, 162, 118);
10405 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10406 color = getPixelColor(device, 158, 122);
10407 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10408 color = getPixelColor(device, 162, 122);
10409 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10411 color = getPixelColor(device, 478, 358);
10412 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10413 color = getPixelColor(device, 482, 358);
10414 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10415 color = getPixelColor(device, 478, 362);
10416 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10417 color = getPixelColor(device, 482, 362);
10418 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10421 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10422 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10424 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10425 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10428 /* This test tests depth clamping / clipping behaviour:
10429 * - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10430 * minimum/maximum z value.
10431 * - The viewport's MinZ/MaxZ is irrelevant for this.
10432 * - When D3DRS_CLIPPING is enabled depth values are clipped.
10433 * - Pretransformed vertices behave the same as regular vertices.
10435 static void depth_clamp_test(IDirect3DDevice9 *device)
10437 const struct tvertex quad1[] =
10439 { 0, 0, 5.0f, 1.0, 0xff002b7f},
10440 { 640, 0, 5.0f, 1.0, 0xff002b7f},
10441 { 0, 480, 5.0f, 1.0, 0xff002b7f},
10442 { 640, 480, 5.0f, 1.0, 0xff002b7f},
10444 const struct tvertex quad2[] =
10446 { 0, 300, 10.0f, 1.0, 0xfff9e814},
10447 { 640, 300, 10.0f, 1.0, 0xfff9e814},
10448 { 0, 360, 10.0f, 1.0, 0xfff9e814},
10449 { 640, 360, 10.0f, 1.0, 0xfff9e814},
10451 const struct vertex quad3[] =
10453 {-0.65, 0.55, 5.0f, 0xffffffff},
10454 {-0.35, 0.55, 5.0f, 0xffffffff},
10455 {-0.65, 0.15, 5.0f, 0xffffffff},
10456 {-0.35, 0.15, 5.0f, 0xffffffff},
10458 const struct vertex quad4[] =
10460 {-0.87, 0.83, 10.0f, 0xffffffff},
10461 {-0.65, 0.83, 10.0f, 0xffffffff},
10462 {-0.87, 0.55, 10.0f, 0xffffffff},
10463 {-0.65, 0.55, 10.0f, 0xffffffff},
10465 const struct vertex quad5[] =
10467 { -0.5, 0.5, 10.0f, 0xff14f914},
10468 { 0.5, 0.5, 10.0f, 0xff14f914},
10469 { -0.5, -0.5, 10.0f, 0xff14f914},
10470 { 0.5, -0.5, 10.0f, 0xff14f914},
10472 const struct tvertex quad6[] =
10474 { 0, 120, 10.0f, 1.0, 0xfff91414},
10475 { 640, 120, 10.0f, 1.0, 0xfff91414},
10476 { 0, 180, 10.0f, 1.0, 0xfff91414},
10477 { 640, 180, 10.0f, 1.0, 0xfff91414},
10480 D3DVIEWPORT9 vp;
10481 D3DCOLOR color;
10482 HRESULT hr;
10484 vp.X = 0;
10485 vp.Y = 0;
10486 vp.Width = 640;
10487 vp.Height = 480;
10488 vp.MinZ = 0.0;
10489 vp.MaxZ = 7.5;
10491 hr = IDirect3DDevice9_SetViewport(device, &vp);
10492 if(FAILED(hr))
10494 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10495 * the tests because the 7.5 is just intended to show that it doesn't have
10496 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10497 * viewport and continue.
10499 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10500 vp.MaxZ = 1.0;
10501 hr = IDirect3DDevice9_SetViewport(device, &vp);
10503 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10505 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10506 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10509 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10511 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10513 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10515 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10517 hr = IDirect3DDevice9_BeginScene(device);
10518 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10520 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10521 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10524 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10526 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10528 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10529 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10532 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10534 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10537 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10540 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10542 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10543 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10546 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10548 hr = IDirect3DDevice9_EndScene(device);
10549 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10551 color = getPixelColor(device, 75, 75);
10552 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10553 color = getPixelColor(device, 150, 150);
10554 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10555 color = getPixelColor(device, 320, 240);
10556 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10557 color = getPixelColor(device, 320, 330);
10558 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10559 color = getPixelColor(device, 320, 330);
10560 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10562 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10563 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10565 vp.MinZ = 0.0;
10566 vp.MaxZ = 1.0;
10567 hr = IDirect3DDevice9_SetViewport(device, &vp);
10568 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10571 static void depth_bounds_test(IDirect3DDevice9 *device)
10573 const struct tvertex quad1[] =
10575 { 0, 0, 0.0f, 1, 0xfff9e814},
10576 { 640, 0, 0.0f, 1, 0xfff9e814},
10577 { 0, 480, 1.0f, 1, 0xfff9e814},
10578 { 640, 480, 1.0f, 1, 0xfff9e814},
10580 const struct tvertex quad2[] =
10582 { 0, 0, 0.6f, 1, 0xff002b7f},
10583 { 640, 0, 0.6f, 1, 0xff002b7f},
10584 { 0, 480, 0.6f, 1, 0xff002b7f},
10585 { 640, 480, 0.6f, 1, 0xff002b7f},
10587 const struct tvertex quad3[] =
10589 { 0, 100, 0.6f, 1, 0xfff91414},
10590 { 640, 100, 0.6f, 1, 0xfff91414},
10591 { 0, 160, 0.6f, 1, 0xfff91414},
10592 { 640, 160, 0.6f, 1, 0xfff91414},
10595 union {
10596 DWORD d;
10597 float f;
10598 } tmpvalue;
10600 IDirect3D9 *d3d = NULL;
10601 IDirect3DSurface9 *offscreen_surface = NULL;
10602 D3DCOLOR color;
10603 HRESULT hr;
10605 IDirect3DDevice9_GetDirect3D(device, &d3d);
10606 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10607 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10608 skip("No NVDB (depth bounds test) support\n");
10609 IDirect3D9_Release(d3d);
10610 return;
10612 IDirect3D9_Release(d3d);
10614 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10615 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10616 todo_wine ok(hr != D3D_OK, "Able to create surface, hr = %08x\n", hr);
10617 if(offscreen_surface)
10619 IDirect3DSurface9_Release(offscreen_surface);
10622 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10623 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10626 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10628 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10630 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10632 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10635 hr = IDirect3DDevice9_BeginScene(device);
10636 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10638 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10639 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10642 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10645 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10647 tmpvalue.f = 0.625;
10648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10649 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10651 tmpvalue.f = 0.75;
10652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10653 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10656 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10658 tmpvalue.f = 0.75;
10659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10660 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10663 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10666 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10668 hr = IDirect3DDevice9_EndScene(device);
10669 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10671 color = getPixelColor(device, 150, 130);
10672 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10673 color = getPixelColor(device, 150, 200);
10674 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10675 color = getPixelColor(device, 150, 300-5);
10676 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10677 color = getPixelColor(device, 150, 300+5);
10678 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10679 color = getPixelColor(device, 150, 330);
10680 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10681 color = getPixelColor(device, 150, 360-5);
10682 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10683 color = getPixelColor(device, 150, 360+5);
10684 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10686 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10687 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10690 static void depth_buffer_test(IDirect3DDevice9 *device)
10692 static const struct vertex quad1[] =
10694 { -1.0, 1.0, 0.33f, 0xff00ff00},
10695 { 1.0, 1.0, 0.33f, 0xff00ff00},
10696 { -1.0, -1.0, 0.33f, 0xff00ff00},
10697 { 1.0, -1.0, 0.33f, 0xff00ff00},
10699 static const struct vertex quad2[] =
10701 { -1.0, 1.0, 0.50f, 0xffff00ff},
10702 { 1.0, 1.0, 0.50f, 0xffff00ff},
10703 { -1.0, -1.0, 0.50f, 0xffff00ff},
10704 { 1.0, -1.0, 0.50f, 0xffff00ff},
10706 static const struct vertex quad3[] =
10708 { -1.0, 1.0, 0.66f, 0xffff0000},
10709 { 1.0, 1.0, 0.66f, 0xffff0000},
10710 { -1.0, -1.0, 0.66f, 0xffff0000},
10711 { 1.0, -1.0, 0.66f, 0xffff0000},
10713 static const DWORD expected_colors[4][4] =
10715 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10716 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10717 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10718 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10721 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10722 unsigned int i, j;
10723 D3DVIEWPORT9 vp;
10724 D3DCOLOR color;
10725 HRESULT hr;
10727 vp.X = 0;
10728 vp.Y = 0;
10729 vp.Width = 640;
10730 vp.Height = 480;
10731 vp.MinZ = 0.0;
10732 vp.MaxZ = 1.0;
10734 hr = IDirect3DDevice9_SetViewport(device, &vp);
10735 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10738 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10740 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10742 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10744 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10745 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10746 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10748 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10749 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10750 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10751 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10752 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10753 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10754 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10755 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10756 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10757 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10758 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10760 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10761 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10762 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10763 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10765 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10766 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10767 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10768 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10770 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10771 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10772 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10773 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10775 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10776 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10777 hr = IDirect3DDevice9_BeginScene(device);
10778 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10781 hr = IDirect3DDevice9_EndScene(device);
10782 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10784 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10785 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10786 IDirect3DSurface9_Release(backbuffer);
10787 IDirect3DSurface9_Release(rt3);
10788 IDirect3DSurface9_Release(rt2);
10789 IDirect3DSurface9_Release(rt1);
10791 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10792 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10794 hr = IDirect3DDevice9_BeginScene(device);
10795 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10797 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10799 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10800 hr = IDirect3DDevice9_EndScene(device);
10801 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10803 for (i = 0; i < 4; ++i)
10805 for (j = 0; j < 4; ++j)
10807 unsigned int x = 80 * ((2 * j) + 1);
10808 unsigned int y = 60 * ((2 * i) + 1);
10809 color = getPixelColor(device, x, y);
10810 ok(color_match(color, expected_colors[i][j], 0),
10811 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10815 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10816 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10819 static void intz_test(IDirect3DDevice9 *device)
10821 static const DWORD ps_code[] =
10823 0xffff0200, /* ps_2_0 */
10824 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10825 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10826 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
10827 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10828 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10829 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
10830 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
10831 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
10832 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
10833 0x0000ffff, /* end */
10835 struct
10837 float x, y, z;
10838 float s, t, p, q;
10840 quad[] =
10842 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
10843 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
10844 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
10845 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
10847 struct
10849 UINT x, y;
10850 D3DCOLOR color;
10852 expected_colors[] =
10854 {400, 60, D3DCOLOR_ARGB(0x00, 0x9f, 0xff, 0x00)},
10855 {560, 180, D3DCOLOR_ARGB(0x00, 0xdf, 0x55, 0x00)},
10856 {560, 300, D3DCOLOR_ARGB(0x00, 0xdf, 0x66, 0x00)},
10857 {400, 420, D3DCOLOR_ARGB(0x00, 0x9f, 0xb6, 0x00)},
10858 {240, 420, D3DCOLOR_ARGB(0x00, 0x60, 0x6d, 0x00)},
10859 { 80, 300, D3DCOLOR_ARGB(0x00, 0x20, 0x33, 0x00)},
10860 { 80, 180, D3DCOLOR_ARGB(0x00, 0x20, 0x55, 0x00)},
10861 {240, 60, D3DCOLOR_ARGB(0x00, 0x60, 0xff, 0x00)},
10864 IDirect3DSurface9 *original_ds, *original_rt, *rt;
10865 IDirect3DTexture9 *texture;
10866 IDirect3DPixelShader9 *ps;
10867 IDirect3DSurface9 *ds;
10868 IDirect3D9 *d3d9;
10869 D3DCAPS9 caps;
10870 HRESULT hr;
10871 UINT i;
10873 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10874 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
10875 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
10877 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
10878 return;
10881 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
10882 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
10884 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10885 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
10886 if (FAILED(hr))
10888 skip("No INTZ support, skipping INTZ test.\n");
10889 return;
10892 IDirect3D9_Release(d3d9);
10894 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
10895 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10896 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
10897 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10899 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
10900 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
10901 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
10902 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
10903 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
10904 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10905 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
10906 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
10908 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
10909 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10911 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10913 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10914 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10915 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10919 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10920 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10921 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10922 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10924 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10925 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10926 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10927 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10928 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10930 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
10931 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
10932 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
10933 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10935 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10936 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10937 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10939 /* Setup the depth/stencil surface. */
10940 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10941 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10943 hr = IDirect3DDevice9_BeginScene(device);
10944 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10946 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10947 hr = IDirect3DDevice9_EndScene(device);
10948 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
10951 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10952 IDirect3DSurface9_Release(ds);
10953 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
10954 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10955 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10956 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10957 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10958 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10960 /* Read the depth values back. */
10961 hr = IDirect3DDevice9_BeginScene(device);
10962 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10964 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10965 hr = IDirect3DDevice9_EndScene(device);
10966 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10968 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
10970 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
10971 ok(color_match(color, expected_colors[i].color, 1),
10972 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
10973 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
10976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10977 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10979 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
10980 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10981 IDirect3DSurface9_Release(original_ds);
10982 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10983 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10984 IDirect3DTexture9_Release(texture);
10985 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10986 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10987 IDirect3DPixelShader9_Release(ps);
10989 IDirect3DSurface9_Release(original_rt);
10990 IDirect3DSurface9_Release(rt);
10993 static void shadow_test(IDirect3DDevice9 *device)
10995 static const DWORD ps_code[] =
10997 0xffff0200, /* ps_2_0 */
10998 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10999 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11000 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11001 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11002 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11003 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11004 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11005 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11006 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11007 0x0000ffff, /* end */
11009 struct
11011 D3DFORMAT format;
11012 const char *name;
11014 formats[] =
11016 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11017 {D3DFMT_D32, "D3DFMT_D32"},
11018 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11019 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11020 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11021 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11022 {D3DFMT_D16, "D3DFMT_D16"},
11023 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11024 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11026 struct
11028 float x, y, z;
11029 float s, t, p, q;
11031 quad[] =
11033 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11034 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11035 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11036 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11038 struct
11040 UINT x, y;
11041 D3DCOLOR color;
11043 expected_colors[] =
11045 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11046 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11047 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11048 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11049 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11050 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11051 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11052 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11055 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11056 IDirect3DPixelShader9 *ps;
11057 IDirect3D9 *d3d9;
11058 D3DCAPS9 caps;
11059 HRESULT hr;
11060 UINT i;
11062 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11063 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11064 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11066 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11067 return;
11070 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11071 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11072 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11073 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11074 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11075 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11077 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11078 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11079 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11080 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11081 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11083 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11084 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11086 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11087 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11088 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11090 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11092 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11094 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11095 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11097 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11098 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11099 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11100 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11101 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11102 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11103 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11105 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11107 D3DFORMAT format = formats[i].format;
11108 IDirect3DTexture9 *texture;
11109 IDirect3DSurface9 *ds;
11110 unsigned int j;
11112 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11113 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11114 if (FAILED(hr)) continue;
11116 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11117 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11118 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11120 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11121 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11123 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11124 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11126 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11127 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11129 IDirect3DDevice9_SetPixelShader(device, NULL);
11130 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11132 /* Setup the depth/stencil surface. */
11133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11134 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11136 hr = IDirect3DDevice9_BeginScene(device);
11137 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11138 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11139 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11140 hr = IDirect3DDevice9_EndScene(device);
11141 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11143 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11144 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11145 IDirect3DSurface9_Release(ds);
11147 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11148 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11150 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11151 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11153 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11154 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11156 /* Do the actual shadow mapping. */
11157 hr = IDirect3DDevice9_BeginScene(device);
11158 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11160 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11161 hr = IDirect3DDevice9_EndScene(device);
11162 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11164 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11165 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11166 IDirect3DTexture9_Release(texture);
11168 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11170 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11171 ok(color_match(color, expected_colors[j].color, 0),
11172 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11173 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11174 formats[i].name, color);
11177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11178 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11182 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11183 IDirect3DPixelShader9_Release(ps);
11185 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11186 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11187 IDirect3DSurface9_Release(original_ds);
11189 IDirect3DSurface9_Release(original_rt);
11190 IDirect3DSurface9_Release(rt);
11192 IDirect3D9_Release(d3d9);
11195 static void fp_special_test(IDirect3DDevice9 *device)
11197 static const DWORD vs_header[] =
11199 0xfffe0200, /* vs_2_0 */
11200 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11201 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11202 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11205 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11206 static const DWORD vs_pow[] =
11207 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11208 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11209 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11210 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11211 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11212 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11214 static const DWORD vs_footer[] =
11216 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11217 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11218 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11219 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11220 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11221 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11222 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11223 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11224 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11225 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11226 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11227 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11228 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11229 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11230 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11231 0x0000ffff, /* end */
11234 static const struct
11236 const char *name;
11237 const DWORD *ops;
11238 DWORD size;
11239 D3DCOLOR color1;
11240 D3DCOLOR color2;
11242 vs_body[] =
11244 /* The basic ideas here are:
11245 * 2.0 * +/-INF == +/-INF
11246 * NAN != NAN
11248 * The vertex shader value is written to the red component, with 0.0
11249 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11250 * result in 0x00. The pixel shader value is written to the green
11251 * component, but here 0.0 also results in 0x00. The actual value is
11252 * written to the blue component.
11254 * There are at least two different ways for D3D implementations to
11255 * handle this. AMD seems to stick mostly to the D3D documentation,
11256 * and doesn't generate floating point specials in the first place.
11257 * Note that that doesn't just apply to functions like rcp and rsq,
11258 * but also basic mul, add, etc. nVidia seems to generate infinities,
11259 * but then clamp them before sending them to the interpolators. In
11260 * OpenGL these aren't clamped, and interpolating them generates NANs
11261 * in the fragment shader, unless flat shading is used (essentially
11262 * replicating the values instead of interpolating them).
11264 * I can't currently explain the nVidia results for pow and nrm.
11265 * They're not specials in the vertex shader, but look like -INF in
11266 * the pixel shader. */
11267 {"log", vs_log, sizeof(vs_log), 0x00000000 /* -FLT_MAX */, 0x00ff0000 /* clamp(-INF) */},
11268 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff /* +FLT_MAX */, 0x0000ff00 /* ??? */},
11269 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000 /* 0.0 */, 0x0000ff00 /* ??? */},
11270 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff /* +FLT_MAX */, 0x00ff00ff /* clamp(+INF) */},
11271 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000 /* -FLT_MAX */, 0x00ff0000 /* clamp(-INF) */},
11272 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff /* +FLT_MAX */, 0x00ff00ff /* clamp(+INF) */},
11273 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff /* +FLT_MAX */, 0x00ff00ff /* clamp(+INF) */},
11276 static const DWORD ps_code[] =
11278 0xffff0200, /* ps_2_0 */
11279 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11280 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11281 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11282 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11283 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11284 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11285 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11286 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11287 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11288 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11289 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11290 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11291 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11292 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11293 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11294 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11295 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11296 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11297 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11298 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11299 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11300 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11301 0x0000ffff, /* end */
11304 struct
11306 float x, y, z;
11307 float s;
11309 quad[] =
11311 { -1.0f, 1.0f, 0.0f, 0.0f},
11312 { 1.0f, 1.0f, 1.0f, 0.0f},
11313 { -1.0f, -1.0f, 0.0f, 0.0f},
11314 { 1.0f, -1.0f, 1.0f, 0.0f},
11317 IDirect3DPixelShader9 *ps;
11318 UINT body_size = 0;
11319 DWORD *vs_code;
11320 D3DCAPS9 caps;
11321 HRESULT hr;
11322 UINT i;
11324 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11325 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11326 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11328 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11329 return;
11332 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11333 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11335 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11336 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11337 IDirect3DDevice9_SetPixelShader(device, ps);
11338 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11341 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11344 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11346 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11348 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11351 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11352 memcpy(vs_code, vs_header, sizeof(vs_header));
11354 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11356 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11357 IDirect3DVertexShader9 *vs;
11358 D3DCOLOR color;
11360 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11361 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11362 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11364 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11365 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11366 IDirect3DDevice9_SetVertexShader(device, vs);
11367 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11369 hr = IDirect3DDevice9_BeginScene(device);
11370 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11372 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11373 hr = IDirect3DDevice9_EndScene(device);
11374 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11376 color = getPixelColor(device, 320, 240);
11377 ok(color_match(color, vs_body[i].color1, 1) || color_match(color, vs_body[i].color2, 1),
11378 "Expected color 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11379 vs_body[i].color1, vs_body[i].color2, vs_body[i].name, color);
11381 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11382 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11384 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11385 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11386 IDirect3DVertexShader9_Release(vs);
11389 HeapFree(GetProcessHeap(), 0, vs_code);
11391 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11392 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11393 IDirect3DPixelShader9_Release(ps);
11396 START_TEST(visual)
11398 IDirect3DDevice9 *device_ptr;
11399 D3DCAPS9 caps;
11400 HRESULT hr;
11401 DWORD color;
11403 d3d9_handle = LoadLibraryA("d3d9.dll");
11404 if (!d3d9_handle)
11406 skip("Could not load d3d9.dll\n");
11407 return;
11410 device_ptr = init_d3d9();
11411 if (!device_ptr)
11413 skip("Creating the device failed\n");
11414 return;
11417 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11419 /* Check for the reliability of the returned data */
11420 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11421 if(FAILED(hr))
11423 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11424 goto cleanup;
11427 color = getPixelColor(device_ptr, 1, 1);
11428 if(color !=0x00ff0000)
11430 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11431 goto cleanup;
11433 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11435 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11436 if(FAILED(hr))
11438 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11439 goto cleanup;
11442 color = getPixelColor(device_ptr, 639, 479);
11443 if(color != 0x0000ddee)
11445 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11446 goto cleanup;
11448 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11450 /* Now execute the real tests */
11451 depth_clamp_test(device_ptr);
11452 stretchrect_test(device_ptr);
11453 lighting_test(device_ptr);
11454 clear_test(device_ptr);
11455 color_fill_test(device_ptr);
11456 fog_test(device_ptr);
11457 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11459 test_cube_wrap(device_ptr);
11460 } else {
11461 skip("No cube texture support\n");
11463 z_range_test(device_ptr);
11464 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11466 maxmip_test(device_ptr);
11468 else
11470 skip("No mipmap support\n");
11472 offscreen_test(device_ptr);
11473 alpha_test(device_ptr);
11474 shademode_test(device_ptr);
11475 srgbtexture_test(device_ptr);
11476 release_buffer_test(device_ptr);
11477 float_texture_test(device_ptr);
11478 g16r16_texture_test(device_ptr);
11479 pixelshader_blending_test(device_ptr);
11480 texture_transform_flags_test(device_ptr);
11481 autogen_mipmap_test(device_ptr);
11482 fixed_function_decl_test(device_ptr);
11483 conditional_np2_repeat_test(device_ptr);
11484 fixed_function_bumpmap_test(device_ptr);
11485 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11486 stencil_cull_test(device_ptr);
11487 } else {
11488 skip("No two sided stencil support\n");
11490 pointsize_test(device_ptr);
11491 tssargtemp_test(device_ptr);
11492 np2_stretch_rect_test(device_ptr);
11493 yuv_color_test(device_ptr);
11494 zwriteenable_test(device_ptr);
11495 alphatest_test(device_ptr);
11496 viewport_test(device_ptr);
11498 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11500 test_constant_clamp_vs(device_ptr);
11501 test_compare_instructions(device_ptr);
11503 else skip("No vs_1_1 support\n");
11505 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11507 test_mova(device_ptr);
11508 loop_index_test(device_ptr);
11509 sincos_test(device_ptr);
11510 sgn_test(device_ptr);
11511 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11512 test_vshader_input(device_ptr);
11513 test_vshader_float16(device_ptr);
11514 stream_test(device_ptr);
11515 } else {
11516 skip("No vs_3_0 support\n");
11519 else skip("No vs_2_0 support\n");
11521 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11523 fog_with_shader_test(device_ptr);
11525 else skip("No vs_1_1 and ps_1_1 support\n");
11527 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11529 texbem_test(device_ptr);
11530 texdepth_test(device_ptr);
11531 texkill_test(device_ptr);
11532 x8l8v8u8_test(device_ptr);
11533 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11534 constant_clamp_ps_test(device_ptr);
11535 cnd_test(device_ptr);
11536 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11537 dp2add_ps_test(device_ptr);
11538 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11539 nested_loop_test(device_ptr);
11540 fixed_function_varying_test(device_ptr);
11541 vFace_register_test(device_ptr);
11542 vpos_register_test(device_ptr);
11543 multiple_rendertargets_test(device_ptr);
11544 } else {
11545 skip("No ps_3_0 or vs_3_0 support\n");
11547 } else {
11548 skip("No ps_2_0 support\n");
11552 else skip("No ps_1_1 support\n");
11554 texop_test(device_ptr);
11555 texop_range_test(device_ptr);
11556 alphareplicate_test(device_ptr);
11557 dp3_alpha_test(device_ptr);
11558 depth_buffer_test(device_ptr);
11559 intz_test(device_ptr);
11560 shadow_test(device_ptr);
11561 fp_special_test(device_ptr);
11562 depth_bounds_test(device_ptr);
11564 cleanup:
11565 if(device_ptr) {
11566 D3DPRESENT_PARAMETERS present_parameters;
11567 IDirect3DSwapChain9 *swapchain;
11568 ULONG ref;
11570 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11571 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11572 IDirect3DSwapChain9_Release(swapchain);
11573 ref = IDirect3DDevice9_Release(device_ptr);
11574 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11575 DestroyWindow(present_parameters.hDeviceWindow);